V
Vibeview
Pricing

CLI

Run VibeView tests from the command line. Integrate with CI/CD pipelines for automated mobile testing.

Quick Start

# 1. Install (see Installation section for registry setup)
npm install -g @scriptx-com/vibeview-cli

# 2. Log in (opens browser)
vibeview login --base-url https://vibeview.io

# 3. Run a test suite
vibeview run-suite <suite-id> --output human

Installation

The CLI is distributed as a private npm package on GitHub Packages.

1. Configure npm for the VibeView registry:

Create or update .npmrc in your home directory (or project root):

@scriptx-com:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_PAT

Replace YOUR_GITHUB_PAT with a GitHub Personal Access Token that has packages:read scope.

2. Install globally:

npm install -g @scriptx-com/vibeview-cli

Requirements: Node.js 20 or later.

After installation, the vibeview command is available in your terminal.

Authentication

The CLI resolves your API token in this order:

  1. --token flag — pass a token directly on each command.
  2. VIBEVIEW_API_TOKEN environment variable — best for CI environments.
  3. Config file — saved automatically by vibeview login at ~/.vibeview/config.json.

If no token is found, the CLI exits with an error and suggests using the --token flag, setting VIBEVIEW_API_TOKEN, or running vibeview login.

The server URL is resolved similarly: --base-url flag, then VIBEVIEW_BASE_URL environment variable, then config file, then the built-in default https://vibeview.io. If you run against a self-hosted or staging instance, set the server URL explicitly via --base-url or VIBEVIEW_BASE_URL.

Commands

login

Log in to VibeView interactively. Opens your browser to complete authentication, then saves the token locally.

vibeview login --base-url https://vibeview.io
OptionDescription
--base-url <url>VibeView server URL (defaults to https://vibeview.io)

The command:

  1. Opens your browser to the VibeView login page.
  2. Waits up to 2 minutes for you to complete login.
  3. Saves the token to ~/.vibeview/config.json (file permissions 0600).

list-suites

List all test suites available in your organization.

vibeview list-suites --output human
OptionDescriptionDefault
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)
--output <format>Output format: human, jsonhuman
--tag <tag>Filter by tag (repeatable)(all suites)
--match <mode>any or all — how multiple --tag values are combinedany

Example output (human):

  3 suite(s)

  abc123  Login Flow [ios] [smoke, auth]  (4 cases)
  def456  Checkout  [android]  (6 cases)
  ghi789  Onboarding [ios] [smoke]  (3 cases)

Tags (when present) are shown in brackets after the platform. Descriptions are not rendered in human output — use --output json to retrieve them.

Example output (JSON):

[
  {
    "id": "abc123",
    "name": "Login Flow",
    "platform": "ios",
    "case_count": 4,
    "description": "Covers email/password and SSO sign-in.",
    "tags": [
      { "name": "smoke", "display_name": "Smoke" },
      { "name": "auth", "display_name": "Auth" }
    ]
  }
]

Every suite includes description (string or null) and tags (array, possibly empty). Use JSON output when you need either field — for example, to drive downstream tooling that picks suites by description text or tag membership.

Tag filtering example:

vibeview list-suites --tag profiles --tag smoke --match any

run-suite

Run all test cases in a suite and wait for results.

vibeview run-suite <suite-id> [options]
OptionDescriptionDefault
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)
--output <format>Output format: human, json, junithuman
--verboseShow per-case breakdownfalse
--timeout <seconds>Max wait time in seconds300
--commit-sha <sha>Git commit SHA for GitHub status checks(none)
--model <model>AI model to use(server default)
--provider <provider>AI provider(server default)
--mode <mode>Execution mode: hybrid, ai, replay(server default)
--device-category <category>Device category to allocate: phone, tablet, tvphone
--device <device_id>Pin run to a specific device (see list-devices). Conflicts with --device-category.(none)
--build <id>Specific AppBuild id to run against (integer). Defaults to the suite app’s latest build when omitted.(latest)
--metadata <json>JSON object passed through unchanged to webhook payloads (e.g. PR context)(none)
--metadata-file <path>Read the metadata JSON object from a file — use for nested JSON in CI(none)

The command triggers the suite run, then polls every 3 seconds until the run completes or the timeout is reached. The polled JSON result includes per-step/per-case error_kind (failure classification) and screenshot_signed_url (signed, no-auth image URL) for programmatic consumers — see Reading run results in the CI testing guide.

Example:

vibeview run-suite abc123 \
  --commit-sha $(git rev-parse HEAD) \
  --output junit \
  --timeout 300

Pin a specific build:

vibeview run-suite abc123 --build 142

The id is the numeric AppBuild id, visible on the app detail page. If the suite has no app attached, --build returns an error.

run-suites

Run all suites matching a tag filter, sequentially. Each matched suite gets its own device session and SuiteRun. Useful when CI doesn’t know specific suite IDs but knows what areas changed in a PR.

