diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ae3fc6f2fb5..6b8cffbdf4a3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,7 +67,7 @@ Then run it with: ./packages/opencode/dist/opencode-/bin/opencode ``` -Replace `` with your platform (e.g., `darwin-arm64`, `linux-x64`). +Replace `` with your platform (e.g., `darwin-arm64`, `linux-x64`, `android-arm64`). - Core pieces: - `packages/opencode`: OpenCode core business logic & server. diff --git a/README.md b/README.md index 99b4b2c50ff9..1fc9482e12c8 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,18 @@ nix run nixpkgs#opencode # or github:anomalyco/opencode for latest dev > [!TIP] > Remove versions older than 0.1.x before installing. +#### Android/Termux + +OpenCode can be installed on Android ARM64 devices using Termux: + +```bash +# In Termux +curl -fsSL https://opencode.ai/install | bash +``` + +> [!NOTE] +> The Android build is based on the Linux ARM64 binary and may require proot-distro for full compatibility. Direct execution in Termux may have limitations due to Android's security model. For best results, consider using proot-distro with Alpine Linux. + ### Desktop App (BETA) OpenCode is also available as a desktop application. Download directly from the [releases page](https://github.com/anomalyco/opencode/releases) or [opencode.ai/download](https://opencode.ai/download). diff --git a/install b/install index b0716d532082..4bb5f361e8e0 100755 --- a/install +++ b/install @@ -78,9 +78,22 @@ if [ -n "$binary_path" ]; then else raw_os=$(uname -s) os=$(echo "$raw_os" | tr '[:upper:]' '[:lower:]') + + # Check if running on Android (e.g., Termux) + is_android=false + if [ -d /system/app ] && [ -d /system/priv-app ]; then + is_android=true + fi + case "$raw_os" in Darwin*) os="darwin" ;; - Linux*) os="linux" ;; + Linux*) + if [ "$is_android" = "true" ]; then + os="android" + else + os="linux" + fi + ;; MINGW*|MSYS*|CYGWIN*) os="windows" ;; esac @@ -101,16 +114,19 @@ else combo="$os-$arch" case "$combo" in - linux-x64|linux-arm64|darwin-x64|darwin-arm64|windows-x64) + linux-x64|linux-arm64|darwin-x64|darwin-arm64|windows-x64|android-arm64) ;; *) echo -e "${RED}Unsupported OS/Arch: $os/$arch${NC}" + if [ "$is_android" = "true" ] && [ "$arch" != "arm64" ]; then + echo -e "${MUTED}Note: OpenCode on Android/Termux currently only supports ARM64 architecture.${NC}" + fi exit 1 ;; esac archive_ext=".zip" - if [ "$os" = "linux" ]; then + if [ "$os" = "linux" ] || [ "$os" = "android" ]; then archive_ext=".tar.gz" fi @@ -158,17 +174,20 @@ else fi target="$os-$arch" - if [ "$needs_baseline" = "true" ]; then - target="$target-baseline" - fi - if [ "$is_musl" = "true" ]; then - target="$target-musl" + # Android doesn't need baseline or musl variants + if [ "$os" != "android" ]; then + if [ "$needs_baseline" = "true" ]; then + target="$target-baseline" + fi + if [ "$is_musl" = "true" ]; then + target="$target-musl" + fi fi filename="$APP-$target$archive_ext" - if [ "$os" = "linux" ]; then + if [ "$os" = "linux" ] || [ "$os" = "android" ]; then if ! command -v tar >/dev/null 2>&1; then echo -e "${RED}Error: 'tar' is required but not installed.${NC}" exit 1 @@ -334,7 +353,7 @@ download_and_install() { curl -# -L -o "$tmp_dir/$filename" "$url" fi - if [ "$os" = "linux" ]; then + if [ "$os" = "linux" ] || [ "$os" = "android" ]; then tar -xzf "$tmp_dir/$filename" -C "$tmp_dir" else unzip -q "$tmp_dir/$filename" -d "$tmp_dir" diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index ddb4769912d7..26e76cadd62d 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -60,11 +60,17 @@ const allTargets: { arch: "arm64" | "x64" abi?: "musl" avx2?: false + android?: boolean }[] = [ { os: "linux", arch: "arm64", }, + { + os: "linux", + arch: "arm64", + android: true, + }, { os: "linux", arch: "x64", @@ -146,7 +152,7 @@ for (const item of targets) { const name = [ pkg.name, // changing to win32 flags npm for some reason - item.os === "win32" ? "windows" : item.os, + item.os === "win32" ? "windows" : item.android ? "android" : item.os, item.arch, item.avx2 === false ? "baseline" : undefined, item.abi === undefined ? undefined : item.abi, @@ -163,6 +169,9 @@ for (const item of targets) { const bunfsRoot = item.os === "win32" ? "B:/~BUN/root/" : "/$bunfs/root/" const workerRelativePath = path.relative(dir, parserWorker).replaceAll("\\", "/") + // For Android, use the linux-arm64 target as Bun doesn't have native Android support + const buildTarget = item.android ? "bun-linux-arm64" : name.replace(pkg.name, "bun") + await Bun.build({ conditions: ["browser"], tsconfig: "./tsconfig.json", @@ -174,7 +183,7 @@ for (const item of targets) { //@ts-ignore (bun types aren't up to date) autoloadTsconfig: true, autoloadPackageJson: true, - target: name.replace(pkg.name, "bun") as any, + target: buildTarget as any, outfile: `dist/${name}/bin/opencode`, execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"], windows: {},