Skip to content

digablesolutions/luotsi

Repository files navigation

Luotsi

CI workflow Release workflow .NET 10 Platform Android

Luotsi

Luotsi is a host-driven CLI for Android device automation, inspection, and live view. It runs on the engineer or CI machine, talks to real devices over ADB, and returns structured JSON results plus artifacts. Orchestration, policy, and diagnostics stay on the host; the on-device helper stays thin and purpose-built.

How it works

  1. Run a command — every command returns one JSON envelope with ok, data, artifacts, and error. No third-party device server required.
  2. Run a scenario — drive multi-step device flows from a small JSON playbook. Steps are validated, templated, and timed; failures produce artifact bundles automatically.
  3. Inspect mode — open a JSONL session for agent-driven exploration. Luotsi emits screen snapshots and diffs so an agent can reason about the UI and act without a scenario file.
  4. Live view — stream a mirrored device display to a local SDL window with an operator control layer, hotkeys, and JSONL events for agents consuming stream state.
  5. Telemetry — parse structured LUOTSI_DEVICE_TELEMETRY events from logcat for semantic waits and assertions.
  6. CI-friendly — same binary, same output shape for engineers, CI pipelines, and agent-driven flows.

Install

Download a self-contained archive from GitHub Releases. Each archive contains a single luotsi executable (luotsi.exe on Windows) with no separate .NET runtime required.

# macOS / Linux
./luotsi devices

# Windows (PowerShell)
./luotsi.exe devices

Source builds. The repo is pinned to .NET SDK 10.0.300 (see global.json):

dotnet run --project Luotsi.Cli -- devices

Build and test:

dotnet build Luotsi.sln
dotnet test Luotsi.sln

Code layout

Path Contents
Luotsi.Cli/Cli/ Entrypoint, command dispatch, help text, inspect-mode session loop
Luotsi.Cli/Hosts/Android/ Android transport and device interaction runtime
Luotsi.Cli/Artifacts/ Artifact session management
Luotsi.Cli/Models/ Shared records, envelopes, screen and scenario data models
Luotsi.Cli/Scenarios/ Scenario execution flow and failure plumbing
Luotsi.Cli/Telemetry/ Telemetry parsing contracts and logcat parser
Luotsi.Cli/Errors/ Typed command and wait exceptions
Luotsi.Cli/Infrastructure/ Interfaces and default system-backed implementations

Commands

Quick reference. See docs/commands.md for flags, retry behavior, and wireless pairing details.

Device & ADB

Command Description
devices List adb-visible devices
adb server-status Host ADB server status
adb version ADB binary version
adb features --device <serial> ADB feature set for a device
adb mdns check mDNS availability check
wait-for-device --device <serial> Wait for device readiness
adb reconnect offline Reconnect an offline ADB transport
preflight --device <serial> --package <app.id> Device preflight check
screen-state --device <serial> Dump current screen state

View & Profiles

Command Description
view --device <serial> [options] Open live streaming mirror (JSONL session)
view --profile <name> Open view using a saved profile
view --last Reopen the last successful view session
reconnect Reconnect using the last successful profile
view-doctor --device <serial> Diagnostic report without opening a stream
profile-list List saved profiles
profile-delete --name <name> Delete a saved profile

Wireless

Command Description
wireless --device <usb-serial> Switch a USB device to TCP/IP mode (Android ≤10)
wireless-scan Discover TLS pairing and connect services via mDNS
wireless-pair --endpoint <host:port> --code <code> Pair a device for wireless debugging (Android 11+)
wireless-connect --service <name> Connect to a paired device and return its selector

Port Forwarding

Command Description
forward --local <endpoint> --remote <endpoint> Forward host port → device port
forward-list List active forwards
forward-remove --local <endpoint> Remove a forward
reverse --remote <endpoint> --local <endpoint> Forward device port → host port
reverse-list List active reverses
reverse-remove --remote <endpoint> Remove a reverse

App Lifecycle

Command Description
start-app --package <app.id> [--activity <activity>] [--wait] Launch an app
start-uri --uri <uri> [options] Launch a URI intent
force-stop --package <app.id> Force-stop an app
clear --package <app.id> Clear app data
wait-for-activity --activity <pattern> Wait for activity in the foreground
wait-for-not-activity --activity <pattern> Wait for activity to leave the foreground
is-app-installed --package <app.id> Check if a package is installed
list-installed-packages [--third-party] List installed packages
grant-permission --package <app.id> --permission <permission> Grant a runtime permission
revoke-permission --package <app.id> --permission <permission> Revoke a runtime permission