vibeview run-suites --tag profiles --commit-sha $GIT_SHA
OptionDescriptionDefault
--tag <tag>Tag to match (repeatable)required
--match <mode>any matches if a suite has any of the tags; all requires every tagany
--platform <platform>Restrict the tag-matched set to one platform: ios, android, tvos, androidtv. Suites of other platforms are skipped (and reported).(no filter)
--output <format>Output format: human, json, junithuman
--verbosePrint per-suite progress as they completefalse
--timeout <seconds>Per-suite timeout. Total wait is capped at 2 hours regardless of N.300
--build <id>AppBuild id, validated against every matched suitelatest
--commit-sha <sha>Git SHA propagated to every SuiteRun-
--model <model>AI modelinferred
--provider <provider>AI providerinferred
--mode <mode>Execution mode: hybrid, ai, replayhybrid
--device-category <category>Device category to allocate: phone, tablet, tvphone
--device <device_id>Pin run to a specific device (see list-devices). Conflicts with --device-category.(none)
--metadata <json>JSON object passed through unchanged to webhook payloads (e.g. PR context)(none)
--metadata-file <path>Read the metadata JSON object from a file — use for nested JSON in CI(none)
--token <token>API token (or set VIBEVIEW_API_TOKEN)-
--base-url <url>VibeView server URL (or set VIBEVIEW_BASE_URL)-

Exit codes: 0 aggregate passed; 1 any suite failed; 2 no matches / timeout / error / cancelled.

Example: run all suites tagged auth with the GitHub commit SHA propagated:

vibeview run-suites --tag auth --commit-sha $(git rev-parse HEAD) --output junit > results.xml

Scoping to one platform with --platform: A tag like prod may be shared by suites across iOS, Android, and TV. In a CI matrix where each job builds a single platform, add --platform so the job only runs the suites it actually built an app for — the rest are skipped and listed as excluded:

# A job that built the Android APK only runs the Android suites tagged prod
vibeview run-suites --tag prod --platform android

A suite’s platform comes from the suite itself, or its linked app. Suites with no resolvable platform are treated as a mismatch and excluded under a --platform filter. Omitting --platform keeps the previous behavior — every tag-matched suite runs. --platform combines with --match: --match all --platform android runs suites that have all the given tags and target Android.

run-test

Run a single test case and wait for results.

vibeview run-test <test-id> [options]
OptionDescriptionDefault
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)
--output <format>Output format: human, json, junithuman
--verboseShow step detailsfalse
--timeout <seconds>Max wait time in seconds300
--commit-sha <sha>Git commit SHA for GitHub status checks(none)
--model <model>AI model to use(server default)
--provider <provider>AI provider(server default)
--mode <mode>Execution mode: hybrid, ai, replay(server default)
--device-category <category>Device category to allocate: phone, tablet, tvphone
--device <device_id>Pin run to a specific device (see list-devices). Conflicts with --device-category.(none)
--build <id>Specific AppBuild id to run against (integer). Defaults to the test case app’s latest build when omitted.(latest)
--metadata <json>JSON object passed through unchanged to webhook payloads (e.g. PR context)(none)
--metadata-file <path>Read the metadata JSON object from a file — use for nested JSON in CI(none)

Example:

vibeview run-test test-789 --mode ai --output json

Pin a specific build:

vibeview run-test test-789 --build 142

The id is the numeric AppBuild id, visible on the app detail page. If the test case has no app attached, --build returns an error.

When the device pool is busy

If no matching device is available when you submit a run, VibeView queues you instead of failing. The CLI’s spinner shows your live position:

Queued — position 3 in line for iPhone 15 Pro (tap-pool-01)

Once a device frees up, the run automatically transitions through pending and into running without any intervention on your side.

--timeout covers the entire journey — queue wait plus execution — so set it generously when the pool is contended. On Ctrl+C or --timeout, the CLI cancels its queue entry server-side so the slot doesn’t sit unused.

If you target a specific device with --device <id>, the queue only counts users waiting for that device. Use vibeview list-devices to see what’s currently available or busy.

upload-app

Upload an app build file. If an app with the same bundle/package ID and platform already exists, the build is added to the existing app instead of creating a new one.

vibeview upload-app <file> [options]

Supported file types: .app (iOS simulator build — plain, .zip, .tar.gz, or .tgz archive) and .apk / .apks (Android). .ipa files are rejected: iOS simulators require simulator .app builds, not device .ipa archives.

OptionDescriptionDefault
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)
--output <format>Output format: human, jsonhuman
--name <name>App name (auto-detected from binary if not provided)(auto-detected)

Example:

vibeview upload-app ./build/MyApp.app --output json

Returns the app ID (public_id) which can be used with create-test --app.

create-test

Create a standalone AI test case. The test name can be passed as a positional argument; steps can be provided inline, from a file, or piped via stdin.

