--- summary: "CLI reference: commands, flags, config, lockfile, and sync behavior." read_when: - Using the ClawHub CLI - Debugging install, update, publish, or sync --- # CLI CLI package: `clawhub`, bin: `clawhub`. Install it globally with npm or pnpm: ```bash npm i -g clawhub # or pnpm add -g clawhub ``` Then verify it: ```bash clawhub --help clawhub login clawhub whoami ``` ## Global flags - `--workdir `: working directory (default: cwd; falls back to Clawdbot workspace if configured) - `--dir `: install dir under workdir (default: `skills`) - `--site `: base URL for browser login (default: `https://clawhub.ai`) - `--registry `: API base URL (default: discovered, else `https://clawhub.ai`) - `--no-input`: disable prompts Env equivalents: - `CLAWHUB_SITE` (legacy `CLAWDHUB_SITE`) - `CLAWHUB_REGISTRY` (legacy `CLAWDHUB_REGISTRY`) - `CLAWHUB_WORKDIR` (legacy `CLAWDHUB_WORKDIR`) ### HTTP proxy The CLI respects standard HTTP proxy environment variables for systems behind corporate proxies or restricted networks: - `HTTPS_PROXY` / `https_proxy` - `HTTP_PROXY` / `http_proxy` - `NO_PROXY` / `no_proxy` When any of these variables is set, the CLI routes outbound requests through the specified proxy. `HTTPS_PROXY` is used for HTTPS requests, `HTTP_PROXY` for plain HTTP. `NO_PROXY` / `no_proxy` is respected to bypass the proxy for specific hosts or domains. This is required on systems where direct outbound connections are blocked (e.g. Docker containers, Hetzner VPS with proxy-only internet, corporate firewalls). Example: ```bash export HTTPS_PROXY=http://proxy.example.com:3128 export NO_PROXY=localhost,127.0.0.1 clawhub search "my query" ``` When no proxy variable is set, behavior is unchanged (direct connections). ## Config file Stores your API token + cached registry URL. - macOS: `~/Library/Application Support/clawhub/config.json` - Linux/XDG: `$XDG_CONFIG_HOME/clawhub/config.json` or `~/.config/clawhub/config.json` - Windows: `%APPDATA%\\clawhub\\config.json` - Legacy fallback: if `clawhub/config.json` does not exist yet but `clawdhub/config.json` does, the CLI reuses the legacy path - override: `CLAWHUB_CONFIG_PATH` (legacy `CLAWDHUB_CONFIG_PATH`) ## Commands ### `login` / `auth login` - Default: opens browser to `/cli/auth` and completes via loopback callback. - Headless: `clawhub login --token clh_...` - Remote/headless interactive: `clawhub login --device` prints a code and waits while you authorize it at `/cli/device`. ### `whoami` - Verifies the stored token via `/api/v1/whoami`. ### `token` - Prints the stored API token to stdout. - Useful for piping a local login token into CI secret setup commands. ### `star ` / `unstar ` - Adds/removes a skill from your highlights. - Calls `POST /api/v1/stars/` and `DELETE /api/v1/stars/`. - `--yes` skips confirmation. ### `search ` - Calls `/api/v1/search?q=...`. - Output includes the skill slug, owner handle, display name, and relevance score. - Search favors exact slug/name token matches before download popularity. A standalone slug token such as `map` matches `personal-map` more strongly than the substring inside `amap`. - Downloads are a small popularity prior, not a guarantee of top placement. - If a skill should appear but does not, run `clawhub inspect ` while logged in to check owner-visible moderation diagnostics before renaming metadata. ### `explore` - Lists newest skills via `/api/v1/skills?limit=...&sort=createdAt` (sorted by `createdAt` desc). - Flags: - `--limit ` (1-200, default: 25) - `--sort newest|updated|downloads|rating|installs|installsAllTime|trending` (default: newest) - `--json` (machine-readable output) - Output: ` v ` (summary truncated to 50 chars). ### `inspect ` - Fetches skill metadata and version files without installing. - `--version `: inspect a specific version (default: latest). - `--tag `: inspect a tagged version (e.g. `latest`). - `--versions`: list version history (first page). - `--limit `: max versions to list (1-200). - `--files`: list files for the selected version. - `--file `: fetch raw file content (text files only; 200KB limit). - `--json`: machine-readable output. ### `install ` - Resolves latest version via `/api/v1/skills/`. - Downloads zip via `/api/v1/download`. - Extracts into `//`. - Refuses to overwrite pinned skills; run `clawhub unpin ` first. - Writes: - `/.clawhub/lock.json` (legacy `.clawdhub`) - `/.clawhub/origin.json` (legacy `.clawdhub`) ### `uninstall ` - Removes `//` and deletes the lockfile entry. - Sends best-effort telemetry while logged in so current install counts can be deactivated. - Interactive: asks for confirmation. - Non-interactive (`--no-input`): requires `--yes`. ### `list` - Reads `/.clawhub/lock.json` (legacy `.clawdhub`). - Shows `pinned` next to skills frozen with `clawhub pin`, including the optional reason. ### `pin ` - Marks an installed skill as pinned in the lockfile. - `--reason ` records why the skill is frozen. - Pinned skills are skipped by `update --all` and rejected by direct `update `. - Pinned skills also reject `install --force` so the local bytes cannot be replaced accidentally. ### `unpin ` - Removes the lockfile pin from an installed skill so future updates can modify it. ### `update [slug]` / `update --all` - Computes fingerprint from local files. - If fingerprint matches a known version: no prompt. - If fingerprint does not match: - refuses by default - overwrites with `--force` (or prompt, if interactive) - Pinned skills are never updated by `--force`. - `update ` fails fast for pinned slugs and tells you to run `clawhub unpin ` first. - `update --all` skips pinned slugs and prints a summary of what stayed frozen. ### `skill publish ` - Publishes via `POST /api/v1/skills` (multipart). - Requires semver: `--version 1.2.3`. - `--owner ` publishes under an org/user publisher handle when the actor has publisher access. - `--migrate-owner` moves an existing skill to `--owner` while publishing a new version. Requires admin/owner access on both publishers. - Owner and review behavior is explained in `docs/publishing.md`. - Publishing a skill means it is released under `MIT-0` on ClawHub. - Published skills are free to use, modify, and redistribute without attribution. - ClawHub does not support paid skills or per-skill pricing. - Legacy alias: `publish `. ```bash clawhub skill publish ./my-skill --version 1.0.0 ``` ### `scan --slug ` - Requires `clawhub login`. - Runs ClawHub ClawScan through `POST /api/v1/skills/-/scan`, then polls until the scan is terminal. - Scans are asynchronous and may take time to complete. While queued, the terminal spinner shows the current prioritized scan position and how many scans are ahead. - Published scans require ownership or publisher management access. Moderators/admins can use the same backend through `clawhub-admin`. - `--update` is valid only with `--slug`; it writes successful published scan results back to the selected version. - `--output ` downloads the full report archive with `manifest.json`, `clawscan.json`, `skillspector.json`, `static-analysis.json`, `virustotal.json`, and `README.md`. - `--json` prints the full poll response for automation. - Local path scans are no longer supported. Upload a new version, then use `scan download` to retrieve the stored scan results for that submitted version. ```bash clawhub scan --slug gifgrep clawhub scan --slug gifgrep --version 1.2.3 clawhub scan --slug gifgrep --update --output report.zip ``` ### `scan download ` - Requires `clawhub login`. - Downloads the stored scan report ZIP for a submitted skill or plugin version, including versions that were blocked or hidden by ClawHub security checks. - Skill downloads use the skill slug and default to `--kind skill`. - Plugin downloads use the package name and require `--kind plugin`. - `--version` is required so authors inspect the exact submitted version that ClawHub blocked. - `--output ` chooses the destination path. ```bash clawhub scan download gifgrep --version 1.2.3 clawhub scan download @scope/demo --version 2.0.0 --kind plugin --output report.zip ``` #### GitHub Actions ClawHub ships an official reusable workflow at [`/.github/workflows/skill-publish.yml`](../.github/workflows/skill-publish.yml) for skill repos and catalog repos. Typical catalog setup: ```yaml name: Skill Publish on: pull_request: workflow_dispatch: jobs: dry-run: if: github.event_name == 'pull_request' uses: openclaw/clawhub/.github/workflows/skill-publish.yml@v1 with: owner: nvidia dry_run: true publish: if: github.event_name == 'workflow_dispatch' uses: openclaw/clawhub/.github/workflows/skill-publish.yml@v1 with: owner: nvidia dry_run: false secrets: clawhub_token: ${{ secrets.CLAWHUB_TOKEN }} ``` Notes: - `root` defaults to `skills` for catalog repos. - Pass `skill_path: skills/review-helper` to process one skill folder. - `owner` maps to the CLI `--owner` flag; omit it to publish as the authenticated user. - V1 skill publishing uses `clawhub_token`; GitHub OIDC trusted publishing is package-only for now. ### `delete ` - Soft-delete a skill (owner, moderator, or admin). - Calls `DELETE /api/v1/skills/{slug}`. - Owner-initiated soft deletes reserve the slug for 30 days; the command prints the expiry time. - `--reason ` records a moderation note on the skill and audit log. - `--note ` is an alias for `--reason`. - `--yes` skips confirmation. ### `undelete ` - Restore a hidden skill (owner, moderator, or admin). - Calls `POST /api/v1/skills/{slug}/undelete`. - `--reason ` records a moderation note on the skill and audit log. - `--note ` is an alias for `--reason`. - `--yes` skips confirmation. ### `hide ` - Hide a skill (owner, moderator, or admin). - Alias for `delete`. ### `unhide ` - Unhide a skill (owner, moderator, or admin). - Alias for `undelete`. ### `skill rename ` - Rename an owned skill and keep the previous slug as a redirect alias. - Calls `POST /api/v1/skills/{slug}/rename`. - `--yes` skips confirmation. ### `skill merge ` - Merge one owned skill into another owned skill. - The source slug stops listing publicly and becomes a redirect alias to the target. - Calls `POST /api/v1/skills/{sourceSlug}/merge`. - `--yes` skips confirmation. ### `transfer` - Ownership transfer workflow. - Transfers to user handles create a pending request that the recipient accepts. - Transfers to org/publisher handles apply immediately only when the actor has admin access to both the current owner and destination publisher. - Subcommands: - `transfer request [--message "..."] [--yes]` - `transfer list [--outgoing]` - `transfer accept [--yes]` - `transfer reject [--yes]` - `transfer cancel [--yes]` - Endpoints: - `POST /api/v1/skills/{slug}/transfer` - `POST /api/v1/skills/{slug}/transfer/accept` - `POST /api/v1/skills/{slug}/transfer/reject` - `POST /api/v1/skills/{slug}/transfer/cancel` - `GET /api/v1/transfers/incoming` - `GET /api/v1/transfers/outgoing` ### `package explore [query...]` - Browses or searches the unified package catalog via `GET /api/v1/packages` and `GET /api/v1/packages/search`. - Use this for plugins and other package-family entries; top-level `search` remains the skill search surface. - Flags: - `--family skill|code-plugin|bundle-plugin` - `--official` - `--executes-code` - `--target `, `--os `, `--arch `, `--libc ` - `--requires-browser`, `--requires-desktop`, `--requires-native-deps` - `--requires-external-service`, `--external-service ` - `--binary `, `--os-permission ` - `--artifact-kind legacy-zip|npm-pack` - `--npm-mirror` - `--limit ` (1-100, default: 25) - `--json` Examples: ```bash clawhub package explore --family code-plugin clawhub package explore --family code-plugin --os darwin --requires-desktop clawhub package explore --family code-plugin --artifact-kind npm-pack clawhub package explore --npm-mirror clawhub package explore episodic-claw --family code-plugin ``` ### `package inspect ` - Fetches package metadata without installing. - Use this for plugin metadata, compatibility, verification, source, and version/file inspection. - `--version `: inspect a specific version (default: latest). - `--tag `: inspect a tagged version (e.g. `latest`). - `--versions`: list version history (first page). - `--limit `: max versions to list (1-100). - `--files`: list files for the selected version. - `--file `: fetch raw file content (text files only; 200KB limit). - `--json`: machine-readable output. ### `package download ` - Resolves a package version through `GET /api/v1/packages/{name}/versions/{version}/artifact`. - Downloads the artifact from the resolver's `downloadUrl`. - Verifies ClawHub SHA-256 for all artifacts. - For ClawPack npm-pack artifacts, also verifies npm `sha512` integrity, npm shasum, and the tarball's `package.json` name/version. - Legacy ZIP versions download through the legacy ZIP route. - Flags: - `--version `: download a specific version. - `--tag `: download a tagged version (default: `latest`). - `-o, --output `: output file or directory. - `--force`: overwrite an existing output file. - `--json`: machine-readable output. Examples: ```bash clawhub package download @openclaw/example-plugin --tag latest clawhub package download @openclaw/example-plugin --version 1.2.3 -o artifacts/ ``` ### `package verify ` - Computes ClawHub SHA-256, npm `sha512` integrity, and npm shasum for a local artifact. - With `--package`, resolves expected metadata from ClawHub and compares the local file against the published artifact metadata. - With direct digest flags, verifies without a network lookup. - Flags: - `--package `: package name to resolve expected artifact metadata. - `--version ` or `--tag `: expected package version. - `--sha256 `: expected ClawHub SHA-256. - `--npm-integrity `: expected npm integrity. - `--npm-shasum `: expected npm shasum. - `--json`: machine-readable output. Examples: ```bash clawhub package verify ./example-plugin-1.2.3.tgz --package @openclaw/example-plugin --version 1.2.3 clawhub package verify ./example-plugin-1.2.3.tgz --sha256 ``` ### `package validate ` - Runs the ClawHub CLI's bundled Plugin Inspector against a local plugin package folder. - Defaults to offline/static validation, without locating or importing a local OpenClaw checkout. - Hard compatibility errors exit non-zero. Warning-only findings are printed but exit zero. - Flags: - `--out `: write Plugin Inspector reports to this directory. - `--openclaw `: inspect against an explicit local OpenClaw checkout. - `--runtime`: enable runtime capture; imports plugin code. - `--allow-execute`: allow runtime capture in an isolated workspace. - `--no-mock-sdk`: disable mocked OpenClaw SDK during runtime capture. - `--json`: machine-readable output. Example: ```bash clawhub package validate ./example-plugin ``` If validation reports a package, manifest, SDK import, or artifact finding, see [Plugin validation fixes](./plugin-validation-fixes.md), then rerun the command. ### `package delete ` - Soft-deletes a package and all releases. - Requires the package owner, an org publisher owner/admin, platform moderator, or platform admin. - Flags: - `--yes`: skip confirmation. - `--json`: machine-readable output. Example: ```bash clawhub package delete @openclaw/example-plugin --yes ``` ### `package undelete ` - Restores a soft-deleted package and releases. - Requires the package owner, an org publisher owner/admin, platform moderator, or platform admin. - Calls `POST /api/v1/packages/{name}/undelete`. - Flags: - `--yes`: skip confirmation. - `--json`: machine-readable output. Example: ```bash clawhub package undelete @openclaw/example-plugin --yes ``` ### `package transfer ` - Transfers a package to another publisher. - Requires admin access to both the current package owner and destination publisher, unless performed by a platform admin. - Scoped package names must transfer to the matching scope owner. - Calls `POST /api/v1/packages/{name}/transfer`. - Flags: - `--to `: destination publisher handle. - `--reason `: optional audit reason. - `--json`: machine-readable output. Example: ```bash clawhub package transfer @openclaw/example-plugin --to openclaw ``` ### `package report` - Authenticated command for reporting a package to moderators. - Calls `POST /api/v1/packages/{name}/report`. - Reports are package-level, optionally tied to a version, and become visible to moderators for review. - Reports do not auto-hide packages or block downloads by themselves. - Flags: - `--version `: optional package version to attach to the report. - `--reason `: required report reason. - `--json`: machine-readable output. Example: ```bash clawhub package report @openclaw/example-plugin --version 1.2.3 --reason "suspicious native payload" ``` ### `package moderation-status` - Owner command for checking package moderation visibility. - Calls `GET /api/v1/packages/{name}/moderation`. - Shows current package scan state, open report count, latest release manual moderation state, download block state, and moderation reasons. - Flags: - `--json`: machine-readable output. Example: ```bash clawhub package moderation-status @openclaw/example-plugin ``` ### `package readiness ` - Checks whether a package is ready for future OpenClaw consumption. - Calls `GET /api/v1/packages/{name}/readiness`. - Reports blockers for official status, ClawPack availability, artifact digest, source provenance, OpenClaw compatibility, host targets, environment metadata, and scan state. - Flags: - `--json`: machine-readable output. Example: ```bash clawhub package readiness @openclaw/example-plugin ``` ### `package migration-status ` - Shows operator-oriented migration status for a package that may replace a bundled OpenClaw plugin. - Calls the same computed readiness endpoint as `package readiness`, but prints migration-focused status, latest version, official-package state, checks, and blockers. - Flags: - `--json`: machine-readable output. Example: ```bash clawhub package migration-status @openclaw/example-plugin ``` ### `publisher create ` - Creates an org publisher owned by the authenticated user. - The handle is normalized to lowercase and may be passed with or without `@`. - Newly created org publishers are not trusted/official by default. - Fails if the handle is already used by an existing publisher, user, or reserved route. ```bash clawhub publisher create opik --display-name "Opik" ``` ### `package publish ` - Publishes a code plugin or bundle plugin via `POST /api/v1/packages`. - `` accepts: - Local folder path: `./my-plugin` - Local ClawPack npm-pack tarball: `./my-plugin-1.2.3.tgz` - GitHub repo: `owner/repo` or `owner/repo@ref` - GitHub URL: `https://github.com/owner/repo` - Metadata is auto-detected from `package.json`, `openclaw.plugin.json`, and real OpenClaw bundle markers such as `.codex-plugin/plugin.json`, `.claude-plugin/plugin.json`, and `.cursor-plugin/plugin.json`. - `.tgz` sources are treated as ClawPack. The CLI uploads the exact npm-pack bytes and uses the extracted `package/` contents only for validation and metadata prefill. - Code-plugin folders are packed into a ClawPack npm tarball before upload so OpenClaw installs can verify the exact artifact. Bundle-plugin folders still use the extracted-file publish path. - For GitHub sources, source attribution is auto-populated from the repo, resolved commit, ref, and subpath. - For local folders, source attribution is auto-detected from local git when the origin remote points at GitHub. - External code plugins must declare `openclaw.compat.pluginApi` and `openclaw.build.openclawVersion` explicitly. Top-level `package.json.version` is not used as a fallback for publish validation. - `--dry-run` previews the resolved publish payload without uploading. - `--json` emits machine-readable output for CI. - `--owner ` publishes under a user or org publisher handle when the actor has publisher access. - Scoped package names must match the selected owner. See `docs/publishing.md`. - Existing flags (`--family`, `--name`, `--version`, `--source-repo`, `--source-commit`, `--source-ref`, `--source-path`) still work as overrides. - Private GitHub repos require `GITHUB_TOKEN`. ```bash clawhub package publish ./plugin.tgz --owner openclaw ``` #### Recommended local flow Use `--dry-run` first so you can confirm the resolved package metadata and source attribution before creating a live release: ```bash npm pack clawhub package publish ./my-plugin-1.2.3.tgz --family code-plugin --dry-run clawhub package publish ./my-plugin-1.2.3.tgz --family code-plugin ``` #### Local folder flow For code plugins, folder publish builds and uploads a ClawPack artifact from the package folder: ```bash clawhub package publish ./my-plugin --family code-plugin --dry-run clawhub package publish ./my-plugin --family code-plugin ``` #### Minimal `package.json` for `--family code-plugin` External code plugins need a small amount of OpenClaw metadata in `package.json`. This minimal manifest is enough for a successful publish: ```json { "name": "@myorg/openclaw-my-plugin", "version": "1.0.0", "type": "module", "openclaw": { "extensions": ["./index.ts"], "compat": { "pluginApi": ">=2026.3.24-beta.2" }, "build": { "openclawVersion": "2026.3.24-beta.2" } } } ``` Required fields: - `openclaw.compat.pluginApi` - `openclaw.build.openclawVersion` Notes: - `package.json.version` is your package release version, but it is not used as a fallback for OpenClaw compatibility/build validation. - `openclaw.hostTargets` and `openclaw.environment` are optional metadata. ClawHub may surface them when present, but they are not required for publish. - `openclaw.compat.minGatewayVersion` and `openclaw.build.pluginSdkVersion` are optional extras if you want to publish more detailed compatibility metadata. - If you are using an older `clawhub` CLI release, upgrade before publishing so the local preflight checks run before upload. - If validation reports a remediation code, see [Plugin validation fixes](./plugin-validation-fixes.md). #### GitHub Actions ClawHub also ships an official reusable workflow at [`/.github/workflows/package-publish.yml`](../.github/workflows/package-publish.yml) for plugin repos. Typical caller setup: ```yaml name: Package Publish on: pull_request: workflow_dispatch: push: tags: - "v*" jobs: dry-run: if: github.event_name == 'pull_request' uses: openclaw/clawhub/.github/workflows/package-publish.yml@v0.12.0 with: dry_run: true publish: if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') permissions: contents: read id-token: write uses: openclaw/clawhub/.github/workflows/package-publish.yml@v0.12.0 with: dry_run: false secrets: clawhub_token: ${{ secrets.CLAWHUB_TOKEN }} ``` Notes: - The reusable workflow defaults `source` to the caller repo. - For monorepos, pass `source_path` so the workflow publishes the plugin package folder, for example `source_path: extensions/codex`. - Pin the reusable workflow to a stable tag or full commit SHA. Do not run release publishing from `@main`. - `pull_request` should use `dry_run: true` so CI stays non-polluting. - Real publishes should be limited to trusted events such as `workflow_dispatch` or tag pushes. - Trusted publishing without a secret only works on `workflow_dispatch`; tag pushes still need `clawhub_token`. - Keep `clawhub_token` available for first publish, untrusted packages, or break-glass publishes. - The workflow uploads the JSON result as an artifact and exposes it as workflow outputs. ### `package trusted-publisher get ` - Shows the GitHub Actions trusted publisher config for a package. - Use this after setting config to confirm the repository, workflow filename, and optional environment pin. - Flags: - `--json`: machine-readable output. Example: ```bash clawhub package trusted-publisher get @openclaw/example-plugin ``` ### `package trusted-publisher set ` - Attaches or replaces GitHub Actions trusted publisher config for an existing package. - The package must be created first through normal manual or token-authenticated `clawhub package publish`. - After config is set, future supported GitHub Actions publishes can use OIDC/trusted publishing without a long-lived ClawHub token. - `--repository ` must be `owner/repo`. - `--workflow-filename ` must match the workflow file name in `.github/workflows/`. - `--environment ` is optional. When configured, the GitHub Actions environment in the OIDC claim must match exactly. - Flags: - `--repository `: GitHub repository, for example `openclaw/example-plugin`. - `--workflow-filename `: workflow file name, for example `package-publish.yml`. - `--environment `: optional exact-match GitHub Actions environment. - `--json`: machine-readable output. Example: ```bash clawhub package trusted-publisher set @openclaw/example-plugin \ --repository openclaw/example-plugin \ --workflow-filename package-publish.yml \ --environment release ``` ### `package trusted-publisher delete ` - Removes trusted publisher config from a package. - Use this as rollback if the workflow, repository, or environment pin needs to be disabled or re-created. - Future real publishes must use normal authenticated publishing until config is set again. - Flags: - `--json`: machine-readable output. Example: ```bash clawhub package trusted-publisher delete @openclaw/example-plugin ``` ### `sync` - Scans for local skill folders and publishes new/changed ones. - Roots can be any folder: a skills directory or a single skill folder with `SKILL.md`. - Auto-adds Clawdbot skill roots when `~/.clawdbot/clawdbot.json` is present: - `agent.workspace/skills` (main agent) - `routing.agents.*.workspace/skills` (per-agent) - `~/.clawdbot/skills` (shared) - `skills.load.extraDirs` (shared packs) - Respects `CLAWDBOT_CONFIG_PATH` / `CLAWDBOT_STATE_DIR` and `OPENCLAW_CONFIG_PATH` / `OPENCLAW_STATE_DIR`. - Flags: - `--root ` extra scan roots - `--all` upload without prompting - `--dry-run` show plan only - `--json` machine-readable summary for CI - `--owner ` publish under a user or org publisher - `--bump patch|minor|major` (default: patch) - `--changelog ` (non-interactive) - `--tags a,b,c` (default: latest) - `--concurrency ` - `--source-repo `, `--source-commit `, `--source-ref ` for GitHub provenance `sync` does not report install telemetry. ### Install telemetry - Sent after `clawhub install ` when logged in, unless `CLAWHUB_DISABLE_TELEMETRY=1` is set. - Reporting is best-effort. Install commands do not fail if telemetry is unavailable. - Details: `docs/telemetry.md`.