> For new test environments, start with `remind env use` and the IAM application `app_secret`. The manual pairing commands are maintained only for existing installations. See [the testing guide](../testing-environments.md).
# remind CLI
`remind` is built entirely on `silicon-remind-client`. It stores preferences,
application sessions, refresh tokens, and test keys under `{home}/.remind/` (default `{home}` is `SILICON_HOME` when set, otherwise `~`). On Unix,
the directory is mode 0700 and state files are mode 0600. A process lock serializes
state mutations and refreshes; saves use an atomic rename. State is separated by
server origin and test-environment UUID so switching servers or sandboxes never
reuses another context's session.
## Install and start
```sh
honeycomb install 'remind'
remind --help
remind login '<SLT-from-IAM>'
```
For local development, use `cargo build -p silicon-remind-cli` and `cargo run -p silicon-remind-cli -- --help`. Release packaging is described in the [release guide](../releases.md).
The default origin is `https://backend.remind.teamofsilicons.com`. For local work:
```sh
remind config set-url http://127.0.0.1:8086
remind --no-update health --ready
remind login <slt> --org tos
```
`remind login <slt>` accepts the short-lived token supplied by IAM directly.
`remind auth login` securely prompts for it. Login does not
start an OTP ceremony or redirect a browser. For an agent/noninteractive shell:
```sh
remind auth login --org tos --slt-stdin < /secure/path/slt.txt
remind auth whoami
remind config home /secure/remind-state
```
The SLT must be for `remind` and bound to the desired organization. A successful
login verifies the organization before saving the new session. Near expiry, a
normal authenticated command rotates the saved refresh token before proceeding.
`auth refresh` requests an explicit rotation; `auth logout` revokes the IAM family
and then removes local credentials.
## IAM discovery and login status
```sh
remind --help
remind iam --json
remind login status --json
remind --test <test_id> login status --json
```
`iam` requires no saved session. It reads the selected backend's public IAM
configuration and returns `app_id`, `iam_url`, and `iam_environment_id` (null in
production). Use this app ID when obtaining an SLT from IAM. App secrets and test
keys are never printed. With `--test`, a saved environment key is required and
metadata describes the linked IAM sandbox; its IAM app secret must be configured.
`login status` checks the session for the selected server and environment against
the live `/auth/me` endpoint, refreshing near-expiry tokens first. A successful
check returns `authenticated: true` alongside `actor_type` (`carbon` or `silicon`),
`principal_id`, `public_id`, `org_id`, `membership_id`, `org_role`,
`authorization_epoch`, and `can_manage_reminders`. It never prints access or refresh
tokens. For example:
```json
{"authenticated":true,"principal_id":"01992000-0000-7000-8000-000000000001","actor_type":"silicon","public_id":"si:assistant","org_id":"tos","membership_id":"01992000-0000-7000-8000-000000000002","org_role":"member","authorization_epoch":1,"can_manage_reminders":true}
```
No saved session or an HTTP 401 from verification/refresh returns
`{"authenticated":false}` with exit status 0. A permission denial, unavailable
server, or malformed response remains an error with a nonzero exit status; it is
not reported as a successful authentication check. `--account` and `--org` select an already saved account/organization context
to verify. They cannot retarget an existing credential. `auth whoami` remains available with its existing identity/error output.
## Home directory selection
`SILICON_HOME` replaces `HOME` as the default state parent when present. Remind
reads the optional `.remind/home` pointer from that default parent; an explicit
`config home` setting stored there takes precedence. Without a pointer, state is
stored directly in `<SILICON_HOME>/.remind/` or `~/.remind/`. An empty
`SILICON_HOME` is an error. A missing default directory is created as needed.
```sh
SILICON_HOME=/private/silicon remind --no-update config show --json
SILICON_HOME=/private/silicon remind config home /existing/remind-state
```
`config home` requires an existing directory and saves its absolute path in the
selected default parent's `.remind/home`. The next invocation uses the new
location. It does not move existing sessions or keys. Unsetting `SILICON_HOME`
selects the normal home and its own pointer again. The Rust client remains
stateless and does not read or create these CLI state files.
## Ordinary reminder workflow
```sh
remind webhook subscribe 'https://example.com/reminders'
remind create --text 'Review the build' --cron '*/15 * * * *' --timezone Asia/Kolkata
remind list
remind get <reminder-id>
remind edit <reminder-id> --text 'Review the release build'
remind pause <reminder-id>
remind resume <reminder-id>
remind executions <reminder-id>
remind archive <reminder-id>
remind list --archived
```
Use any absolute HTTP(S) URL. `webhook subscribe` prompts securely for an optional
signing secret; use `--secret-stdin` to supply a protected file through stdin, or
`--unsigned` when the receiver does not require signatures. `webhook get` never
reveals the secret.
Subscriptions are optional and can be managed independently with `webhook
subscribe`, `webhook list`, and `webhook unsubscribe`. A reminder may be created
before any receiver is configured.
For a one-time reminder, add `--kind one-time`. It fires at the first future cron
match and enters the archive automatically. Every creation requires an IANA
timezone: provide `--timezone Asia/Kolkata` or another IANA identifier. To schedule
in UTC, provide `--timezone UTC` explicitly. Omitting the flag or passing a blank
timezone returns an error explaining how to supply it. Invalid IANA identifiers
are also rejected. Editing an existing reminder may omit `--timezone` to retain
its stored timezone.
`pause` and `resume` accept up to 100 UUIDs and are atomic. A Carbon cannot create
or mutate reminders; it can use `silicons`, `list`, `get`, and `executions` for any
Silicon in its organization. Archiving retains a reminder for 45 days.
## Command reference
| Command | Purpose / useful options |
| --- | --- |
| `auth contexts` | List saved account and organization contexts without credentials |
| `auth login` | Secure SLT prompt; `--org`, `--slt-stdin` |
| `login <slt>` | Direct IAM SLT login; `--org` must match the SLT; testing actor IDs may select an org |
| `iam` | Public `app_id`, IAM URL and linked IAM environment; no login needed |
| `login status` | Live authentication result and Carbon/Silicon identity; supports `--json` |
| `auth whoami` | Live IAM identity and permissions |
| `auth refresh` | Rotate current refresh token |
| `auth logout` | Revoke and forget this session |
| `create` | Required `--text`, `--cron`, `--timezone`; optional `--kind` |
| `list` | `--silicon`, `--archived`, `--status`, `--cursor`, `--limit` |
| `get <id>` | Full reminder details |
| `edit <id>` | At least one of `--text`, `--cron`, `--timezone`, `--kind` |
| `pause <id>…` | Atomic pause of 1–100 owned reminders |
| `resume <id>…` | Atomic resume of 1–100 owned reminders |
| `archive <id>` | Move an owned reminder to the archive |
| `executions <id>` | `--cursor`, `--limit`; inspect deliveries/failures |
| `silicons` | `--after <uuid>`, `--limit`; registered org Silicons |
| `webhook subscribe <url>` | Secure secret prompt, `--secret-stdin`, or `--unsigned` |
| `webhook get` | Read endpoint metadata |
| `webhook disable` | Disable the current Silicon's endpoint |
| `webhook subscribe <url>` | Add another webhook subscription |
| `webhook list` | List all active subscriptions |
| `webhook unsubscribe <id>` | Disable one subscription |
| `config home <directory>` | Set the local state parent directory; it must already exist |
| `env create <name>` | `--description`, `--iam-key-file`, `--iam-app-secret-file` |
| `env list` | `--include-deleted`, `--after <uuid>`, `--limit` |
| `env get <id>` | Environment metadata and deadlines |
| `env key <id>` | Retrieve, print and locally save the active key |
| `env rotate <id>` | Replace the root key and save its successor |
| `env delete <id>` | Retire; recoverable for 30 days |
| `env restore <id>` | Restore with a new root key |
| `env import <id>` | Save a shared key; prompt or `--key-stdin` |
| `env forget <id>` | Remove this computer's key/session only |
| `test-info` | Selected sandbox metadata; requires `--test` |
| `clean` | Clear selected sandbox data; requires `--test` |
| `config show` | Preferences and counts; no saved secrets |
| `config set-url <origin>` | Change the saved service origin |
| `config auto-update off` | Disable the retired updater preference |
| `update --check` | Show Honeycomb update instructions |
| `update` | Show Honeycomb update instructions |
| `health` | Liveness; `--ready` checks database readiness |
Every command accepts `-h`/`--help`. Missing required flags produce the relevant
usage. Global flags are `--url`, `--account`, `--org`, `--test <id>`, `--json`, `--no-update`, and
`--idempotency-key`. `REMIND_URL` and `REMIND_ORG` supply URL/org defaults for an
invocation. They do not move existing sessions between contexts.
`--json` emits machine-readable JSON and suppresses success suggestions. Errors
go to stderr. Exit status is 0 for success, 2 for CLI/local input failures, 3 for
API authentication failure, 4 for API forbidden, and 1 for other failures. Use the
API's machine error code in the error text to distinguish state conflicts.
## Sandboxes
Manage environments with the production session, without `--test`:
```sh
remind env create release-qa --description 'Manual release verification' \
--iam-key-file /secure/path/iam-test-key \
--iam-app-secret-file /secure/path/iam-test-app-secret
```
The returned UUID is your selector; the root key is saved locally. Use ordinary
commands with the prefix:
```sh
remind --test <id> test-info
remind --test <id> auth login --org test-org
remind --test <id> webhook set <test-hook-endpoint>
remind --test <id> create --text 'Sandbox reminder' --cron '* * * * *'
remind --test <id> list
remind --test <id> clean
```
A teammate can share the root key: `remind env import <id> --key-stdin < key.txt`.
Import verifies that the key belongs to the requested UUID before saving it.
The environment key provides sandbox administration; ordinary reminder commands
still need an IAM test identity. Cleaning clears all Remind data and logs but
keeps the environment, root key and IAM binding. It does not clean IAM itself.
Legacy manually paired sandboxes support at most 100 retained reminders. It is retired after 15 days
without successful user activity; scheduler polls do not keep it alive. Deleted
environments can be recovered for 30 days. See the [full guide](../testing-environments.md).
## Updating
Install with `honeycomb install 'remind'` and update with `honeycomb update 'remind'`. Remind never replaces its executable. `remind update` and `remind update --check` return the Honeycomb command without changing files or querying crates.io.
Remove an older standalone updater with `remind daemon uninstall`; `daemon status` remains available for diagnosis. `daemon install`, `daemon run`, and `config auto-update on` now explain the migration to Honeycomb. `--no-update` and `config auto-update off` remain accepted for older scripts.
## Sandbox selection, manuals, and reports
Use `remind env use --secret-stdin < /private/app-secret` to select the IAM application's sandbox without a root key or environment UUID. Sign in with a test SLT or an existing active test public identity. `remind env exit` restores the production session; `--production` overrides selection for one command. Selected test name/ID always appears on stderr, including failures and help. Legacy administrative commands below apply only to manually paired environments; IAM-discovered worlds follow IAM's lifecycle and have no 100-reminder quota.
Read bundled manuals with `remind docs cli|api|client|testing|webhooks`. `remind report 'reproduction details' --pr https://github.com/teamofsilicons/silicon-remind/pull/123` queues a bug report email through the public Rust client and backend using your Remind session. `--pr` is optional; output contains the report ID and delivery status. Run `remind report-status <id>` to inspect delivery. Reports in a sandbox are simulated. Production delivery uses Postmark. Include expected and actual behavior, versions, and a request ID when available; exclude secrets.
`env create` needs only a name and IAM root key; `--iam-app-secret-file` is
optional. To install the test app secret later, use
`remind --test <id> configure-iam --iam-app-secret-file /private/test-app-secret`.
Ordinary actions fail with an explicit configuration error until this is done.
Refresh retries persist their operation key before contacting IAM. After an
uncertain response, run the command again using this same local store; it safely
replays the pending refresh. Do not copy a rotating session family between machines.
Runtime `--json` failures return `error.code` and `error.message`. Backend errors
also retain HTTP `status`, `request_id` and optional `retry_after`; local argument
validation uses `invalid_input`. Clap usage/help errors retain its standard CLI
help format. Credentials and response bodies are not included in errors.
## Telemetry
Operational telemetry is on by default. `remind config telemetry off` disables both CLI/daemon events and API request observations for this installation; `on` enables them. `REMIND_TELEMETRY_ENABLED=false` also disables them. No command arguments, credentials, reminder text or webhook URLs are included. Test events remain in the selected sandbox. See [diagnostics](../diagnostics.md).