Telemetry & Waits

Command Description
telemetry-tail --device <serial> --tail <n> Snapshot recent telemetry from logcat
telemetry-watch --device <serial> --timeout-sec <n> Collect telemetry over a bounded window
wait-log --device <serial> --contains <text> --timeout-sec <n> Wait for a matching logcat line
tap-text --device <serial> --text <text> Tap a UI element by visible text
wait-step --device <serial> --step <name> Wait for a semantic step telemetry event
wait-action-ready --device <serial> --action <name> [--step <name>] Wait for a semantic action-ready telemetry event

Scenarios & Inspect

Command Description
run --device <serial> --file <path> Execute a JSON scenario playbook
inspect --device <serial> Open an agent-driven JSONL inspection session

View session

view is a long-lived JSONL session that mirrors a connected device to a local SDL window. See docs/view-session.md for the full reference.

Key flags: --preset <name> (low-latency / balanced / high-quality / safe), --capture-backend <auto|screenrecord|mediaprojection>, --save-profile <name>, --record <file>, --share-bind <host:port>, --read-only.

The SDL window has a clickable toolbar, multi-device shelf, and hotkeys (F1–F12, Ctrl+V, drag-and-drop). Full hotkey and JSONL event tables are in docs/view-session.md.

Inspect mode

inspect opens a JSONL session for agent-driven exploration without a scenario file. Startup emits session_started and an initial screen_snapshot; state-affecting commands emit command_result followed by a screen_delta.

luotsi inspect --device 192.168.0.134:5555

Send one JSON command per line:

{"id":"1","command":"refresh"}
{"id":"2","command":"tap_text","text":"Sign in","timeout_sec":10}
{"id":"3","command":"telemetry_tail","tail":200}
{"id":"4","command":"exit"}

Available inspect commands: refresh, tap, tap_text, wait_visible, type_text, keyevent, telemetry_tail, telemetry_watch, exit.

Scenarios

Scenarios are JSON playbooks. See docs/scenarios.md for the full format, template syntax, and action reference.

{
  "name": "android-home-smoke",
  "steps": [
    { "name": "go home",            "action": "keyevent",       "code": "KEYCODE_HOME" },
    { "name": "let launcher settle","action": "sleep",          "milliseconds": 750 },
    { "name": "capture screenshot", "action": "takeScreenshot", "label": "android-home-smoke" }
  ]
}

Template syntax: ${env:NAME}, ${env:NAME|fallback}, ${var:name}, ${now:HHmmss}.

Generic examples: examples/scenarios/android-home-smoke.json, examples/scenarios/android-navigation-smoke.json.

Output format

Every command returns a single JSON envelope:

{
  "schema": "luotsi-command.v1",
  "ok": true,
  "command": "screen-state",
  "data": {},
  "artifacts": {
    "artifact_root": "/tmp/luotsi/..."
  },
  "error": null
}

Scenario run commands return the scenario result inside data, including per-step timing and top-level overhead:

{
  "scenario": "android-home-smoke",
  "status": "passed",
  "timing": {
    "total_ms": 86361.4686,
    "prologue_ms": 655.9714,
    "steps_ms": 85701.7421,
    "non_step_ms": 659.7265
  },
  "steps": []
}

Artifacts

Every command that reaches the device writes artifacts to a dedicated artifact root. Failures produce a bundle automatically:

  • device-fingerprint.json — written by preflight and scenario runs
  • wait-log.txt / wait-log.json — log streaming waits
  • telemetry-tail.txt / telemetry-tail.json — telemetry snapshots
  • telemetry-watch.txt / telemetry-watch.json — bounded telemetry collection
  • Failure bundles — screenshot, logcat, screen-state, hierarchy, and metadata when a runtime command fails after reaching the device

Documentation

Doc Contents
docs/commands.md Full command reference with flags, retry behavior, wireless pairing
docs/view-session.md Presets, backends, profiles, hotkeys, JSONL events, sharing
docs/scenarios.md Playbook format, template syntax, all actions
docs/architecture.md System architecture and component flow
docs/subsystems.md CLI, host automation, scenario, view, and telemetry subsystems

About

Luotsi is a host-driven CLI for Android device automation, inspection, and live view.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors