Skip to content

feat(cli): add native Android support - #60903

Draft
sigsegv0x0b wants to merge 1 commit into
anomalyco:devfrom
sigsegv0x0b:android-termux-support
Draft

sigsegv0x0b wants to merge 1 commit into
anomalyco:devfrom
sigsegv0x0b:android-termux-support

Conversation

@sigsegv0x0b

Copy link
Copy Markdown

Issue for this PR

Related to #47612

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds a native android-arm64 build target so @opencode/cli installs and runs on Termux/Android without glibc-runner.

  • Add { os: "android", arch: "arm64" } and map it to Bun's bun-linux-arm64-android, including the bun-linux-aarch64-android release asset name. Publish android in the distribution package os list so npm stops rejecting the install.
  • Build opencode-pty for aarch64-linux-android and publish @opencode/pty-android-arm64. The Ghostty build pins API 28 (so Zig does not consult getprop on Termux) and the daemon uses TMPDIR for its socket because Android has no writable /tmp.
  • Embed the Android fff native library through the existing @ff-labs/fff-bun patch so file search works in the compiled binary.
  • Add an Android job to the process-daemon release workflow with the NDK, a Zig libc spec, and the API 28 linker. On-device tests are skipped for that target.

Dependencies: this is a draft until two releases exist:

  1. anomalyco/opentui needs an @opentui/core-android-arm64 prebuild; the published @opentui/core@0.8.0 rejects android-arm64 at runtime. The opencode side alone gets npm install working but the TUI would still fail.
  2. @opencode/pty@0.4.0 is already published without the android optional dependency, so the CLI build needs a new @opencode/pty release (and a pin bump here) before it can resolve @opencode/pty-android-arm64.

I can mark this ready and bump the pins once both are released.

How did you verify your code works?

On Termux (Android aarch64, SDK 37), using a locally built libopentui.so and opencode-pty for the same commit:

  • opencode --version and --help run natively (bionic ELF, /system/bin/linker64).
  • opencode --standalone renders the TUI (logo, prompt, status bar) with the native render library; no Unsupported OpenTUI Node asset target error.
  • opencode-pty play spawns Termux bash, captures output, and prints parsed libghostty screen state.
  • bun run typecheck in packages/cli, cargo fmt --check, and Prettier pass.

The Android release job itself has not run on GitHub Actions yet; it is new in this PR.

Visual

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="72" viewBox="0 0 240 72" fill="none">
  <style>
    .cursor { animation: blink 1.1s steps(1) infinite; }
    .badge { animation: rise 2.6s ease-in-out infinite; transform-origin: 186px 36px; }
    .scan { animation: scan 2.6s linear infinite; }
    @keyframes blink { 0%, 49% { opacity: 1 } 50%, 100% { opacity: 0 } }
    @keyframes rise { 0% { opacity: 0; transform: translateX(-8px) scale(.92) } 30%, 100% { opacity: 1; transform: none } }
    @keyframes scan { 0% { transform: translateY(0) } 100% { transform: translateY(38px) } }
    @media (prefers-reduced-motion: reduce) { .cursor, .badge, .scan { animation: none } }
  </style>
  <rect x="1" y="1" width="238" height="70" rx="8" stroke="currentColor" stroke-opacity=".28"/>
  <path d="M18 25 L30 36 L18 47" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity=".9"/>
  <rect x="40" y="27" width="78" height="5" rx="2.5" fill="currentColor" opacity=".55"/>
  <rect x="40" y="38" width="44" height="5" rx="2.5" fill="currentColor" opacity=".26"/>
  <rect x="88" y="38" width="6" height="5" rx="1" class="cursor" fill="currentColor"/>
  <g class="badge">
    <rect x="148" y="25" width="76" height="22" rx="11" stroke="currentColor" stroke-opacity=".45" fill="currentColor" fill-opacity=".07"/>
    <circle cx="161" cy="36" r="4" fill="currentColor" opacity=".85"/>
    <rect x="171" y="33.5" width="43" height="5" rx="2.5" fill="currentColor" opacity=".7"/>
  </g>
  <rect class="scan" x="12" y="18" width="216" height="1" fill="currentColor" opacity=".16"/>
</svg>

Screenshots / recordings

No screenshot: the TUI was exercised over a headless Termux pty, so the output is terminal escape sequences rather than an image.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Build the CLI natively for Termux with Bun's android target instead of
requiring glibc-runner, and publish an @opencode/cli-android-arm64 package.

- Add the android-arm64 target and map it to bun-linux-arm64-android, with
  the matching bun-linux-aarch64-android release asset.
- Publish android in the distribution package os list and resolve
  @opencode/pty-android-arm64 from the CLI build.
- Build opencode-pty for aarch64-linux-android, pin the Zig API level to 28
  so the Ghostty build does not query getprop on Termux, and use TMPDIR for
  the service socket on Android because /tmp is not writable there.
- Embed the Android fff native library so file search works in compiled
  binaries.

The TUI additionally needs an @opentui/core-android-arm64 prebuild; that
change lives in anomalyco/opentui.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant