@nemoobc/opencode-termux 1.18.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # @nemoobc/opencode-termux
2
+
3
+ **opencode CLI native di Termux/Android — TANPA proot.**
4
+
5
+ Paket ini menjembatani masalah: `opencode-ai` resmi tidak punya target `android`,
6
+ sehingga postinstall gagal di Termux. Solusinya: paket ini mengunduh binary
7
+ resmi `opencode-linux-arm64-musl` + **loader musl & libstdc++/libgcc dari Alpine**,
8
+ lalu menjalankannya lewat loader tersebut — murni userspace.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pkg update && pkg install nodejs-lts
14
+ npm i -g @nemoobc/opencode-termux
15
+ opencode-termux --version
16
+ ```
17
+
18
+ Alias biar terasa asli:
19
+
20
+ ```bash
21
+ ln -sf $PREFIX/bin/opencode-termux $PREFIX/bin/opencode
22
+ ```
23
+
24
+ Default model gratis: `opencode/x-preview-f-free` (Ox Alpha Free).
25
+
26
+ ## Cara kerja
27
+
28
+ ```
29
+ opencode-termux → ld-musl-aarch64.so.1 (dibundel) → opencode (musl, dibundel)
30
+ ↑ LD_LIBRARY_PATH: libstdc++/libgcc (dibundel)
31
+ ```
32
+
33
+ Tidak ada file sistem Android yang disentuh. Semua ada di `$PREFIX/lib/node_modules/@nemoobc/opencode-termux/vendor`.
34
+
35
+ ## Batasan
36
+
37
+ - Arsitektur: **arm64** (hampir semua HP sekarang). x86_64 bisa dipaksa utk uji: `OCX_ARCH=x64 OCX_FORCE=1 npm rebuild ...`
38
+ - Butuh koneksi internet saat `npm install` (mengunduh ~200 MB binary)
39
+ - Jika upstream opencode rilis versi baru, paket ini perlu bump versi mengikuti
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ const { spawnSync } = require("child_process")
3
+ const fs = require("fs")
4
+ const path = require("path")
5
+ const vendor = path.join(__dirname, "..", "vendor")
6
+ const loader = path.join(vendor, "ld-musl.so")
7
+ const bin = path.join(vendor, "opencode")
8
+ if (!fs.existsSync(loader) || !fs.existsSync(bin)) {
9
+ console.error("[opencode-termux] vendor belum terpasang. Jalankan ulang:")
10
+ console.error(" npm rebuild -g @nemoobc/opencode-termux")
11
+ process.exit(1)
12
+ }
13
+ const r = spawnSync(loader, [bin, ...process.argv.slice(2)], {
14
+ stdio: "inherit",
15
+ env: { ...process.env, LD_LIBRARY_PATH: vendor },
16
+ })
17
+ process.exit(r.status ?? 1)
package/install.mjs ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * postinstall untuk @nemoobc/opencode-termux
4
+ * Menyusun bundle native: loader musl + libgcc/libstdc++ + binary opencode
5
+ * Target: Termux (android/arm64). Override uji: OCX_ARCH=x64 OCX_FORCE=1
6
+ */
7
+ import fs from "fs"
8
+ import path from "path"
9
+ import { execFileSync } from "child_process"
10
+ import { fileURLToPath } from "url"
11
+
12
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
13
+ const V = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8")).version
14
+ const ARCH = process.env.OCX_ARCH || "arm64"
15
+ const FORCE = !!process.env.OCX_FORCE
16
+ const IS_ANDROID = process.platform === "android"
17
+ const IS_ARM64 = process.arch === "arm64"
18
+
19
+ if (!IS_ANDROID && !FORCE) {
20
+ console.log("[opencode-termux] Bukan Termux/Android — instalasi dilewati (pakai opencode-ai resmi).")
21
+ process.exit(0)
22
+ }
23
+ if (!FORCE && !IS_ARM64 && ARCH !== "x64") {
24
+ console.log(`[opencode-termux] arsitektur ${process.arch} belum didukung.`)
25
+ process.exit(0)
26
+ }
27
+ const A = ARCH === "x64" ? "x86_64" : "aarch64"
28
+
29
+ const dl = (url, dest) => {
30
+ console.log(`[opencode-termux] download ${url.split("/").pop()}`)
31
+ execFileSync("curl", ["-sL", "--retry", "3", "-o", dest, url], { stdio: "inherit" })
32
+ }
33
+ const untar = (tgz, dest, members = []) => {
34
+ fs.mkdirSync(dest, { recursive: true })
35
+ const args = ["xzf", tgz, "-C", dest, ...members]
36
+ try { execFileSync("tar", args) }
37
+ catch { execFileSync("tar", args.map(a => a.startsWith("./") ? a.slice(2) : a)) }
38
+ }
39
+
40
+ const work = path.join(__dirname, ".build")
41
+ fs.rmSync(work, { recursive: true, force: true })
42
+ fs.mkdirSync(work, { recursive: true })
43
+
44
+ // 1) binary opencode (musl) dari npm resmi
45
+ dl(`https://registry.npmjs.org/opencode-linux-${ARCH}-musl/-/opencode-linux-${ARCH}-musl-${V}.tgz`, `${work}/oc.tgz`)
46
+ untar(`${work}/oc.tgz`, `${work}/oc`)
47
+
48
+ // 2) loader+libc musl dari Alpine minirootfs
49
+ const AV = "v3.21", AL = "3.21.3"
50
+ dl(`https://dl-cdn.alpinelinux.org/alpine/${AV}/releases/${A}/alpine-minirootfs-${AL}-${A}.tar.gz`, `${work}/ap.tgz`)
51
+ untar(`${work}/ap.tgz`, `${work}/ap`, ["./lib"])
52
+
53
+ // 3) libgcc + libstdc++
54
+ const apkDir = `${work}/apk`; fs.mkdirSync(apkDir, { recursive: true })
55
+ for (const f of [`libgcc-14.2.0-r4.apk`, `libstdc%2B%2B-14.2.0-r4.apk`]) {
56
+ dl(`https://dl-cdn.alpinelinux.org/alpine/${AV}/main/${A}/${f}`, `${apkDir}/${f}`)
57
+ untar(`${apkDir}/${f}`, apkDir)
58
+ }
59
+
60
+ // 4) rakit vendor/
61
+ const vendor = path.join(__dirname, "vendor")
62
+ fs.rmSync(vendor, { recursive: true, force: true }); fs.mkdirSync(vendor)
63
+ const cp = (from, name) => fs.copyFileSync(from, path.join(vendor, name))
64
+ cp(`${work}/ap/lib/ld-musl-${A}.so.1`, "ld-musl.so")
65
+ cp(`${work}/oc/package/bin/opencode`, "opencode")
66
+ for (const f of fs.readdirSync(`${apkDir}/usr/lib`)) {
67
+ if (/^libstdc\+\+\.so|^libgcc_s\.so/.test(f)) cp(`${apkDir}/usr/lib/${f}`, f)
68
+ }
69
+ for (const f of fs.readdirSync(vendor)) fs.chmodSync(path.join(vendor, f), 0o755)
70
+
71
+ // 5) smoke test
72
+ console.log("[opencode-termux] smoke test…")
73
+ execFileSync(path.join(vendor, "ld-musl.so"),
74
+ [path.join(vendor, "opencode"), "--version"],
75
+ { stdio: "inherit", env: { ...process.env, LD_LIBRARY_PATH: vendor } })
76
+
77
+ fs.rmSync(work, { recursive: true, force: true })
78
+ console.log(`[opencode-termux] ✅ siap! Jalankan dengan: opencode-termux`)
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@nemoobc/opencode-termux",
3
+ "version": "1.18.21",
4
+ "description": "opencode CLI native untuk Termux/Android tanpa proot — membundel loader musl + binary opencode resmi (upstream opencode-ai)",
5
+ "bin": {
6
+ "opencode-termux": "./bin/opencode.js"
7
+ },
8
+ "scripts": {
9
+ "postinstall": "node install.mjs"
10
+ },
11
+ "keywords": ["opencode", "termux", "android", "cli", "ai"],
12
+ "license": "MIT",
13
+ "engines": { "node": ">=18" },
14
+ "files": ["bin", "install.mjs", "README.md"]
15
+ }