Skip to content

Releases: olef-dev/olef

Olef v3.0.2

Choose a tag to compare

@andriyo andriyo released this 03 Nov 04:25

A reliability and security release from a full code audit: no workflow
changes, a few new options, and several hundred fixes.

  • Errors say what to change in hints: every JSON error now carries a
    hints list with the advice in words (for example, which flag to pass).
    next_actions is still the list of commands to run next. The same advice
    stays in msg for this release; read hints instead, because the prose
    in msg and the single detail.hint will go away in the next one.
  • olef watch says it's still alive: after 15 s with nothing else to
    report, watch prints a {"type":"heartbeat"} line, so an agent can tell
    an idle stream from a dead one. Ignore lines of that type; --heartbeat-ms
    changes the interval and 0 turns it off.
  • Lock the proxy away from local services, or step around pinning:
    olef net start --block-host <host|ip|cidr> and --block-local refuse
    connections from the app to your machine's loopback or local network
    (allowed by default, so dev servers keep working). Hosts that pin their
    certificate can be relayed untouched with --passthrough-host <glob> or,
    while the proxy runs, olef net passthrough add --host <glob>; a TLS
    failure that looks like pinning now suggests that command.
  • The device viewer's Send needs your click: sending your notes or
    recorded steps to the agent now works only from a real click in the
    viewer, never from a tool the agent can call.
  • olef devices in a linked project lists this machine first: your
    emulators and USB phones, with the linked Olef Cloud workspace's devices
    in their own cloud section. Listing never starts a cloud session.
  • The debugger stops leaving apps frozen: two stops close together
    (two breakpoint hits, or a pause racing a hit) could leave the app
    suspended after resume. Kotlin listOf() and Arrays.asList values
    now show their items, and breakpoints inside Java lambdas bind.
  • Leased phones and labs:
    • A release that times out keeps the lease as pending_release instead
      of forgetting a lease that's still billed.
    • A status error no longer cancels a live or starting lease.
    • Spend isn't counted past a lease's end after the computer sleeps.
    • On a lab host, the agent only forwards the adb services a lessee needs,
      and removing a device ends its open streams.
  • The on-device server refuses web pages: requests whose Host or
    Origin isn't a loopback address are refused, which stops a page in the
    device's browser from reaching it.
  • Olef Cloud sync and remote commands: a file the worker refuses no
    longer stalls sync forever, paths a worker sends can't escape their
    folder on Windows, and large inputs are streamed instead of held in
    memory.
  • Many smaller fixes across the proxy (gRPC and HTTP/2 trailers, a
    response body forwarded byte for byte when nothing edits it), record and
    replay (typed passwords are kept as secrets, swipes compile to
    ui swipe), test runs (test run --timeout-ms, killed scripts reported
    as such), fault injection (fault run --step-timeout-ms, clean-up after
    Ctrl-C), app apply, why, doctor and the plugins.

Update with olef update and run the command it prints. The first
olef connect after updating installs the matching on-device server, and
the first olef app apply may reinstall the app once.

Install

macOS and Linux: brew install olef-dev/tap/olef, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/olef-dev/olef/releases/download/v3.0.2/olef-installer.sh | sh

Windows: scoop bucket add olef https://github.com/olef-dev/scoop-bucket and scoop install olef, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/olef-dev/olef/releases/download/v3.0.2/olef-installer.ps1 | iex"

Already installed? olef update prints the command for your install. See updating.

Olef v3.0.1

Choose a tag to compare