vibeview create-test [name] [options]
OptionDescriptionDefault
[name]Test case name (positional argument)CLI Test
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)
--output <format>Output format: human, jsonhuman
--app <id>App ID (public_id) or package name (requires --platform)(required)
--platform <platform>Platform (ios, android) when using package name for --app(optional)
--steps <json>Test steps as inline JSON array(one of steps/steps-file/stdin required)
--steps-file <path>Path to JSON file containing test steps(optional)
--context <text>Additional context for AI test execution(optional)
--test-name <name>Test case name (alternative to the positional argument; the positional wins if both are given)CLI Test

Steps are an array of objects with a description field:

[{"description": "Open the app"}, {"description": "Tap Login"}, {"description": "Verify home screen"}]

Examples:

# Inline steps
vibeview create-test --app abc123 --steps '[{"description":"Open app"},{"description":"Tap Login"}]'

# From a file, with the name as a positional argument
vibeview create-test "Login Flow" --app abc123 --steps-file ./test-steps.json

# Piped from another tool
echo '[{"description":"Verify onboarding"}]' | vibeview create-test --app abc123

list-apps

List all apps in your organization.

vibeview list-apps [options]
OptionDescriptionDefault
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)
--output <format>Output format: human, jsonhuman

Example output (human):

  3 app(s)

  abc123  MyApp [ios]  com.example.myapp
  def456  MyApp [android]  com.example.myapp
  ghi789  TestApp [ios]  com.test.app

list-devices

List devices registered with the platform — useful to find a device_id to pass to --device.

vibeview list-devices [options]
OptionDescriptionDefault
--type <type>Filter by device type: ios, android(all)
--category <category>Filter by category: phone, tablet, tv(all)
--status <status>Filter by status: available, busy, offline(all)
--output <format>human or jsonhuman
--token <token>API token(from auth resolution)
--base-url <url>VibeView server URL(from auth resolution)

Example: find an available Android TV:

vibeview list-devices --type android --category tv

Sample output:

DEVICE_ID         NAME              TYPE     CATEGORY  OS    STATUS
atv-01            Apple TV 4K       ios      tv        17.5  available
emu-tv-01         Android TV        android  tv        34    busy

Output Formats

human

Readable terminal output with colors and a spinner during execution. Best for local development.

json

Structured JSON for programmatic parsing. Includes full run result with per-case status, duration, and error messages.

junit

JUnit XML format for CI/CD integration. Compatible with GitHub Actions, Jenkins, GitLab CI, and other CI systems that consume JUnit reports.

Example: upload JUnit results as a GitHub Actions artifact

- name: Run VibeView suite
  run: vibeview run-suite ${{ secrets.SUITE_ID }} --output junit > results.xml

- name: Upload test results
  uses: actions/upload-artifact@v4
  with:
    name: vibeview-results
    path: results.xml

Exit Codes

CodeMeaning
0All tests passed
1One or more tests failed
2Execution error (network failure, authentication error, timeout, or a cancelled run)

Use exit codes in CI scripts to gate deployments:

vibeview run-suite $SUITE_ID --commit-sha $COMMIT_SHA || exit 1

CI/CD Integration

For the simplest GitHub Actions setup, use the VibeView workflow template which wraps these CLI commands automatically.

test-spec.json Convention

CI pipelines can store test configuration in .vibeview/test-spec.json at the repository root. This file defines the test steps as code, allowing AI agents and automation tools to describe tests declaratively. The app build path comes from the workflow’s APP_PATH env var (not the spec file), and platform is auto-detected from the binary at upload time.

{
  "version": 1,
  "steps": ["Launch the app", "Verify the home screen loads"],
  "context": "Optional context for the AI agent",
  "test_name": "My Test"
}

The workflow template reads this file automatically. For the full schema reference and examples, see the CI Testing guide.

GitHub Actions

name: VibeView Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: https://npm.pkg.github.com
          scope: '@scriptx-com'

      - name: Install VibeView CLI
        run: npm install -g @scriptx-com/vibeview-cli
        env:
          NODE_AUTH_TOKEN: ${{ secrets.VIBEVIEW_NPM_TOKEN }}

      - name: Run test suite
        env:
          VIBEVIEW_API_TOKEN: ${{ secrets.VIBEVIEW_API_TOKEN }}
          VIBEVIEW_BASE_URL: ${{ secrets.VIBEVIEW_BASE_URL }}
        run: |
          vibeview run-suite ${{ secrets.SUITE_ID }} \
            --commit-sha ${{ github.sha }} \
            --output junit > results.xml

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: vibeview-results
          path: results.xml

Tip: replace run-suite ${{ secrets.SUITE_ID }} with run-suites --tag <area> to run a tag-filtered set instead of a single suite.

Generic CI

For any CI system, set the VIBEVIEW_API_TOKEN and VIBEVIEW_BASE_URL environment variables, then call the CLI:

export VIBEVIEW_API_TOKEN="your-token-here"
export VIBEVIEW_BASE_URL="https://vibeview.io"

vibeview run-suite <suite-id> --commit-sha $(git rev-parse HEAD) --output human

The CLI exits with code 0 on success and 1 on failure, so your CI pipeline can use the exit code to pass or fail the build.