npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@relictombs/opencode-android

v0.2.0

Published

OpenCode TUI plugin for presenting, controlling, and running Expo apps on one Android Emulator

Downloads

96

Readme

Relictombs Android

Run, present, inspect, and control Expo apps on one Android Emulator from the OpenCode V2 TUI. OpenCode starts without booting Android; an explicit human or agent action creates one owned headless emulator, and the sidebar attaches to that same runtime. Human input, screenshots, accessibility snapshots, agent actions, and Expo all target the same device.

Requirements

  • macOS on Apple Silicon for the provided Android setup target.
  • Node.js 24 or newer with npm. Bun is only needed when contributing from a source checkout.
  • OpenCode V2 0.0.0-next-16650 or a newer compatible @next build, launched as opencode2.
  • A Kitty-graphics terminal such as Ghostty on the machine running OpenCode. Android may run locally or on an Relictombs host reached through WSS, SSH loopback forwarding, or a VPN-side proxy that presents loopback endpoints.
  • The Android SDK, Emulator, platform tools, and an existing AVD on whichever machine owns the Emulator. The client does not need them when Android runs on the server.
  • Homebrew and Homebrew OpenJDK for the provided macOS setup target.
  • For local Expo automation, an app whose project has expo installed locally. expo_start never falls back to npx or downloads a CLI; remote mode does not register the Expo tools.

Run the interactive wizard for the complete setup:

npx --yes @relictombs/[email protected]

Choose Android or both surfaces, then choose local or remote execution. For remote use, the wizard accepts a direct SSH destination or a Tailscale machine name or address. It checks or prepares the Android host and verifies FFmpeg and connectivity. Local and existing-host flows can print generated JSON instead of writing it; setup-owned SSH sessions apply the global or project configuration because their token and tunnel are temporary.

Advanced manual configuration

Install the package and add the TUI plugin to ~/.config/opencode/cli.json (or $OPENCODE_CONFIG_DIR/cli.json):

{
  "plugins": ["@relictombs/[email protected]"]
}

This is the local setup: omitting remoteHost keeps Android stopped until an explicit human or agent action starts the configured AVD on the same machine as OpenCode. It enables the Android/Expo MCP tools plus /android-start and /android-stop, and needs no Relictombs host, FFmpeg, or SSH tunnel.

For local development, pack and install the package into OpenCode's package cache, then use a normal package spec in the config. Do not point OpenCode at dist/tui.js: a raw workspace file can resolve a second copy of OpenTUI/Solid and fail with No renderer found when the sidebar mounts. The packed artifact keeps OpenCode's renderer packages as optional peers and bundles the Android implementation around the host's exact @opentui/core singleton.

Do not configure opentui-device-mcp separately. This plugin registers its own combined relictombs-android MCP server for the configured AVD and current OpenCode project directory.

The package includes skills/relictombs-android/SKILL.md. Copy it to ~/.config/opencode/skills/relictombs-android/SKILL.md when installing manually, or add a workspace-specific skill under .opencode/skills/ when the project needs an exact demonstration sequence.

Options are passed through the OpenCode plugin configuration:

| Option | Default | Purpose | | ----------------- | ------------------------ | --------------------------------------------- | | avdName | OpenTUI_Pixel_8_API_36 | Local Android Virtual Device to launch | | expoPort | 8081 | Local Metro port owned by this MCP process | | framePixelRatio | 2 | Terminal capture density | | maxFps | 30 | Maximum terminal presentation rate | | nodeCommand | node | Node executable for the local MCP entry | | remoteHost | unset | Authenticated server control/media connection |

Advanced manual remote configuration

The wizard is the supported start-to-finish remote path. The following JSON shape is only for operators who supervise the server and authenticated loopback tunnel themselves. mediaEndpoint rewrites the server's advertised media origin while preserving its source identity and frame-rate query.