@andriyo andriyo released this 30 Oct 19:23
  • olef init replaces the old ShadowDroid plugin: after it installs
    the Olef plugin for Claude Code or Codex, it removes the shadowdroid
    plugin from v2 (and, in Claude Code, its shadowdroid marketplace), with
    the same consent as the install: --plugins, or a yes in a terminal. An
    unattended init only reports it, with the command that removes it. If
    the Olef install fails, the old plugin stays.
  • Old ShadowDroid skills are set aside: a skill v2 installed as
    …/skills/shadowdroid/SKILL.md (Claude Code, Codex, Cursor, Gemini,
    Antigravity) sat next to the Olef skill with outdated commands. init,
    skill --sync and connect now rename an unedited one to
    SKILL.md.retired and install the Olef skill in its place, unless the
    agent's Olef plugin already provides it. A copy you edited is left alone
    and reported, so you can move your changes over.
  • Olef Cloud on olef.dev: a new olef cloud login signs in through
    api.olef.dev and the approval page is app.olef.dev/activate. If you're
    already signed in, nothing changes: your login keeps working against
    api.shadowdroid.dev, which is the same service. The Codex plugin's
    cloud MCP server is now https://mcp.olef.dev/mcp, so Codex asks you to
    sign in to it once more.
  • Tests recorded with v2 run unchanged: a 2.2 recording exports
    SHADOWDROID_SESSION_FILE and SHADOWDROID_STEP itself, and 3.0.0
    ignored them, so its first step failed with device_reserved. Each
    SHADOWDROID_* variable is now read when its OLEF_* name isn't set (the
    shadowdroid command prefers the old name, as v2 did). olef doctor still
    lists them so you can rename them.
  • A folder linked to a workspace that moved to the cloud is refused:
    olef cloud start and the commands that start a session answer
    cloud_workspace_moved instead of starting a session on the cloud copy.
  • Leased lab TVs in the viewer: the menu says "Release this TV", and
    Release, Extend and Keep work from a Cloud viewer of a lab device. When a
    lease ends, the viewer stops showing its remaining time.
  • A remote command's error output is complete: in a cloud-linked
    project, the last lines a remote command wrote to stderr could go missing
    when it failed; they're now always printed before the exit code is.
  • Native watchpoints on x86_64 emulators: LLDB can report a write
    watchpoint's stop without its reason there, so debug status showed a
    pause. When the watched value changed, the stop is now reported as that
    watchpoint's, with a note saying so.
  • The lab service survives a Homebrew upgrade: olef lab service install used to point the service at the CLI's versioned Homebrew
    folder, which the next upgrade deletes. It now copies the CLI into
    ~/.olef/lab/cli/<version>/ and runs that copy.

Update with olef update, run the command it prints, then olef init --plugins to replace the old plugin. On a lab host, run olef lab service install with the new CLI, then olef lab service stop and olef lab service start.

Install

macOS and Linux: brew install olef-dev/tap/olef, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/olef-dev/olef/releases/download/v3.0.1/olef-installer.sh | sh

Windows: scoop bucket add olef https://github.com/olef-dev/scoop-bucket and scoop install olef, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/olef-dev/olef/releases/download/v3.0.1/olef-installer.ps1 | iex"

Already installed? olef update prints the command for your install. See updating.

Olef v3.0.0

Choose a tag to compare

@andriyo andriyo released this 29 Oct 23:02

ShadowDroid is now Olef. Same CLI, device service, runtime, plugins and
Cloud, under a new name, a new home at olef.dev and a
new look. Updating moves you across; scripts that call shadowdroid keep
working.

What changes

  • The command is olef. Every install also puts a shadowdroid command
    next to it that runs olef (a link on macOS and Linux, a .cmd shim on
    Windows), so scripts, CI and recorded tests keep working.
  • Your settings move once. The first olef run moves ~/.shadowdroid to
    ~/.olef (leaving a ~/.shadowdroid link on macOS and Linux) and a
    project's .shadowdroid/ folder to .olef/. The proxy CA moves as it is,
    so devices that trust it keep trusting it. A ~/.olef that already exists
    is kept as ~/.olef.before-move-<time>.
  • Environment variables are OLEF_*. SHADOWDROID_* names aren't read
    any more: rename them (SHADOWDROID_DEVICE → OLEF_DEVICE, and so on).
    olef doctor lists any still set, with their new names.
  • The device service is dev.olef.server. The first olef connect
    removes the old io.github.andriyo.shadowdroid service from each device and
    installs the new one.
  • The agent plugins are olef. Run olef init to install them, then
    remove the old shadowdroid plugin from Claude Code (/plugin uninstall shadowdroid@shadowdroid) or Codex. The MCP tools are now
    mcp__plugin_olef_olef__*, so update any permission rules that named the
    old ones.
  • The repositories moved to the olef-dev
    organization. Old URLs redirect; new installs use
    brew install olef-dev/tap/olef or the installers below.
  • New CA name: a CA created from now on is "Olef MITM CA". An existing
    one is kept as it is.

What keeps working

  • Recorded tests in tests/shadowdroid/ and steps that start with
    shadowdroid, a project's .shadowdroidignore, and --billing shadowdroid.
  • Olef Cloud: your account, workspaces, sign-in and the existing
    app.shadowdroid.dev, api.shadowdroid.dev and mcp.shadowdroid.dev
    addresses. The same services now also answer on app.olef.dev,
    api.olef.dev and mcp.olef.dev.

