From 339f27677c1cf2ecaffb12795100d3168ec58e26 Mon Sep 17 00:00:00 2001 From: JOBIANS TECHIE <88005779+Jobians@users.noreply.github.com> Date: Tue, 6 Oct 2026 17:45:35 +0100 Subject: [PATCH 1/4] Map android platform to linux binaries in launcher --- publish/npm/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/publish/npm/index.js b/publish/npm/index.js index 2f0327de..34b1f9f3 100644 --- a/publish/npm/index.js +++ b/publish/npm/index.js @@ -22,6 +22,7 @@ switch (process.platform) { break; case "linux": + case "android": switch (process.arch) { case "arm64": packageName = "@mobilenext/mobilecli-linux-arm64"; From 8a338a9533a4d196be5fa1eeb12c4ad74d42e9ba Mon Sep 17 00:00:00 2001 From: JOBIANS TECHIE <88005779+Jobians@users.noreply.github.com> Date: Tue, 6 Oct 2026 17:52:43 +0100 Subject: [PATCH 2/4] Allow android in linux-arm64 package os field --- publish/npm-linux-arm64/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish/npm-linux-arm64/package.json b/publish/npm-linux-arm64/package.json index da715a55..3212d0e6 100644 --- a/publish/npm-linux-arm64/package.json +++ b/publish/npm-linux-arm64/package.json @@ -8,6 +8,6 @@ "url": "git+https://github.com/mobile-next/mobilecli.git" }, "license": "FSL-1.1-ALv2", - "os": ["linux"], + "os": ["linux", "android"], "cpu": ["arm64"] } From f16b36aed7222769da79101bc950f965824d1373 Mon Sep 17 00:00:00 2001 From: JOBIANS TECHIE <88005779+Jobians@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:46:25 +0100 Subject: [PATCH 3/4] Allow android in linux-amd64 package os field --- publish/npm-linux-amd64/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish/npm-linux-amd64/package.json b/publish/npm-linux-amd64/package.json index 7b0570e4..edbcc504 100644 --- a/publish/npm-linux-amd64/package.json +++ b/publish/npm-linux-amd64/package.json @@ -8,6 +8,6 @@ "url": "git+https://github.com/mobile-next/mobilecli.git" }, "license": "FSL-1.1-ALv2", - "os": ["linux"], + "os": ["linux", "android"], "cpu": ["x64"] } From 6dc564e24dc797402fba0470b5d858f7a0766edb Mon Sep 17 00:00:00 2001 From: JOBIANS TECHIE <88005779+Jobians@users.noreply.github.com> Date: Tue, 6 Oct 2026 19:22:16 +0100 Subject: [PATCH 4/4] Use file credential storage on Android/Termux instead of crashing in keyring --- cli/credentials.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cli/credentials.go b/cli/credentials.go index 37a38937..289e940f 100644 --- a/cli/credentials.go +++ b/cli/credentials.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" "sync" "time" @@ -22,6 +23,15 @@ import ( // insecureStorage is bound to the global --insecure-storage flag. var insecureStorage bool +// useFileStorage reports whether the token lives in the credentials file rather +// than the OS keyring. That is the case when --insecure-storage is set, and +// always on Android (Termux), which has no keyring and where probing for one +// kills the process: the seccomp filter rejects the faccessat2 syscall that +// exec.LookPath makes, so the keyring backend crashes with SIGSYS. +func useFileStorage() bool { + return insecureStorage || runtime.GOOS == "android" || os.Getenv("TERMUX_VERSION") != "" +} + // credentialsFilePath returns the path to the plaintext token file used when // --insecure-storage is set: $XDG_CONFIG_HOME/mobilecli/credentials, falling // back to ~/.config/mobilecli/credentials. We deliberately use ~/.config on @@ -42,7 +52,7 @@ func credentialsFilePath() (string, error) { // storeToken saves the token in the keyring, or in the credentials file when // --insecure-storage is set. func storeToken(token string) error { - if insecureStorage { + if useFileStorage() { return storeTokenInFile(token) } if err := keyring.Set(keyringService, keyringUser, token); err != nil { @@ -74,7 +84,7 @@ func loadToken() (string, error) { return token, nil } - if insecureStorage { + if useFileStorage() { return loadTokenFromFile() } @@ -155,7 +165,7 @@ func loadTokenFromFile() (string, error) { // deleteToken removes the stored token. It returns keyring.ErrNotFound when no // token was stored, so logout can report "not logged in". func deleteToken() error { - if insecureStorage { + if useFileStorage() { path, err := credentialsFilePath() if err != nil { return err