{
  "plugins": [
    {
      "package": "@relictombs/[email protected]",
      "options": {
        "remoteHost": {
          "endpoint": "ws://127.0.0.1:43100/control",
          "mediaEndpoint": "ws://127.0.0.1:43101",
          "token": "<copy the 64-character token printed by the server>"
        }
      }
    }
  ]
}

Plain ws: is rejected for non-loopback names. The stock host CLI serves loopback ws: only, so use SSH forwarding or a VPN-side port-forward/proxy that presents both endpoints on the client loopback; VPN reachability alone is insufficient. A directly reachable wss: deployment requires a trusted TLS edge or custom host composition; it must forward WebSocket upgrades and the Authorization header, and the client must trust its certificate. Raw RGBA and server paths never cross this connection: the server negotiates ALV2/H.264 with an ALV1/NUT fallback, and the client decodes it into owned memory before direct Kitty presentation.

Remote mode is intentionally presentation and human-input only in this release. The Relictombs host eagerly owns the configured Emulator, so /android-start and /android-stop are not registered. The plugin also does not register its local relictombs-android stdio MCP server: that server owns local ADB, Expo, and a local state file, none of which can truthfully control the server. Run agent/Expo automation on the server separately until those bounded operations are added to the authenticated host protocol.

Agent workflow

  1. Create or edit an Expo app with ordinary OpenCode workspace tools. The plugin deliberately does not expose an arbitrary file-writing or shell MCP tool.
  2. Show OpenCode's sidebar with its built-in Toggle sidebar command (<leader>b). Click the Default · Android selector or run /android to switch between OpenCode's normal sidebar and the full-height device view.
  3. In local mode, call android_status, then android_start when stopped. A human can instead click Start Android, choose Start Android Emulator from the command palette, or run /android-start. /android-stop releases it.
  4. Call expo_start with the app directory relative to the OpenCode project, for example { "project": "apps/demo" }. The tool resolves that app's installed expo/bin/cli, starts expo start --android, and pins Expo/ADB to the plugin-owned emulator. expo_start also starts Android when needed.
  5. Use snapshot and tap_node for semantic interaction, screenshot for visual verification, and the bounded touch, swipe, text, key, and installed-app tools when needed.
  6. Call expo_status for bounded recent Metro logs or expo_stop to stop the owned server.

The MCP tools are:

  • Lifecycle: android_status, android_start, android_stop.
  • Android: status, snapshot, screenshot, tap, tap_node, swipe, type_text, press, launch_app.
  • Expo: expo_status, expo_start, expo_stop.

There is no arbitrary ADB shell escape hatch. Expo projects are canonicalized under the current OpenCode project, and only a project-local Expo CLI is executed. Switching back to the default sidebar releases only its Presentation; the emulator remains ready for MCP and a later remount. Deactivating the plugin removes its sidebar controls, unregisters MCP, and stops the emulator. MCP disconnection stops any Expo process owned by that MCP instance. Terminal touch uses the authenticated Emulator controller; typing and navigation use bounded fixed-argument input commands against the plugin-owned emulator's exact ADB serial.

In remote mode, deactivation closes the authenticated control/media session and leaves the server responsible for the Emulator lifetime.

Exact setup, plugin, and host versions remain a coordinated release set; current peers negotiate ALV2 while older peers retain the ALV1/NUT compatibility path. The npx setup and host commands are available in the coordinated 0.2.0 release.

Host composition API

Custom server launchers can import @relictombs/opencode-android/host-mcp and call acquireAndroidHostMcp(...) after the host has started its one emulator. The adapter attaches automation to the supplied emulator serial, owns Expo for the supplied absolute server project root and port, and exposes the combined Android and Expo tools on an authenticated loopback Streamable HTTP endpoint. It never launches a second AVD, and all resources remain scoped to the caller's Effect scope.

Development

bun run test
bun run typecheck
bun run build
bun run check

The OpenCode V2 TUI plugin API is beta. Upgrade OpenCode and this plugin together when that API changes.