Also new

  • A new look: the Olef mark and palette in the device viewer, the Cloud
    web app and the plugin icons.
  • Sign in to Olef Cloud with an email link (live already): no password,
    the same invite rules as GitHub and Google sign-in.

Update

  • Homebrew: brew update && brew upgrade olef-dev/tap/olef moves you to
    the olef formula. Name it in full: Homebrew 7 refuses a bare
    brew upgrade for a tap you haven't trusted.
  • macOS and Linux installer:
    curl --proto '=https' --tlsv1.2 -LsSf https://github.com/olef-dev/olef/releases/latest/download/olef-installer.sh | sh
  • Scoop: scoop update shadowdroid keeps working; to switch names,
    scoop uninstall shadowdroid; scoop install olef.
  • Windows installer:
    powershell -ExecutionPolicy Bypass -c "irm https://github.com/olef-dev/olef/releases/latest/download/olef-installer.ps1 | iex"

Then run olef init. More in
Updating Olef.

On a lab host, the service has a new name too. Remove the old one, then
install the new one with olef lab service install and olef lab service start:

  • macOS: sudo sh -c 'launchctl bootout system/dev.shadowdroid.lab; rm -f /Library/LaunchDaemons/dev.shadowdroid.lab.plist'
  • Linux: sudo sh -c 'systemctl disable --now shadowdroid-lab; rm -f /etc/systemd/system/shadowdroid-lab.service'

Install

macOS and Linux: brew install olef-dev/tap/olef, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/olef-dev/olef/releases/download/v3.0.0/olef-installer.sh | sh

Windows: scoop bucket add olef https://github.com/olef-dev/scoop-bucket and scoop install olef, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/olef-dev/olef/releases/download/v3.0.0/olef-installer.ps1 | iex"

Already installed? olef update prints the command for your install. See updating.

ShadowDroid v2.7.4

Choose a tag to compare

@andriyo andriyo released this 27 Oct 13:18
  • A lab phone on wireless debugging stays online when its name changes:
    the lab agent knows each enrolled device by its hardware serial, not the
    exact adb serial it was enrolled under. A phone whose wireless-debugging
    name became adb-<serial>-<id> (2)._adb-tls-connect._tcp after a restart
    (or got a new id after wireless debugging was reset) was reported offline
    although it was connected; the agent now finds it under its new name, and
    reconnects it through the wireless-debugging services it sees on the
    network. lab add records the hardware serial; devices enrolled before
    work too. lab devices shows each enrolled device under the name it has
    now.
  • Your own lab works without real-phones access (a Cloud change, live
    already): shadowdroid lab register and reserving your own lab's devices
    no longer need the real-phones preview. It's needed only for phones
    ShadowDroid bills.

Update with shadowdroid update, run the command it prints, then
shadowdroid init. On a lab host, run shadowdroid lab service install
with the new CLI (it points the service at it), then lab service stop and
lab service start.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.4/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.4/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.

ShadowDroid v2.7.3

Choose a tag to compare

@andriyo andriyo released this 27 Oct 05:34
  • The viewer no longer shows a nonsense idle timeout for lab devices:
    a lab lease the Cloud manages never idle-releases from the viewer, so the
    lease tooltip no longer says "released after 307445734561826 min without
    use".
  • The viewer names the leased device by its kind: the menu says
    "Release this TV" (or tablet, or device) for a lab TV or tablet, and the
    idle warning says what it's counting for.

Update with shadowdroid update, run the command it prints, then
shadowdroid init.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.3/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.3/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.

ShadowDroid v2.7.2

Choose a tag to compare

@andriyo andriyo released this 27 Oct 04:14

The device viewer (shadowdroid pane, the agent apps' viewer and
view.shadowdroid.dev) is easier to use on tablets, phones and narrow panes:

  • Bigger targets: toolbar and zoom buttons are 36 px with a mouse and
    44 px on a touch screen.
  • Zoom moved to the status bar, so it never covers the device.
  • One toolbar row in a narrow pane: below 560 px, Recents, Rotate,
    Annotate, Record steps and the side panel move into the settings menu.
  • "Live · idle" on a still screen instead of "0 fps"; the frame rate
    shows while the screen changes, and the stream's size is in the status
    tooltip.
  • Sharper on wide panes: the Auto video quality picks Sharp when the
    pane is wide, so small text isn't soft.
  • Primary buttons use the ShadowDroid red ("Let Claude use it", Reserve,
    Keep) in light and dark; the rest of the viewer stays neutral.

