From 9b3c4167f95adfaf539076c6f4374e09e3c77404 Mon Sep 17 00:00:00 2001 From: Mikhail Derbichev Date: Wed, 5 Aug 2026 12:54:36 +0500 Subject: [PATCH 1/5] Document agent-native signup in the lium skill --- lium/SKILL.md | 46 ++++++++++++++++++++++++++++++++++++++++++++-- llms-full.txt | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/lium/SKILL.md b/lium/SKILL.md index 0894f2f..e43edae 100644 --- a/lium/SKILL.md +++ b/lium/SKILL.md @@ -1,6 +1,6 @@ --- name: lium -description: GPU pod management on Lium platform via CLI and Python SDK. Use for renting GPUs, creating/managing pods, deploying ML workloads, transferring files to remote GPUs, running code on remote GPUs, and programmatic compute management. Triggers on "lium", "lium.io", "lium-sdk", "GPU rental", "rent a GPU", "GPU pod", "cloud GPU", "remote GPU", "deploy to GPU", any lium CLI command (lium up/ls/ps/ssh/exec/scp/rsync/rm/fund), lium SDK, @machine decorator. +description: GPU pod management on Lium platform via CLI and Python SDK. Use for creating a Lium account, renting GPUs, creating/managing pods, deploying ML workloads, transferring files to remote GPUs, running code on remote GPUs, and programmatic compute management. Triggers on "lium", "lium.io", "lium-sdk", "create a lium account", "sign up for lium", "lium api key", "GPU rental", "rent a GPU", "GPU pod", "cloud GPU", "remote GPU", "deploy to GPU", any lium CLI command (lium up/ls/ps/ssh/exec/scp/rsync/rm/fund), lium SDK, @machine decorator. allowed-tools: Bash(lium:*) --- @@ -51,8 +51,50 @@ pip install lium.io **CRITICAL**: Many lium commands are interactive by default. As an agent, always pass all parameters explicitly to avoid interactive prompts. +### No Account Yet — Sign Up via API + +`lium init` authenticates a user who **already has an account**. Signup itself is programmatic too — three calls against `https://lium.io/api`, no browser, no dashboard. Never stall at the web signup form. + +Only create an account when the user asks for one. Ask for their **real email** first — the account, its balance and password recovery hang off that address. Never use a disposable inbox, never guess an address. + +```bash +BASE=https://lium.io/api + +# 1. Create the account. The response carries NO API key. +curl -sX POST $BASE/users -H 'Content-Type: application/json' \ + -d '{"name":"Ada","email":"ada@example.com","password":"..."}' +# 200 {"msg": "success"} +# An API key named "Default" is created server-side at this moment. + +# 2. Log in for an access token (JWT). +TOKEN=$(curl -sX POST $BASE/users/login -H 'Content-Type: application/json' \ + -d '{"email":"ada@example.com","password":"..."}' | jq -r .token) + +# 3. Read the key created at signup (format sk_...). +KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ + | jq -r '.[] | select(.name=="Default") | .key') +``` + +Store it as the CLI/SDK credential (writes `~/.lium/config.ini`): + +```bash +lium config set api.api_key "$KEY" +``` + +An update is in flight to return the API key directly from `POST /users`, collapsing steps 1–3 into one call. Until it ships, run all three. + +### After Signup — What Still Blocks the First Rental + +- **$5 signup credit** is granted automatically, **once per IP address**. If another account was already created from this IP, no credit is granted. Say that plainly and offer to fund — don't leave a later failure unexplained. +- **Renting requires a verified email.** The verification link arrives in the welcome email; the user clicks it once. This is currently the only step a human has to perform. Ask, then retry — don't fail the whole task. +- **Renting requires a positive balance.** `POST /executors/{executor_id}/rent` returns `403 "User is not verified"` (email not confirmed yet) or `403 "Insufficient balance"`. +- **Funding without a browser**: `POST /tmc-pay/create-invoice`, authenticated with the API key (`X-API-Key: sk_...`), returns `deposit_address`, the crypto amount and `expires_at` — enough for an agent with a wallet to top up headlessly. `POST /nowpayments/create-invoice` is the equivalent alternative. +- **SSH keys need no special handling** — the SDK registers the user's public key server-side right before renting. + ### Authentication Setup for Agents +For a user who already has an account (skip if you just ran the signup flow above and stored the key). + **Preferred: two-step headless auth** — no API key needed, no blocking, no browser: 1. Run `lium init --no-browser` — get auth URL and session ID (exits immediately) @@ -330,7 +372,7 @@ if ! command -v lium >/dev/null 2>&1; then export PATH="$HOME/.lium/bin:$PATH" fi -# 2. Authenticate (two-step headless flow) +# 2. Authenticate (two-step headless flow; no account yet → sign up via API first) lium init --no-browser # → parse URL and session ID from output, show URL to user # → wait for user to confirm they approved diff --git a/llms-full.txt b/llms-full.txt index 8240813..8d09cb4 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -53,8 +53,50 @@ pip install lium.io **CRITICAL**: Many lium commands are interactive by default. As an agent, always pass all parameters explicitly to avoid interactive prompts. +### No Account Yet — Sign Up via API + +`lium init` authenticates a user who **already has an account**. Signup itself is programmatic too — three calls against `https://lium.io/api`, no browser, no dashboard. Never stall at the web signup form. + +Only create an account when the user asks for one. Ask for their **real email** first — the account, its balance and password recovery hang off that address. Never use a disposable inbox, never guess an address. + +```bash +BASE=https://lium.io/api + +# 1. Create the account. The response carries NO API key. +curl -sX POST $BASE/users -H 'Content-Type: application/json' \ + -d '{"name":"Ada","email":"ada@example.com","password":"..."}' +# 200 {"msg": "success"} +# An API key named "Default" is created server-side at this moment. + +# 2. Log in for an access token (JWT). +TOKEN=$(curl -sX POST $BASE/users/login -H 'Content-Type: application/json' \ + -d '{"email":"ada@example.com","password":"..."}' | jq -r .token) + +# 3. Read the key created at signup (format sk_...). +KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ + | jq -r '.[] | select(.name=="Default") | .key') +``` + +Store it as the CLI/SDK credential (writes `~/.lium/config.ini`): + +```bash +lium config set api.api_key "$KEY" +``` + +An update is in flight to return the API key directly from `POST /users`, collapsing steps 1–3 into one call. Until it ships, run all three. + +### After Signup — What Still Blocks the First Rental + +- **$5 signup credit** is granted automatically, **once per IP address**. If another account was already created from this IP, no credit is granted. Say that plainly and offer to fund — don't leave a later failure unexplained. +- **Renting requires a verified email.** The verification link arrives in the welcome email; the user clicks it once. This is currently the only step a human has to perform. Ask, then retry — don't fail the whole task. +- **Renting requires a positive balance.** `POST /executors/{executor_id}/rent` returns `403 "User is not verified"` (email not confirmed yet) or `403 "Insufficient balance"`. +- **Funding without a browser**: `POST /tmc-pay/create-invoice`, authenticated with the API key (`X-API-Key: sk_...`), returns `deposit_address`, the crypto amount and `expires_at` — enough for an agent with a wallet to top up headlessly. `POST /nowpayments/create-invoice` is the equivalent alternative. +- **SSH keys need no special handling** — the SDK registers the user's public key server-side right before renting. + ### Authentication Setup for Agents +For a user who already has an account (skip if you just ran the signup flow above and stored the key). + **Preferred: two-step headless auth** — no API key needed, no blocking, no browser: 1. Run `lium init --no-browser` — get auth URL and session ID (exits immediately) @@ -332,7 +374,7 @@ if ! command -v lium >/dev/null 2>&1; then export PATH="$HOME/.lium/bin:$PATH" fi -# 2. Authenticate (two-step headless flow) +# 2. Authenticate (two-step headless flow; no account yet → sign up via API first) lium init --no-browser # → parse URL and session ID from output, show URL to user # → wait for user to confirm they approved From 8213f916c7f3ab0bd1a2581533036c46b3610021 Mon Sep 17 00:00:00 2001 From: Mikhail Derbichev Date: Wed, 5 Aug 2026 13:43:20 +0500 Subject: [PATCH 2/5] Lead the signup flow with lium signup and state the CLI version it needs --- lium/SKILL.md | 89 +++++++++++++++++++++++++++++++++++++-------------- llms-full.txt | 89 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 130 insertions(+), 48 deletions(-) diff --git a/lium/SKILL.md b/lium/SKILL.md index e43edae..6843b5b 100644 --- a/lium/SKILL.md +++ b/lium/SKILL.md @@ -23,11 +23,15 @@ curl -fsSL https://raw.githubusercontent.com/Datura-ai/lium/main/scripts/install This auto-detects OS (Linux/macOS) and architecture, downloads the binary to `~/.lium/bin/lium`, and adds it to PATH. -After install, initialize authentication: +After install, authentication depends on whether the user has a Lium account: + +- **No account** → `lium signup --email ` — see "No Account Yet — Sign Up". Do not send the user to the web signup form. +- **Has an account** → `lium init` (opens a browser) or `lium init --no-browser` for headless/agent use — see "Authentication Setup for Agents". ```bash -lium init # opens browser automatically -lium init --no-browser # prints auth URL (for headless/agent use) +lium signup --email ada@example.com # no account yet +lium init # existing account, browser +lium init --no-browser # existing account, headless ``` Verify setup: @@ -51,45 +55,79 @@ pip install lium.io **CRITICAL**: Many lium commands are interactive by default. As an agent, always pass all parameters explicitly to avoid interactive prompts. -### No Account Yet — Sign Up via API +### No Account Yet — Sign Up + +`lium init` authenticates a user who **already has an account**. To create one, use +`lium signup` — no browser, no dashboard, no web form. The whole cold start is four commands: + +```bash +lium signup --email ada@example.com # creates the account, stores the API key +lium ls # browse machines +lium up # rent +lium ssh # connect +``` + +Only create an account when the user asks for one. Ask for their **real email** first — the +verification link needed for renting is sent there, and the account, its balance and password +recovery are tied to it. Never invent an address, never use a disposable inbox. -`lium init` authenticates a user who **already has an account**. Signup itself is programmatic too — three calls against `https://lium.io/api`, no browser, no dashboard. Never stall at the web signup form. +`lium signup` prints the generated password — hand it to the user, it is their dashboard login. +Add `--json` for a machine-readable `{email, password, api_key, ssh_key_configured, next_steps}`. +The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one +set up with `lium init`. -Only create an account when the user asks for one. Ask for their **real email** first — the account, its balance and password recovery hang off that address. Never use a disposable inbox, never guess an address. +**Requires CLI 0.0.29 or newer.** Older binaries do not have the command. Check and update: + +```bash +lium --version +lium signup --help >/dev/null 2>&1 || echo "CLI too old — update it" + +# Binary install (installed via install.sh): auto-updates on launch, or force it +curl -fsSL https://lium.io/install.sh | bash + +# pip / uv install +uv tool upgrade lium.io # or: pip install -U lium.io +``` + +On an older CLI that cannot be updated, the same signup is three HTTP calls: ```bash BASE=https://lium.io/api -# 1. Create the account. The response carries NO API key. +# 1. Create the account. An API key named "Default" is minted server-side here. curl -sX POST $BASE/users -H 'Content-Type: application/json' \ -d '{"name":"Ada","email":"ada@example.com","password":"..."}' -# 200 {"msg": "success"} -# An API key named "Default" is created server-side at this moment. -# 2. Log in for an access token (JWT). +# 2. Log in for a JWT. 3. Read the key back (format sk_...). TOKEN=$(curl -sX POST $BASE/users/login -H 'Content-Type: application/json' \ -d '{"email":"ada@example.com","password":"..."}' | jq -r .token) - -# 3. Read the key created at signup (format sk_...). KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ | jq -r '.[] | select(.name=="Default") | .key') -``` -Store it as the CLI/SDK credential (writes `~/.lium/config.ini`): - -```bash lium config set api.api_key "$KEY" +lium config set ssh.key_path ~/.ssh/id_ed25519 ``` -An update is in flight to return the API key directly from `POST /users`, collapsing steps 1–3 into one call. Until it ships, run all three. +### Before the First Rental — Verification and Balance + +`lium up` calls `POST /executors/{executor_id}/rent`, which fails with `403` until both gates +are cleared. Map the error to the action: + +| 403 on rent | Meaning | Action | +|---|---|---| +| `"User is not verified"` | The verification link in the welcome email has not been clicked. Only the user can click it — there is no API for it. | Ask the user to click it, then retry. Do not abandon the task. | +| `"Insufficient balance"` | No usable credit. New accounts get a $5 credit, granted once per IP address. | Tell the user and offer a funding option. | -### After Signup — What Still Blocks the First Rental +Funding options: -- **$5 signup credit** is granted automatically, **once per IP address**. If another account was already created from this IP, no credit is granted. Say that plainly and offer to fund — don't leave a later failure unexplained. -- **Renting requires a verified email.** The verification link arrives in the welcome email; the user clicks it once. This is currently the only step a human has to perform. Ask, then retry — don't fail the whole task. -- **Renting requires a positive balance.** `POST /executors/{executor_id}/rent` returns `403 "User is not verified"` (email not confirmed yet) or `403 "Insufficient balance"`. -- **Funding without a browser**: `POST /tmc-pay/create-invoice`, authenticated with the API key (`X-API-Key: sk_...`), returns `deposit_address`, the crypto amount and `expires_at` — enough for an agent with a wallet to top up headlessly. `POST /nowpayments/create-invoice` is the equivalent alternative. -- **SSH keys need no special handling** — the SDK registers the user's public key server-side right before renting. +- Dashboard: https://lium.io/billing +- Headless invoice: `POST /tmc-pay/create-invoice` with header `X-API-Key: sk_...` returns + `deposit_address`, the crypto amount and `expires_at`. Give these to the user to pay from + their wallet — do not move funds on their behalf. +- `lium fund -w default -a 10.0 -y` for users with a Bittensor wallet. + +SSH keys need no extra registration — the public key at `ssh.key_path` is registered +server-side right before renting. ### Authentication Setup for Agents @@ -372,7 +410,10 @@ if ! command -v lium >/dev/null 2>&1; then export PATH="$HOME/.lium/bin:$PATH" fi -# 2. Authenticate (two-step headless flow; no account yet → sign up via API first) +# 2a. No account yet → sign up (asks the user for their real email first) +lium signup --email + +# 2b. Existing account → two-step headless auth instead lium init --no-browser # → parse URL and session ID from output, show URL to user # → wait for user to confirm they approved diff --git a/llms-full.txt b/llms-full.txt index 8d09cb4..b387ab8 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -25,11 +25,15 @@ curl -fsSL https://raw.githubusercontent.com/Datura-ai/lium/main/scripts/install This auto-detects OS (Linux/macOS) and architecture, downloads the binary to `~/.lium/bin/lium`, and adds it to PATH. -After install, initialize authentication: +After install, authentication depends on whether the user has a Lium account: + +- **No account** → `lium signup --email ` — see "No Account Yet — Sign Up". Do not send the user to the web signup form. +- **Has an account** → `lium init` (opens a browser) or `lium init --no-browser` for headless/agent use — see "Authentication Setup for Agents". ```bash -lium init # opens browser automatically -lium init --no-browser # prints auth URL (for headless/agent use) +lium signup --email ada@example.com # no account yet +lium init # existing account, browser +lium init --no-browser # existing account, headless ``` Verify setup: @@ -53,45 +57,79 @@ pip install lium.io **CRITICAL**: Many lium commands are interactive by default. As an agent, always pass all parameters explicitly to avoid interactive prompts. -### No Account Yet — Sign Up via API +### No Account Yet — Sign Up + +`lium init` authenticates a user who **already has an account**. To create one, use +`lium signup` — no browser, no dashboard, no web form. The whole cold start is four commands: + +```bash +lium signup --email ada@example.com # creates the account, stores the API key +lium ls # browse machines +lium up # rent +lium ssh # connect +``` + +Only create an account when the user asks for one. Ask for their **real email** first — the +verification link needed for renting is sent there, and the account, its balance and password +recovery are tied to it. Never invent an address, never use a disposable inbox. -`lium init` authenticates a user who **already has an account**. Signup itself is programmatic too — three calls against `https://lium.io/api`, no browser, no dashboard. Never stall at the web signup form. +`lium signup` prints the generated password — hand it to the user, it is their dashboard login. +Add `--json` for a machine-readable `{email, password, api_key, ssh_key_configured, next_steps}`. +The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one +set up with `lium init`. -Only create an account when the user asks for one. Ask for their **real email** first — the account, its balance and password recovery hang off that address. Never use a disposable inbox, never guess an address. +**Requires CLI 0.0.29 or newer.** Older binaries do not have the command. Check and update: + +```bash +lium --version +lium signup --help >/dev/null 2>&1 || echo "CLI too old — update it" + +# Binary install (installed via install.sh): auto-updates on launch, or force it +curl -fsSL https://lium.io/install.sh | bash + +# pip / uv install +uv tool upgrade lium.io # or: pip install -U lium.io +``` + +On an older CLI that cannot be updated, the same signup is three HTTP calls: ```bash BASE=https://lium.io/api -# 1. Create the account. The response carries NO API key. +# 1. Create the account. An API key named "Default" is minted server-side here. curl -sX POST $BASE/users -H 'Content-Type: application/json' \ -d '{"name":"Ada","email":"ada@example.com","password":"..."}' -# 200 {"msg": "success"} -# An API key named "Default" is created server-side at this moment. -# 2. Log in for an access token (JWT). +# 2. Log in for a JWT. 3. Read the key back (format sk_...). TOKEN=$(curl -sX POST $BASE/users/login -H 'Content-Type: application/json' \ -d '{"email":"ada@example.com","password":"..."}' | jq -r .token) - -# 3. Read the key created at signup (format sk_...). KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ | jq -r '.[] | select(.name=="Default") | .key') -``` -Store it as the CLI/SDK credential (writes `~/.lium/config.ini`): - -```bash lium config set api.api_key "$KEY" +lium config set ssh.key_path ~/.ssh/id_ed25519 ``` -An update is in flight to return the API key directly from `POST /users`, collapsing steps 1–3 into one call. Until it ships, run all three. +### Before the First Rental — Verification and Balance + +`lium up` calls `POST /executors/{executor_id}/rent`, which fails with `403` until both gates +are cleared. Map the error to the action: + +| 403 on rent | Meaning | Action | +|---|---|---| +| `"User is not verified"` | The verification link in the welcome email has not been clicked. Only the user can click it — there is no API for it. | Ask the user to click it, then retry. Do not abandon the task. | +| `"Insufficient balance"` | No usable credit. New accounts get a $5 credit, granted once per IP address. | Tell the user and offer a funding option. | -### After Signup — What Still Blocks the First Rental +Funding options: -- **$5 signup credit** is granted automatically, **once per IP address**. If another account was already created from this IP, no credit is granted. Say that plainly and offer to fund — don't leave a later failure unexplained. -- **Renting requires a verified email.** The verification link arrives in the welcome email; the user clicks it once. This is currently the only step a human has to perform. Ask, then retry — don't fail the whole task. -- **Renting requires a positive balance.** `POST /executors/{executor_id}/rent` returns `403 "User is not verified"` (email not confirmed yet) or `403 "Insufficient balance"`. -- **Funding without a browser**: `POST /tmc-pay/create-invoice`, authenticated with the API key (`X-API-Key: sk_...`), returns `deposit_address`, the crypto amount and `expires_at` — enough for an agent with a wallet to top up headlessly. `POST /nowpayments/create-invoice` is the equivalent alternative. -- **SSH keys need no special handling** — the SDK registers the user's public key server-side right before renting. +- Dashboard: https://lium.io/billing +- Headless invoice: `POST /tmc-pay/create-invoice` with header `X-API-Key: sk_...` returns + `deposit_address`, the crypto amount and `expires_at`. Give these to the user to pay from + their wallet — do not move funds on their behalf. +- `lium fund -w default -a 10.0 -y` for users with a Bittensor wallet. + +SSH keys need no extra registration — the public key at `ssh.key_path` is registered +server-side right before renting. ### Authentication Setup for Agents @@ -374,7 +412,10 @@ if ! command -v lium >/dev/null 2>&1; then export PATH="$HOME/.lium/bin:$PATH" fi -# 2. Authenticate (two-step headless flow; no account yet → sign up via API first) +# 2a. No account yet → sign up (asks the user for their real email first) +lium signup --email + +# 2b. Existing account → two-step headless auth instead lium init --no-browser # → parse URL and session ID from output, show URL to user # → wait for user to confirm they approved From 6d93bb32984a5c36b496c0d73527112fe8223d01 Mon Sep 17 00:00:00 2001 From: Mikhail Derbichev Date: Wed, 5 Aug 2026 15:03:36 +0500 Subject: [PATCH 3/5] Document lium signup, the confirmation-mail endpoints and the real funding shapes --- lium/SKILL.md | 67 +++++++++++++--- lium/references/cli-commands.md | 63 +++++++++++++++- llms-full.txt | 130 +++++++++++++++++++++++++++++--- 3 files changed, 238 insertions(+), 22 deletions(-) diff --git a/lium/SKILL.md b/lium/SKILL.md index 6843b5b..b7c39fa 100644 --- a/lium/SKILL.md +++ b/lium/SKILL.md @@ -68,11 +68,12 @@ lium ssh # connect ``` Only create an account when the user asks for one. Ask for their **real email** first — the -verification link needed for renting is sent there, and the account, its balance and password +confirmation link needed for renting is sent there, and the account, its balance and password recovery are tied to it. Never invent an address, never use a disposable inbox. `lium signup` prints the generated password — hand it to the user, it is their dashboard login. -Add `--json` for a machine-readable `{email, password, api_key, ssh_key_configured, next_steps}`. +Add `--json` for a machine-readable +`{email, password, api_key, signup_credit_granted, ssh_key_configured, next_steps}`. The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one set up with `lium init`. @@ -115,16 +116,64 @@ are cleared. Map the error to the action: | 403 on rent | Meaning | Action | |---|---|---| -| `"User is not verified"` | The verification link in the welcome email has not been clicked. Only the user can click it — there is no API for it. | Ask the user to click it, then retry. Do not abandon the task. | -| `"Insufficient balance"` | No usable credit. New accounts get a $5 credit, granted once per IP address. | Tell the user and offer a funding option. | +| `"User is not verified"` | The confirmation link has not been clicked yet. | Ask the user to click it, then retry — see "Email confirmation" below. Do not abandon the task. | +| `"Insufficient balance"` | The account balance is zero. | Fund the account — see "Funding options" below. | -Funding options: +#### Email confirmation + +Registration sends **two** mails: `"Welcome to Celium!"` (no link in it) and +`"Please confirm your email"` — only the second one carries the link. Point the user at that +subject, and ask them to click the link. That is the normal path. + +Two endpoints on `https://lium.io/api` cover the cases where it does not work. Neither needs +auth; both take JSON: + +```bash +# Mail never arrived / link expired (tokens are valid 24h) — send a fresh one +curl -sX POST https://lium.io/api/auth/resend-verify-email \ + -H 'Content-Type: application/json' -d '{"email":"ada@example.com"}' +# 400 "User doesn't exist." or "Email is already verified." when it does not apply + +# User pastes the link instead of clicking it — finish verification from its ?token= +curl -sX POST https://lium.io/api/auth/verify-email \ + -H 'Content-Type: application/json' -d '{"token":""}' +``` + +#### The $5 signup credit + +New accounts get a $5 credit. It is granted when the platform has the credit enabled **and** no +other account has signed up from this IP address — nothing about the email domain matters. Do not +explain a `403 "Insufficient balance"` with the credit: that error only says the balance is zero, +and the answer to it is to fund the account. + +Whether it landed is answered by `signup_credit_granted` in the signup response (also in +`lium signup --json`). If that field is absent — older CLI or backend — read the balance: + +```bash +lium balance --json # {"balance_usd": 5.0} +``` + +#### Funding options - Dashboard: https://lium.io/billing -- Headless invoice: `POST /tmc-pay/create-invoice` with header `X-API-Key: sk_...` returns - `deposit_address`, the crypto amount and `expires_at`. Give these to the user to pay from - their wallet — do not move funds on their behalf. -- `lium fund -w default -a 10.0 -y` for users with a Bittensor wallet. +- Headless invoice: `POST /tmc-pay/create-invoice` with header `X-API-Key: sk_...` and a body of + `{"amount": , "crypto_currency": "...", "crypto_network": "..."}` (all three required). + Valid currency/network pairs come from `GET /tmc-pay/currencies` (same API key header). The + response carries `deposit_address`, `crypto_amount`, `hosted_invoice_url` and `expires_at` — + give these to the user to pay from their wallet, do not move funds on their behalf. + + ```bash + # {"currencies": [{"code": "USDT", "network": "tron", ...}, ...]} — pick a pair from here + curl -s https://lium.io/api/tmc-pay/currencies -H "X-API-Key: sk_..." + + curl -sX POST https://lium.io/api/tmc-pay/create-invoice -H "X-API-Key: sk_..." \ + -H 'Content-Type: application/json' \ + -d '{"amount": 20, "crypto_currency": "USDT", "crypto_network": "tron"}' + ``` + +- `lium fund -w default -a 10.0 -y` for users with a Bittensor wallet — here `-a` is an amount of + **TAO**, not dollars. `-a` means USD only on the `--alpha` path, which moves Subnet-51 alpha the + user already has staked: `lium fund --alpha -k -a 10 -y`. SSH keys need no extra registration — the public key at `ssh.key_path` is registered server-side right before renting. diff --git a/lium/references/cli-commands.md b/lium/references/cli-commands.md index 290218e..d73aefa 100644 --- a/lium/references/cli-commands.md +++ b/lium/references/cli-commands.md @@ -3,6 +3,7 @@ ## Table of Contents - [Global Options](#global-options) +- [lium signup](#lium-signup) - [lium init](#lium-init) - [lium ls](#lium-ls) - [lium up](#lium-up) @@ -36,11 +37,65 @@ --debug Enable debug output ``` +## lium signup + +Create a Lium account and store the API key it mints. Fully non-interactive — this is +the command to use when the user has **no account yet**. Requires CLI 0.0.29 or newer. + +```bash +lium signup [OPTIONS] + --email EMAIL The user's real email (REQUIRED) — the confirmation link goes there + --name NAME Display name (defaults to the email's local part) + --password PASSWORD Account password (a strong one is generated when omitted) + --json Machine-readable output +``` + +Ask the user for their **real** email — the account, its balance, password recovery and the +confirmation link needed for renting are all tied to it. Never invent an address. + +The command creates the account (`POST /users`), stores the minted API key in +`~/.lium/config.ini` under `api.api_key`, and sets up an SSH key. After it, `lium ls` and +`lium up` work with no further setup. + +**Refuses to run when `api.api_key` is already configured** — it exits with an error instead +of creating a second, unreachable account. To sign up anyway, drop the existing key first: + +```bash +lium config unset api.api_key # then: lium signup --email ... +``` + +Examples: +```bash +lium signup --email ada@example.com +lium signup --email ada@example.com --name Ada --json +``` + +`--json` output: +```json +{ + "api_key": "sk_...", + "email": "ada@example.com", + "next_steps": ["...", "...", "..."], + "password": "generated-or-supplied", + "signup_credit_granted": true, + "ssh_key_configured": true +} +``` + +- `password` — the dashboard login at https://lium.io. Hand it to the user; it is not stored anywhere else. +- `signup_credit_granted` — comes straight from the signup API response and is the authoritative + answer to "did the $5 signup credit land?". If it is missing (older CLI or backend), read the + balance instead: `lium balance --json`. +- Renting stays blocked until the user clicks the link in the **"Please confirm your email"** mail + (the separate "Welcome to Celium!" mail carries no link). + ## lium init -Interactive setup wizard. **NOT suitable for agent/scripted use** — has no non-interactive flags. +Interactive setup wizard for a user who **already has an account** — `lium init` cannot create +one, use [`lium signup`](#lium-signup) for that. **NOT suitable for agent/scripted use** in its +plain form — but `lium init --no-browser` / `lium init --session ` is the headless two-step. -For agent setup, write config directly: +For an agent that already holds an API key, write config directly: ```bash mkdir -p ~/.lium lium config set api.api_key YOUR_KEY @@ -347,8 +402,12 @@ Pods accept these identifiers: LIUM_API_KEY=xyz lium ls # override API key LIUM_SSH_KEY=/tmp/key lium ssh my-pod LIUM_DEBUG=1 lium up # debug output +LIUM_BASE_URL=https://staging.lium.io/api lium signup --email ada@example.com ``` +`LIUM_BASE_URL` (default `https://lium.io/api`, the `/api` suffix included) points the SDK +**and** `lium signup` at another backend — use it to sign up against staging. + ## Exit Codes | Code | Meaning | diff --git a/llms-full.txt b/llms-full.txt index b387ab8..d62db6d 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -70,11 +70,12 @@ lium ssh # connect ``` Only create an account when the user asks for one. Ask for their **real email** first — the -verification link needed for renting is sent there, and the account, its balance and password +confirmation link needed for renting is sent there, and the account, its balance and password recovery are tied to it. Never invent an address, never use a disposable inbox. `lium signup` prints the generated password — hand it to the user, it is their dashboard login. -Add `--json` for a machine-readable `{email, password, api_key, ssh_key_configured, next_steps}`. +Add `--json` for a machine-readable +`{email, password, api_key, signup_credit_granted, ssh_key_configured, next_steps}`. The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one set up with `lium init`. @@ -117,16 +118,64 @@ are cleared. Map the error to the action: | 403 on rent | Meaning | Action | |---|---|---| -| `"User is not verified"` | The verification link in the welcome email has not been clicked. Only the user can click it — there is no API for it. | Ask the user to click it, then retry. Do not abandon the task. | -| `"Insufficient balance"` | No usable credit. New accounts get a $5 credit, granted once per IP address. | Tell the user and offer a funding option. | +| `"User is not verified"` | The confirmation link has not been clicked yet. | Ask the user to click it, then retry — see "Email confirmation" below. Do not abandon the task. | +| `"Insufficient balance"` | The account balance is zero. | Fund the account — see "Funding options" below. | -Funding options: +#### Email confirmation + +Registration sends **two** mails: `"Welcome to Celium!"` (no link in it) and +`"Please confirm your email"` — only the second one carries the link. Point the user at that +subject, and ask them to click the link. That is the normal path. + +Two endpoints on `https://lium.io/api` cover the cases where it does not work. Neither needs +auth; both take JSON: + +```bash +# Mail never arrived / link expired (tokens are valid 24h) — send a fresh one +curl -sX POST https://lium.io/api/auth/resend-verify-email \ + -H 'Content-Type: application/json' -d '{"email":"ada@example.com"}' +# 400 "User doesn't exist." or "Email is already verified." when it does not apply + +# User pastes the link instead of clicking it — finish verification from its ?token= +curl -sX POST https://lium.io/api/auth/verify-email \ + -H 'Content-Type: application/json' -d '{"token":""}' +``` + +#### The $5 signup credit + +New accounts get a $5 credit. It is granted when the platform has the credit enabled **and** no +other account has signed up from this IP address — nothing about the email domain matters. Do not +explain a `403 "Insufficient balance"` with the credit: that error only says the balance is zero, +and the answer to it is to fund the account. + +Whether it landed is answered by `signup_credit_granted` in the signup response (also in +`lium signup --json`). If that field is absent — older CLI or backend — read the balance: + +```bash +lium balance --json # {"balance_usd": 5.0} +``` + +#### Funding options - Dashboard: https://lium.io/billing -- Headless invoice: `POST /tmc-pay/create-invoice` with header `X-API-Key: sk_...` returns - `deposit_address`, the crypto amount and `expires_at`. Give these to the user to pay from - their wallet — do not move funds on their behalf. -- `lium fund -w default -a 10.0 -y` for users with a Bittensor wallet. +- Headless invoice: `POST /tmc-pay/create-invoice` with header `X-API-Key: sk_...` and a body of + `{"amount": , "crypto_currency": "...", "crypto_network": "..."}` (all three required). + Valid currency/network pairs come from `GET /tmc-pay/currencies` (same API key header). The + response carries `deposit_address`, `crypto_amount`, `hosted_invoice_url` and `expires_at` — + give these to the user to pay from their wallet, do not move funds on their behalf. + + ```bash + # {"currencies": [{"code": "USDT", "network": "tron", ...}, ...]} — pick a pair from here + curl -s https://lium.io/api/tmc-pay/currencies -H "X-API-Key: sk_..." + + curl -sX POST https://lium.io/api/tmc-pay/create-invoice -H "X-API-Key: sk_..." \ + -H 'Content-Type: application/json' \ + -d '{"amount": 20, "crypto_currency": "USDT", "crypto_network": "tron"}' + ``` + +- `lium fund -w default -a 10.0 -y` for users with a Bittensor wallet — here `-a` is an amount of + **TAO**, not dollars. `-a` means USD only on the `--alpha` path, which moves Subnet-51 alpha the + user already has staked: `lium fund --alpha -k -a 10 -y`. SSH keys need no extra registration — the public key at `ssh.key_path` is registered server-side right before renting. @@ -451,6 +500,7 @@ echo "y" | lium rm work-pod ## Table of Contents - [Global Options](#global-options) +- [lium signup](#lium-signup) - [lium init](#lium-init) - [lium ls](#lium-ls) - [lium up](#lium-up) @@ -484,11 +534,65 @@ echo "y" | lium rm work-pod --debug Enable debug output ``` +## lium signup + +Create a Lium account and store the API key it mints. Fully non-interactive — this is +the command to use when the user has **no account yet**. Requires CLI 0.0.29 or newer. + +```bash +lium signup [OPTIONS] + --email EMAIL The user's real email (REQUIRED) — the confirmation link goes there + --name NAME Display name (defaults to the email's local part) + --password PASSWORD Account password (a strong one is generated when omitted) + --json Machine-readable output +``` + +Ask the user for their **real** email — the account, its balance, password recovery and the +confirmation link needed for renting are all tied to it. Never invent an address. + +The command creates the account (`POST /users`), stores the minted API key in +`~/.lium/config.ini` under `api.api_key`, and sets up an SSH key. After it, `lium ls` and +`lium up` work with no further setup. + +**Refuses to run when `api.api_key` is already configured** — it exits with an error instead +of creating a second, unreachable account. To sign up anyway, drop the existing key first: + +```bash +lium config unset api.api_key # then: lium signup --email ... +``` + +Examples: +```bash +lium signup --email ada@example.com +lium signup --email ada@example.com --name Ada --json +``` + +`--json` output: +```json +{ + "api_key": "sk_...", + "email": "ada@example.com", + "next_steps": ["...", "...", "..."], + "password": "generated-or-supplied", + "signup_credit_granted": true, + "ssh_key_configured": true +} +``` + +- `password` — the dashboard login at https://lium.io. Hand it to the user; it is not stored anywhere else. +- `signup_credit_granted` — comes straight from the signup API response and is the authoritative + answer to "did the $5 signup credit land?". If it is missing (older CLI or backend), read the + balance instead: `lium balance --json`. +- Renting stays blocked until the user clicks the link in the **"Please confirm your email"** mail + (the separate "Welcome to Celium!" mail carries no link). + ## lium init -Interactive setup wizard. **NOT suitable for agent/scripted use** — has no non-interactive flags. +Interactive setup wizard for a user who **already has an account** — `lium init` cannot create +one, use [`lium signup`](#lium-signup) for that. **NOT suitable for agent/scripted use** in its +plain form — but `lium init --no-browser` / `lium init --session ` is the headless two-step. -For agent setup, write config directly: +For an agent that already holds an API key, write config directly: ```bash mkdir -p ~/.lium lium config set api.api_key YOUR_KEY @@ -795,8 +899,12 @@ Pods accept these identifiers: LIUM_API_KEY=xyz lium ls # override API key LIUM_SSH_KEY=/tmp/key lium ssh my-pod LIUM_DEBUG=1 lium up # debug output +LIUM_BASE_URL=https://staging.lium.io/api lium signup --email ada@example.com ``` +`LIUM_BASE_URL` (default `https://lium.io/api`, the `/api` suffix included) points the SDK +**and** `lium signup` at another backend — use it to sign up against staging. + ## Exit Codes | Code | Meaning | From 301b0ac43006764302ae2c7b29aa1b836142588c Mon Sep 17 00:00:00 2001 From: Mikhail Derbichev Date: Wed, 5 Aug 2026 15:14:40 +0500 Subject: [PATCH 4/5] Document LIUM_SIGNUP_PASSWORD, failure-path credentials and the tri-state credit flag --- lium/SKILL.md | 14 ++++++++++---- lium/references/cli-commands.md | 15 +++++++++++++-- llms-full.txt | 29 +++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/lium/SKILL.md b/lium/SKILL.md index b7c39fa..1def55c 100644 --- a/lium/SKILL.md +++ b/lium/SKILL.md @@ -71,7 +71,10 @@ Only create an account when the user asks for one. Ask for their **real email** confirmation link needed for renting is sent there, and the account, its balance and password recovery are tied to it. Never invent an address, never use a disposable inbox. -`lium signup` prints the generated password — hand it to the user, it is their dashboard login. +`lium signup` prints the generated password — hand it to the user, it is their dashboard login +(to choose one instead, pass `--password` or set `LIUM_SIGNUP_PASSWORD`, which keeps it off argv). +Even when the command fails after the account was created — a timeout, or the API key could not +be read back — the error still reports the email and password, so the account is never stranded. Add `--json` for a machine-readable `{email, password, api_key, signup_credit_granted, ssh_key_configured, next_steps}`. The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one @@ -95,11 +98,13 @@ On an older CLI that cannot be updated, the same signup is three HTTP calls: ```bash BASE=https://lium.io/api -# 1. Create the account. An API key named "Default" is minted server-side here. +# 1. Create the account. An API key named "Default" is minted server-side here; current +# backends return it in the response — {"msg": "success", "api_key": "sk_...", +# "signup_credit_granted": true|false} — older ones mint it without returning it. curl -sX POST $BASE/users -H 'Content-Type: application/json' \ -d '{"name":"Ada","email":"ada@example.com","password":"..."}' -# 2. Log in for a JWT. 3. Read the key back (format sk_...). +# 2-3. Only when the response had no api_key: log in for a JWT, read the key back (format sk_...). TOKEN=$(curl -sX POST $BASE/users/login -H 'Content-Type: application/json' \ -d '{"email":"ada@example.com","password":"..."}' | jq -r .token) KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ @@ -147,7 +152,8 @@ explain a `403 "Insufficient balance"` with the credit: that error only says the and the answer to it is to fund the account. Whether it landed is answered by `signup_credit_granted` in the signup response (also in -`lium signup --json`). If that field is absent — older CLI or backend — read the balance: +`lium signup --json`): `true` → granted, `false` → not granted. When it is `null` or absent — +the backend does not report it — read the balance: ```bash lium balance --json # {"balance_usd": 5.0} diff --git a/lium/references/cli-commands.md b/lium/references/cli-commands.md index d73aefa..a551287 100644 --- a/lium/references/cli-commands.md +++ b/lium/references/cli-commands.md @@ -50,6 +50,9 @@ lium signup [OPTIONS] --json Machine-readable output ``` +The password can also come from the `LIUM_SIGNUP_PASSWORD` environment variable — `--password` +wins when both are set. Whatever its origin, it is always reported back to the caller. + Ask the user for their **real** email — the account, its balance, password recovery and the confirmation link needed for renting are all tied to it. Never invent an address. @@ -64,6 +67,12 @@ of creating a second, unreachable account. To sign up anyway, drop the existing lium config unset api.api_key # then: lium signup --email ... ``` +**Failures never strand the account.** When the command fails after the account was created — +the request timed out, or the API key could not be read back — the error still reports the +email and password, so the user can log in at https://lium.io and copy an API key from the +dashboard. With `--json`, that error goes to stderr as +`{"ok": false, "error": {...}, "data": {"email": "...", "password": "..."}}`. + Examples: ```bash lium signup --email ada@example.com @@ -84,8 +93,9 @@ lium signup --email ada@example.com --name Ada --json - `password` — the dashboard login at https://lium.io. Hand it to the user; it is not stored anywhere else. - `signup_credit_granted` — comes straight from the signup API response and is the authoritative - answer to "did the $5 signup credit land?". If it is missing (older CLI or backend), read the - balance instead: `lium balance --json`. + answer to "did the $5 signup credit land?": `true` → granted; `false` → not granted (the + once-per-IP gate, or the credit disabled platform-side); `null` → the backend did not report + it (older backend) — read the balance instead: `lium balance --json`. - Renting stays blocked until the user clicks the link in the **"Please confirm your email"** mail (the separate "Welcome to Celium!" mail carries no link). @@ -403,6 +413,7 @@ LIUM_API_KEY=xyz lium ls # override API key LIUM_SSH_KEY=/tmp/key lium ssh my-pod LIUM_DEBUG=1 lium up # debug output LIUM_BASE_URL=https://staging.lium.io/api lium signup --email ada@example.com +LIUM_SIGNUP_PASSWORD=pw lium signup --email ada@example.com # signup password kept off argv ``` `LIUM_BASE_URL` (default `https://lium.io/api`, the `/api` suffix included) points the SDK diff --git a/llms-full.txt b/llms-full.txt index d62db6d..fa491c6 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -73,7 +73,10 @@ Only create an account when the user asks for one. Ask for their **real email** confirmation link needed for renting is sent there, and the account, its balance and password recovery are tied to it. Never invent an address, never use a disposable inbox. -`lium signup` prints the generated password — hand it to the user, it is their dashboard login. +`lium signup` prints the generated password — hand it to the user, it is their dashboard login +(to choose one instead, pass `--password` or set `LIUM_SIGNUP_PASSWORD`, which keeps it off argv). +Even when the command fails after the account was created — a timeout, or the API key could not +be read back — the error still reports the email and password, so the account is never stranded. Add `--json` for a machine-readable `{email, password, api_key, signup_credit_granted, ssh_key_configured, next_steps}`. The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one @@ -97,11 +100,13 @@ On an older CLI that cannot be updated, the same signup is three HTTP calls: ```bash BASE=https://lium.io/api -# 1. Create the account. An API key named "Default" is minted server-side here. +# 1. Create the account. An API key named "Default" is minted server-side here; current +# backends return it in the response — {"msg": "success", "api_key": "sk_...", +# "signup_credit_granted": true|false} — older ones mint it without returning it. curl -sX POST $BASE/users -H 'Content-Type: application/json' \ -d '{"name":"Ada","email":"ada@example.com","password":"..."}' -# 2. Log in for a JWT. 3. Read the key back (format sk_...). +# 2-3. Only when the response had no api_key: log in for a JWT, read the key back (format sk_...). TOKEN=$(curl -sX POST $BASE/users/login -H 'Content-Type: application/json' \ -d '{"email":"ada@example.com","password":"..."}' | jq -r .token) KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ @@ -149,7 +154,8 @@ explain a `403 "Insufficient balance"` with the credit: that error only says the and the answer to it is to fund the account. Whether it landed is answered by `signup_credit_granted` in the signup response (also in -`lium signup --json`). If that field is absent — older CLI or backend — read the balance: +`lium signup --json`): `true` → granted, `false` → not granted. When it is `null` or absent — +the backend does not report it — read the balance: ```bash lium balance --json # {"balance_usd": 5.0} @@ -547,6 +553,9 @@ lium signup [OPTIONS] --json Machine-readable output ``` +The password can also come from the `LIUM_SIGNUP_PASSWORD` environment variable — `--password` +wins when both are set. Whatever its origin, it is always reported back to the caller. + Ask the user for their **real** email — the account, its balance, password recovery and the confirmation link needed for renting are all tied to it. Never invent an address. @@ -561,6 +570,12 @@ of creating a second, unreachable account. To sign up anyway, drop the existing lium config unset api.api_key # then: lium signup --email ... ``` +**Failures never strand the account.** When the command fails after the account was created — +the request timed out, or the API key could not be read back — the error still reports the +email and password, so the user can log in at https://lium.io and copy an API key from the +dashboard. With `--json`, that error goes to stderr as +`{"ok": false, "error": {...}, "data": {"email": "...", "password": "..."}}`. + Examples: ```bash lium signup --email ada@example.com @@ -581,8 +596,9 @@ lium signup --email ada@example.com --name Ada --json - `password` — the dashboard login at https://lium.io. Hand it to the user; it is not stored anywhere else. - `signup_credit_granted` — comes straight from the signup API response and is the authoritative - answer to "did the $5 signup credit land?". If it is missing (older CLI or backend), read the - balance instead: `lium balance --json`. + answer to "did the $5 signup credit land?": `true` → granted; `false` → not granted (the + once-per-IP gate, or the credit disabled platform-side); `null` → the backend did not report + it (older backend) — read the balance instead: `lium balance --json`. - Renting stays blocked until the user clicks the link in the **"Please confirm your email"** mail (the separate "Welcome to Celium!" mail carries no link). @@ -900,6 +916,7 @@ LIUM_API_KEY=xyz lium ls # override API key LIUM_SSH_KEY=/tmp/key lium ssh my-pod LIUM_DEBUG=1 lium up # debug output LIUM_BASE_URL=https://staging.lium.io/api lium signup --email ada@example.com +LIUM_SIGNUP_PASSWORD=pw lium signup --email ada@example.com # signup password kept off argv ``` `LIUM_BASE_URL` (default `https://lium.io/api`, the `/api` suffix included) points the SDK From c03efb6859f5b1dfd518afc1b92ae81e70113477 Mon Sep 17 00:00:00 2001 From: Mikhail Derbichev Date: Wed, 5 Aug 2026 15:21:18 +0500 Subject: [PATCH 5/5] Fix review nits: non-interactive rent, no version pin, no premature ssh.key_path --- lium/SKILL.md | 9 +++++---- lium/references/cli-commands.md | 3 ++- llms-full.txt | 12 +++++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lium/SKILL.md b/lium/SKILL.md index 1def55c..dde76b4 100644 --- a/lium/SKILL.md +++ b/lium/SKILL.md @@ -63,7 +63,7 @@ pip install lium.io ```bash lium signup --email ada@example.com # creates the account, stores the API key lium ls # browse machines -lium up # rent +lium up -y # rent lium ssh # connect ``` @@ -80,10 +80,10 @@ Add `--json` for a machine-readable The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one set up with `lium init`. -**Requires CLI 0.0.29 or newer.** Older binaries do not have the command. Check and update: +Older binaries do not have the command. Probe for it, and update when it is missing: ```bash -lium --version +lium --version # diagnostics only — probe the command itself below lium signup --help >/dev/null 2>&1 || echo "CLI too old — update it" # Binary install (installed via install.sh): auto-updates on launch, or force it @@ -111,7 +111,8 @@ KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ | jq -r '.[] | select(.name=="Default") | .key') lium config set api.api_key "$KEY" -lium config set ssh.key_path ~/.ssh/id_ed25519 +# leave ssh.key_path unset — the CLI generates and configures the key on first use, +# and setting the path to a key that does not exist yet makes it skip that ``` ### Before the First Rental — Verification and Balance diff --git a/lium/references/cli-commands.md b/lium/references/cli-commands.md index a551287..4a7edf1 100644 --- a/lium/references/cli-commands.md +++ b/lium/references/cli-commands.md @@ -40,7 +40,8 @@ ## lium signup Create a Lium account and store the API key it mints. Fully non-interactive — this is -the command to use when the user has **no account yet**. Requires CLI 0.0.29 or newer. +the command to use when the user has **no account yet**. Older CLI binaries do not have it — +probe with `lium signup --help` and update the CLI when it is missing. ```bash lium signup [OPTIONS] diff --git a/llms-full.txt b/llms-full.txt index fa491c6..c974374 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -65,7 +65,7 @@ pip install lium.io ```bash lium signup --email ada@example.com # creates the account, stores the API key lium ls # browse machines -lium up # rent +lium up -y # rent lium ssh # connect ``` @@ -82,10 +82,10 @@ Add `--json` for a machine-readable The key is written to `~/.lium/config.ini`, so the account is then indistinguishable from one set up with `lium init`. -**Requires CLI 0.0.29 or newer.** Older binaries do not have the command. Check and update: +Older binaries do not have the command. Probe for it, and update when it is missing: ```bash -lium --version +lium --version # diagnostics only — probe the command itself below lium signup --help >/dev/null 2>&1 || echo "CLI too old — update it" # Binary install (installed via install.sh): auto-updates on launch, or force it @@ -113,7 +113,8 @@ KEY=$(curl -s $BASE/keys -H "Authorization: Bearer $TOKEN" \ | jq -r '.[] | select(.name=="Default") | .key') lium config set api.api_key "$KEY" -lium config set ssh.key_path ~/.ssh/id_ed25519 +# leave ssh.key_path unset — the CLI generates and configures the key on first use, +# and setting the path to a key that does not exist yet makes it skip that ``` ### Before the First Rental — Verification and Balance @@ -543,7 +544,8 @@ echo "y" | lium rm work-pod ## lium signup Create a Lium account and store the API key it mints. Fully non-interactive — this is -the command to use when the user has **no account yet**. Requires CLI 0.0.29 or newer. +the command to use when the user has **no account yet**. Older CLI binaries do not have it — +probe with `lium signup --help` and update the CLI when it is missing. ```bash lium signup [OPTIONS]