Command reference
Every Operio CLI command, grouped by resource
Run operio --help, or operio <group> --help, for the authoritative list at the version you have installed.
Authentication
operio auth login # Browser login
operio auth status # Show the current user
operio auth logout # Clear stored credentials
operio login # Aliases kept for compatibility
operio logout
operio whoami # User, org, and the selected team and project
operio update # Upgrade a global install to the latest versionAgent skill
operio skill install [--global | --dir <skills-dir>] [--force]
operio skill show # Print SKILL.mdinstall copies the skill bundled with this CLI version into ./.claude/skills/operio (or ~/.claude/skills/operio with --global). It refuses to overwrite a copy that differs unless you pass --force. See Use a coding agent.
See The CLI for the login flow.
Team and project
operio teams list
operio teams use <team-id>
operio projects list [--limit 100] [--offset 0]
operio projects create --name "Web app" [--type web]
operio projects use <project-id>auth login selects a team for you — the one your session already belongs to, or the first available — so projects list works immediately. Use teams use to change it. Selecting a team clears the selected project, since a project belongs to exactly one team.
teams use confirms in plain text rather than JSON — it records a choice, so there is nothing to parse back.
Project names accept English letters, digits, and single spaces between words
(^[a-zA-Z0-9]+(?: [a-zA-Z0-9]+)*$). Hyphens and underscores are rejected —
use composer test, not composer-test.
Environments
operio environments list [--project-id <id>]
operio environments get <environment-id>
operio environments create --project-id <id> --name staging --base-url https://staging.example.com
operio environments update <environment-id> [--name <name>] [--base-url <url>]
operio environments delete <environment-id>Environments are web run targets and require --base-url. Mobile projects
target an uploaded build directly and do not require an environment.
create also accepts --input:
operio environments create --input '{
"name": "production",
"baseUrl": "https://app.example.com"
}'Builds (mobile)
operio builds list [--project-id <id>] [--platform ios|android]
operio builds get <build-id>
operio builds upload --file ./app.apk [--project-id <id>] [--name Nightly]upload stores the binary and registers it as a runnable build in one step. The app ID, version, and build number are read from the file. Supported files are a zipped .app (iOS Simulator) or .apk. Device .ipa files are not supported. See Uploading Builds.
Test accounts
Project test accounts are managed independently of environments. See Test accounts for how they're used during a run.
operio test-accounts list [--project-id <id>]
operio test-accounts get <test-account-id>
operio test-accounts create --project-id <id> --label demo --username alex@demo.com --password-stdin
operio test-accounts create --type google --label gmail --username user@gmail.com --password secret
operio test-accounts create --type phone --label sms --username +15551234567 --password 123456
operio test-accounts update <test-account-id> --password new-secret
operio test-accounts update <test-account-id> --label "Primary Admin"| Type | --username | --password |
|---|---|---|
password (default) | Username or email | Password |
google | Google account email | Google password — used for "Sign in with Google" flows |
phone | Test phone number | The fixed OTP code that account always accepts |
--password lands in your shell history and in ps output. Prefer
--password-stdin (printf '%s' "$SECRET" | operio test-accounts create …) or
the OPERIO_PASSWORD environment variable.
Deleting a test account is only available in the web app: it leaves dangling login steps in any test case that used it, which the CLI cannot show you.
Test cases
operio tests list [--project-id <id>] [--status active] [--severity high] [--name <name>] [--created-by <id>] [--limit 100] [--offset 0]
operio tests get <test-case-id>
operio tests create [--name <name>] [--description <text>] [--severity <severity>] [--step <type:value>…] [--status <status>] [--tag-ids <ids>] [--input <json|file|->] [--project-id <id>] [--suite <test-suite-id>…] [--full]
operio tests update <test-case-id> [--name <name>] [--severity <severity>] [--step <type:value>…] [--input <json|file|->] [--full]
operio tests activate <test-case-id> [--full]
operio tests deactivate <test-case-id> [--full]
operio tests run <test-case-id> (--environment-id <id> | --build-id <id>) [--wait] [--timeout 600]From flags
Steps use <type>:<value> and run in flag order:
operio tests create \
--name "Guest checkout" \
--description "A guest can buy without an account" \
--severity high \
--step "action:Add the first item to the cart" \
--step wait:2 \
--step "verify:The cart badge shows 1 item"Step types are action, verify, wait, screenshot, and login. Only the first colon separates the type, so instructions may contain URLs. Repeat --step as needed; flags override the same field in --input.
Test case payload
name, description, severity (critical, high, medium, low), and steps are required. Repeat --suite to add the case to multiple suites; it may only be used with active or inactive status. JSON input uses testSuiteIds.
Omitting status creates a draft from the CLI. The API defaults to active. Review the case before publishing, or pass --status active to create it as published.
tests activate publishes a draft or inactive case. tests deactivate returns an active one to inactive, excluding it from runs without deleting it. Only active test cases can be included in a run.
{
"name": "Checkout",
"description": "Complete a purchase as a signed-in customer",
"severity": "high",
"steps": [
{ "order": 1, "type": "login", "testAccountId": "cred-id" },
{ "order": 2, "type": "action", "instruction": "Open the checkout page" },
{ "order": 3, "type": "wait", "seconds": 5 },
{ "order": 4, "type": "screenshot", "label": "Order summary" },
{ "order": 5, "type": "verify", "assertion": "The order total is visible" }
]
}Step types
Every step has a positive integer order and a type. Each type carries exactly the fields it needs — nothing else.
| Type | Required field | Meaning |
|---|---|---|
action | instruction | Something to do, in plain English |
verify | assertion | Something that must be true. Only verify failures fail a run |
wait | seconds (1–180) | A fixed pause |
screenshot | label | Capture the current view and file it under this name |
login | testAccountId | Sign in with a stored project test account |
severity belongs to the test case, not to a step.
Field names changed
Earlier versions used a single action field on every step, plus waitSeconds
on wait steps. Steps now use instruction (action), assertion (verify), and
seconds (wait). Update stored JSON payloads when you upgrade.
Test suites
operio suites list [--project-id <id>]
operio suites get <test-suite-id> [--full]
operio suites create --name Smoke [--test-case-ids c1,c2] [--priority high] [--order-strategy suite_order] [--execution-mode sequential|parallel] [--start-from start|previous_test_case] [--preparation-test c0] [--full]
operio suites run <test-suite-id> (--environment-id <id> | --build-id <id>) [--wait] [--timeout 600]Runs and results
operio runs create --input '{"projectId":"…","environmentId":"…","testCaseIds":["…"]}' [--wait] [--timeout 600]
operio runs create --project-id <id> (--environment-id <id> | --build-id <id>) --test-case-ids c1,c2 [--name "Nightly"] [--wait]
operio runs explore --goal "Buy the cheapest item as a guest" (--environment-id <id> | --build-id <id>) [--project-id <id>] [--name "Explore checkout"] [--wait] [--timeout 600]
operio runs list [--project-id <id>] [--status running] [--test-case-id <id>] [--start-date <iso>] [--end-date <iso>] [--limit 100] [--offset 0]
operio runs get <run-id> [--full]
operio runs stop <run-id>
operio results get <test-case-id> <result-id> [--full]Run commands require exactly one target: --environment-id for a web project
or --build-id for a mobile project. In --input JSON, the corresponding
mobile field is mobileBuildId.
Exploratory runs
runs explore starts an exploratory run: instead of executing test cases, the
agent works toward a plain-English --goal (up to 1000 characters) and reports
what it found. It takes the same targets, --name, --wait, and --timeout as
runs create, and --input accepts {"goal":"…","environmentId":"…"}. The
run's summary includes its type and goal; runs get <run-id> --full returns
the agent's complete result.
--wait
--wait polls until the run reaches a terminal state or --timeout seconds elapse (default 600), then prints a single final run summary on stdout.
The exit code carries the verdict:
0— the run completed and every case passed1— the run completed with failing cases, or the run itself failed, errored, or was stopped
That's what makes --wait usable directly as a CI gate:
operio suites run "$SUITE_ID" --environment-id "$ENV_ID" --wait || exit 1Pagination
tests list and runs list accept --limit and --offset and return pagination metadata (limit, offset, total, hasMore) alongside the page of items. Other list commands return the full collection.
operio tests list --limit 50 --offset 50