Update with shadowdroid update, run the command it prints, then
shadowdroid init.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.2/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.2/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.

ShadowDroid v2.7.1

Choose a tag to compare

@andriyo andriyo released this 25 Oct 06:40
  • Labs no longer quarantine a Samsung phone for a setting nobody
    touched:
    after each lease a lab checks that the device is back the way
    it was. Samsung's state for continuing apps on other Galaxy devices
    changes on its own whenever such devices come and go nearby, and the
    check took it for something the lease had left behind, so the phone went
    out of service. Labs now ignore those settings.

To update a lab, install the new CLI where the lab agent runs it, run
shadowdroid lab service install with it, then shadowdroid lab service stop and shadowdroid lab service start.

Update with shadowdroid update, run the command it prints, then
shadowdroid init.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.1/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.1/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.

ShadowDroid v2.7.0

Choose a tag to compare

@andriyo andriyo released this 24 Oct 22:15
  • Pair on a Cloud session: when a teammate shares their ShadowDroid
    Cloud workspace with you, its viewer shows who is here and who is
    driving. One person drives at a time; Take control hands it over and
    Hand back returns it. Watchers see the device without driving it.
  • shadowdroid cloud share: invite a teammate in your team org to pair
    on (or, with --watch, watch) the linked workspace, list who it's shared
    with, and take access away (cloud share add|rm).
  • shadowdroid cloud project: projects are a team org's shared
    definition of one app: its GitHub repository, shared environment and
    shared secrets (for every workspace, or for CI or agents only), and who
    works on it. cloud project list|show|create|grant, secret-set,
    secret-rm, and cloud project workspace <project> to make your own
    workspace from one, with no GitHub access of your own needed.
  • Admins look inside only when the org allows it: in a team org, an
    owner decides whether admins may watch (or control) a member's workspace;
    each look needs a reason, lasts up to an hour, and the member sees who and
    why. This ships in ShadowDroid Cloud.

Update with shadowdroid update, run the command it prints, then
shadowdroid init.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.0/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.7.0/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.

ShadowDroid v2.6.3

Choose a tag to compare

@andriyo andriyo released this 24 Oct 21:26
  • No more smeared video after a late frame: when part of a frame
    arrived after the viewer had already sent it on, the Android app's
    decoder showed smears until the next key frame. The viewer now restarts
    the stream at once with a fresh key frame.
  • Lab devices show their own name in the viewer's title, instead of
    the device host's internal adb address, and the viewer stops cleanly
    when the lease ends.
  • Labs come back within seconds after a device host restart: a lab
    agent now says that ShadowDroid's device host isn't reachable (not that
    a session may be starting) and retries every 5 seconds instead of
    backing off to 30.
  • ShadowDroid Cloud: streamed output no longer lags in workspaces with
    secrets.
    The secret masking held back the last bytes of every output
    chunk until more output arrived, so prompts and live output could stall.
    It now holds back only bytes that could start a secret. This ships in
    the Cloud workers, not the CLI.

Update with shadowdroid update, run the command it prints, then
shadowdroid init.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.6.3/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.6.3/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.

ShadowDroid v2.6.2

Choose a tag to compare

@andriyo andriyo released this 24 Oct 10:20
  • Steady live video from devices that send it in pieces: older devices
    (Android 9, Fire TV sticks on Fire OS 7) without adb's delayed_ack send
    each frame in several packets, each waiting for a reply, so over Wi-Fi or
    a device lab the viewer could get half frames and keep restarting
    ("Decoder error"). The viewer now learns how long a frame can take to
    arrive from each device and waits for the rest.

Update with shadowdroid update, run the command it prints, then
shadowdroid init.

Install

macOS and Linux: brew install shadowdroid-dev/tap/shadowdroid, or

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.6.2/shadowdroid-installer.sh | sh

Windows: scoop bucket add shadowdroid https://github.com/shadowdroid-dev/scoop-bucket and scoop install shadowdroid, or

powershell -ExecutionPolicy Bypass -c "irm https://github.com/shadowdroid-dev/shadowdroid/releases/download/v2.6.2/shadowdroid-installer.ps1 | iex"

Already installed? shadowdroid update prints the command for your install. See updating.