CLI Reference
The viscereality CLI mirrors the WPF desktop app's capabilities for
scripting, automation, and headless operation.
Installed Sussex packaged builds now expose a local agent workspace under
the current operator-data root. For unpackaged/source builds that is typically
%LOCALAPPDATA%\ViscerealityCompanion\agent-workspace; for packaged MSIX
installs it is the host-visible packaged path under
%LOCALAPPDATA%\Packages\<package-family>\LocalCache\Local\ViscerealityCompanion\agent-workspace.
The Sussex shell Home page includes Open Agent Workspace plus Copy Local Agent Prompt so installed-app users can hand a local agent a bundled
viscereality command, the mirrored CLI docs, and the Sussex example
catalogs without pointing it at the protected WindowsApps payload. The
generated workspace includes cli/current/Viscereality CLI.exe plus
viscereality.ps1 and viscereality.cmd wrapper scripts that preload the
mirrored sample-root overrides, point VISCEREALITY_LSL_DLL at the bundled
workspace copy when it is present, and export VISCEREALITY_OPERATOR_DATA_ROOT
so the bundled CLI uses the same host-visible operator-data root as the app.
For source builds, the simplest way to stage the official Quest-side developer tools the app expects is:
dotnet run --project src/ViscerealityCompanion.Cli -- tooling install-official
Sussex Workflow Split
For the Sussex study workflow there is now a deliberate split between CLI and GUI surfaces:
- CLI:
- deterministic setup, install, launch, status, and profile operations
- machine-readable inspection with
--json
Sequential Guidewindow:- one pre-session verification pass directly before a real participant
Experiment Sessionwindow:- the live participant-run surface for participant id entry,
Start Recording,Stop Recording, live telemetry, clock/network consistency, recenter, particle toggles, screenshots, direct dynamic-axis / fixed-axis calibration start controls, and quick access to the session folder, pulled Quest backup, and session review PDF
- the live participant-run surface for participant id entry,
The CLI currently mirrors the setup and profile side of Sussex. It does not
yet replace the participant-run Start Recording / Stop Recording flow in
the Experiment Session window. After Stop Recording, the GUI now pulls the
Quest backup into device-session-pull and generates session_review_report.pdf
inside the same participant session folder.
Running
From the guided-install local agent workspace under the current operator-data root, prefer:
.\viscereality.ps1 --help
That wrapper preloads the mirrored sample-root overrides before invoking the
bundled CLI under cli/current, and it now exports the bundled workspace
lsl.dll path automatically when that copy is present. It also exports
VISCEREALITY_OPERATOR_DATA_ROOT so the CLI keeps using the same host-visible
operator-data root as the packaged app.
From a source checkout, run:
dotnet run --project src/ViscerealityCompanion.Cli -- <command> [options]
Or install as a global tool:
dotnet pack src/ViscerealityCompanion.Cli
dotnet tool install --global --add-source src/ViscerealityCompanion.Cli/bin/Release viscereality
viscereality --help
Commands
Device Connection
| Command | Description |
|---|---|
probe |
Detect Quest devices connected via USB |
wifi |
Enable Wi-Fi ADB on the USB-connected Quest |
connect <endpoint> |
Connect to a Quest device over Wi-Fi |
status |
Query headset status (connection, battery, foreground app) |
App Management
| Command | Description |
|---|---|
install <apk> |
Install an APK on the connected Quest |
launch <package> |
Launch an app by package ID |
perf <cpu> <gpu> |
Set CPU and GPU performance levels (0–5) |
LSL Monitoring
| Command | Description |
|---|---|
monitor |
Monitor an LSL stream (continuous output) |
Options:
--stream <name>— stream name (default:quest_monitor)--type <type>— stream type (default:quest.telemetry)--channel <index>— channel index (default:0)
Twin Mode
| Command | Description |
|---|---|
twin send <action> |
Send a twin command (for example twin-start, twin-pause) |
twin status |
Show twin bridge status and settings comparison |
twin send is intentionally conservative for one-shot command testing. It now
waits briefly after opening the LSL bridge before publishing and keeps the
process alive briefly after publishing so the outlet has time to advertise and
deliver the sample:
--settle-ms <milliseconds>controls the pre-send settle delay--hold-ms <milliseconds>controls the post-send hold delay
The defaults are suitable for normal local validation. Shorten them only when you already have a stable receiver path and need a faster scripted loop.
Catalog
| Command | Description |
|---|---|
catalog list |
List available apps, bundles, and profiles |
Options:
--root <path>— catalog root directory (auto-detected if omitted)
Study Shells
| Command | Description |
|---|---|
study list |
List available pinned study shells |
study install <study> |
Install the pinned study APK |
study apply-profile <study> |
Apply the pinned study device profile |
study launch <study> |
Launch the pinned study runtime using the study launch policy. The command now refuses to launch while the headset reports asleep; wake the headset first. |
study stop <study> |
Stop the pinned study runtime and unwind any study task-pinning policy |
study status <study> |
Compare current headset state against the pinned study baseline |
study probe-connection <study> |
Mirror the Step 9 Probe Connection check: inspect the pinned APK match, pinned device profile state, Quest Wi-Fi transport reachability, expected inlet, quest_twin_state return path, Wi-Fi snapshot context, and twin transport detail |
study diagnostics-report <study> |
Run the Windows LSL, machine inventory, Quest setup, Quest Wi-Fi transport, twin return-path, and safe command-acceptance diagnostics and write a shareable JSON/LaTeX/PDF report folder |
For Sussex, the study id is currently sussex-university.
Remote headset wake/sleep is no longer part of the supported public GUI
operator flow for Sussex. Use manual headset wake/sleep, and clear Guardian or
other Meta visual blockers before study launch.
Sussex Profiles
The Sussex profile commands mirror the GUI profile tabs and are the preferred agentic path for repeatable tuning work:
sussex visual ...sussex condition ...sussex controller ...
Common subcommands on both surfaces are:
listfieldsshow <profile>createupdate <profile>delete <profile>import <path>export <profile> <path>set-startup <profile>clear-startupapply-live <profile>
Use --json whenever an agent needs stable machine-readable output.
For the controller-breathing surface, the calibration setup is now part of the same field catalog and profile commands:
use_principal_axis_calibration=onkeeps the dynamic motion-axis solveuse_principal_axis_calibration=offkeeps the fixed warmed-up controller orientationmin_accepted_delta=0.0008controls how much movement counts as a new accepted calibration samplemin_acceptable_travel=0.02controls how much total travel calibration must see before it accepts the solvevibration_inhale_frequency/vibration_inhale_intensityset the controller vibration used while the runtime classifies inhalevibration_exhale_frequency/vibration_exhale_intensityset the controller vibration used while the runtime classifies exhalevibration_retention_frequency/vibration_retention_intensityset the tracked low-motion retention vibration
Bad tracking has no vibration parameters. The Sussex runtime always disables controller vibration while tracking is bad, the selected controller is inactive, or controller-breathing calibration has not been accepted yet.
Example:
viscereality sussex controller fields --json
viscereality sussex controller update "<profile>" `
--set use_principal_axis_calibration=off `
--set min_accepted_delta=0.0008 `
--set min_acceptable_travel=0.02 `
--json
The release also bundles two low-motion controller profiles derived from the bundled baseline:
Small Motion MildSmall Motion Conservative
Small Motion Conservative is the pinned startup controller profile for the
current Sussex packaged release. Startup/default pinning and current-session hotload are
separate:
sussex controller set-startup "<profile>"changes what the next Sussex launch stages to the headsetsussex controller apply-live "<profile>"hotloads the currently running Sussex session and does not rewrite the saved next-launch profile
Both paths reset controller-breathing calibration in the runtime. Recalibrate on-headset afterward.
Sussex Conditions
The Sussex condition commands mirror the GUI Conditions tab. A condition is
the experiment-session choice that links one visual profile, one
controller-breathing profile, and an active-selection flag:
| Command | Description |
|---|---|
sussex condition list |
List bundled conditions, local overrides, and local-only conditions |
sussex condition list --active-only |
List exactly what the Experiment Session condition dropdown will show |
sussex condition show <condition> |
Show one condition with resolved profile names |
sussex condition create |
Create a local condition from one visual profile and one breathing profile |
sussex condition update <condition> |
Edit a local condition, or save a bundled condition as a local override |
sussex condition duplicate <condition> |
Copy a condition into a new local condition |
sussex condition import <path> |
Import a shared condition JSON file |
sussex condition export <condition> <path> |
Export one condition as shareable JSON |
sussex condition delete <condition> |
Delete a local condition, or remove a local override |
The CLI accepts the portable bundled profile ids used by the GUI, such as
condition-current-visual, condition-fixed-radius-no-orbit,
condition-current-breathing, and condition-fixed-radius-breathing.
Example:
viscereality sussex condition create `
--id small-motion-no-orbit `
--label "Small Motion, No Orbit" `
--visual condition-fixed-radius-no-orbit `
--breathing "Small Motion Conservative" `
--inactive `
--property visual.orbit=0..0 `
--json
viscereality sussex condition update small-motion-no-orbit --active --json
viscereality sussex condition list --active-only --json
The packaged app and packaged CLI share the same host-visible operator-data
root, so conditions edited through the GUI are visible to the CLI and
conditions imported through the CLI are visible in the GUI after refreshing or
opening the Conditions tab.
Utilities
| Command | Description |
|---|---|
utility home |
Return to Quest launcher |
utility back |
Send back event |
utility wake |
Wake Quest display |
utility list |
List installed packages |
utility reboot |
Reboot Quest |
hzdb
| Command | Description |
|---|---|
hzdb screenshot |
Capture a Quest screenshot |
hzdb perf |
Capture a Perfetto trace |
| `hzdb proximity <enable | disable>` |
hzdb wake |
Wake the Quest |
hzdb info |
Read detailed device info |
hzdb ls <path> |
List files under a Quest path |
hzdb pull <remote-path> <local-path> |
Pull one Quest file to Windows |
Tooling
| Command | Description |
|---|---|
tooling status |
Show the local managed official Quest tooling cache state |
tooling status --check-upstream |
Also query the latest published upstream versions |
tooling install-official |
Install or update Meta hzdb plus Android platform-tools into the current operator-data root under ...\ViscerealityCompanion\tooling |
tooling status only covers the managed official Quest tool cache. It does not
decide whether liblsl is available in the current process layout.
Windows Environment
| Command | Description |
|---|---|
windows-env analyze |
Mirror the GUI Analyze Windows Environment check for adb, hzdb, liblsl, Windows network-adapter hazards, the local twin bridge, the exported agent workspace, liblsl discovery health, a temporary local LSL outlet rediscovery check, and the expected upstream LSL stream. When a live headset selector is available, it also adds a Quest Wi-Fi transport-path check that probes raw reachability to the headset's current Wi-Fi ADB endpoint. |
Useful safety flags:
--local-onlyskips persisted headset selectors and all ADB-backed Quest Wi-Fi transport probes. Use this when the headset is being used for something else and you only want the Windows/package/liblsl side.--skip-stream-probeskips the expected upstream HRV LSL stream lookup.--check-timeout-seconds <n>bounds each heavyweight diagnostic check. A timed-out check returns a warning and the analyzer still prints the remaining partial diagnostics.
windows-env analyze separates four related LSL questions:
- whether this Windows process can load the liblsl runtime
- whether liblsl discovery can run at all without a socket / adapter error
- whether this PC can advertise a temporary local LSL outlet and rediscover it
- whether the expected
HRV_Biofeedback / HRVsender is currently visible on Windows
That distinction matters because the Quest can sometimes receive a sender while
the Windows-side discovery inventory is failing. When the discovery self-check
reports set_option or "requested address is not valid in its context", or
when the local loopback outlet cannot be rediscovered, treat that as a Windows
adapter / multicast / firewall-profile hazard first. The analysis also lists
active IPv4 adapters and warns about common instability sources such as VPN,
Tailscale, WireGuard, Hyper-V, Docker, WSL, TAP/Wintun, VirtualBox, VMware,
multiple default gateways, and adapters without multicast support.
When a headset is connected over Wi-Fi ADB, windows-env analyze now also
checks the PC↔Quest router path directly:
- whether the selector IP matches the headset-reported Wi-Fi IP
- whether the host Wi-Fi adapter and Quest appear to share the same IPv4 subnet
- whether Windows can ping the Quest IP
- whether Windows can open TCP port
5555on the Quest IP
If the PC and Quest report the same SSID but TCP 5555 is blocked, treat that
as a router/client-isolation hazard first, not as proof that the Sussex APK or
Windows liblsl path is broken.
Use study probe-connection sussex-university --wait-seconds 15 for the
headset-side half. That probe now reports the pinned Sussex build match and the
required device profile before it reports the runtime inlet and
quest_twin_state return path. It also inventories the Windows-visible
quest_twin_state / quest.twin.state publisher and prints the source id that
the companion expects from the pinned Sussex APK. If the Quest visibly reacts
to the TEST sender but Probe Connection says no quest_twin_state has reached
Windows, treat that as a return-telemetry problem rather than a forward-LSL
problem. If the new Twin-state outlet line says no publisher is visible, look
at Quest-to-Windows multicast/client-isolation or whether the Sussex scene is
publishing the twin-state outlet. If it shows a visible outlet with a different
source id, reinstall the pinned APK and capture the CLI JSON because that points
at a Quest build/source-id contract mismatch.
Use study diagnostics-report sussex-university --wait-seconds 15 when you
need one artifact to send to another maintainer. The command writes a
timestamped folder under the operator-data diagnostics root containing
sussex_lsl_twin_diagnostics.json, sussex_lsl_twin_diagnostics.tex, and
sussex_lsl_twin_diagnostics.pdf. The report combines windows-env analyze,
machine-visible LSL inventory, the Quest pinned APK/profile snapshot, the raw
Quest Wi-Fi transport path, quest_twin_state publisher visibility, the Step
9 return-path interpretation, and a safe particle-off command acknowledgement
probe.
Use --skip-command-check for passive inspection only.
Environment Variables
| Variable | Purpose |
|---|---|
VISCEREALITY_QUEST_SESSION_KIT_ROOT |
Override catalog root directory |
VISCEREALITY_OPERATOR_DATA_ROOT |
Override the host-visible operator-data root used for session state, study data, screenshots, tooling, and agent-workspace compatibility |
VISCEREALITY_ADB_EXE |
Override the adb.exe path the app and CLI should use |
VISCEREALITY_HZDB_EXE |
Override the hzdb.exe path the app and CLI should use |
VISCEREALITY_LSL_DLL |
Path to lsl.dll for LSL features |
Example
viscereality probe
viscereality wifi
viscereality connect 192.168.43.1:5555
viscereality perf 4 4
viscereality install path/to/app.apk
viscereality launch com.Viscereality.SussexExperiment
viscereality twin send twin-start
viscereality monitor --stream quest_monitor --type quest.telemetry
Example Sussex Agent Workflow
viscereality study status sussex-university
viscereality windows-env analyze
viscereality study probe-connection sussex-university
viscereality study diagnostics-report sussex-university --wait-seconds 15
viscereality study install sussex-university
viscereality study apply-profile sussex-university
viscereality study launch sussex-university
viscereality sussex visual fields --json
viscereality sussex visual apply-live "<profile>" --json
viscereality sussex condition list --active-only --json
viscereality sussex condition show fixed-radius-no-orbit
viscereality sussex controller fields --json
viscereality sussex controller show "Small Motion Conservative" --json
viscereality sussex controller set-startup "Small Motion Conservative" --json
# Optional for a running, foreground Sussex session:
viscereality sussex controller apply-live "Small Motion Conservative" --json
After that deterministic CLI setup:
- Open the Sussex
Sequential Guidein the desktop app and complete the pre-session checks. - Use the guide's final handoff or the Home screen button to open
Experiment Session. - Run the real participant session from that window with
Start RecordingandStop Recording. - After
Stop Recording, use the same window to open:- the Windows session folder
- the pulled Quest backup folder
- the generated
session_review_report.pdf
If you need a CLI-only recovery path for Quest-side files after the run, use
hzdb ls plus hzdb pull against the recorded study.recording.device.session_dir
or the session_snapshot.json entry in the Windows session folder.