feat(system): add native Termux (Android) support#277
Conversation
- Add 'android' to supported operating systems in system detection. - Implement source compilation for 'engram' via 'go install' on Android to ensure compatibility with Bionic libc. - Fix path resolution by mapping '/tmp' to '$PREFIX/tmp' in TermuxResolver. - Update engram installation directory to use home-relative paths on Android. - Improve OS support error messages to include Android.
There was a problem hiding this comment.
Pull request overview
Adds native Android/Termux support across system detection, path resolution, installation, and upgrade flows so gentle-ai can run end-to-end in Termux without sudo and with Android PIE-compatible builds.
Changes:
- Add Android (
GOOS=android) as a supported OS and map it to a Termux platform profile (apt, supported). - Introduce a
PathResolverabstraction with a Termux-aware implementation for$PREFIX-based path mapping, and use it in install flows (e.g.,/tmp). - Add Termux-specific PATH persistence and Android PIE
go installupgrade behavior; expand unit tests and platform docs/specs.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
internal/system/detect.go |
Adds android support and introduces termux distro mapping. |
internal/system/detect_test.go |
Adds coverage for Android support and Termux distro detection. |
internal/system/guard.go |
Updates supported OS error message to include Android. |
internal/system/guard_test.go |
Updates assertions for the supported OS error message. |
internal/system/resolver.go |
New PathResolver abstraction and Termux $PREFIX resolver. |
internal/system/resolver_test.go |
Adds unit tests for default/Termux resolvers and resolver factory. |
internal/system/path.go |
Adds Termux PATH persistence (.bashrc/.zshrc) and test hook for GOOS. |
internal/system/path_test.go |
Adds Termux PATH persistence test coverage. |
internal/installcmd/resolver.go |
Suppresses sudo in Termux and uses resolver-mapped /tmp for GGA installs. |
internal/components/engram/download.go |
Adds Android install-via-go install path and Android install dir handling. |
internal/update/upgrade/strategy.go |
Injects Android PIE -ldflags for go install upgrades. |
internal/update/upgrade/strategy_test.go |
Adds PIE-flag verification test and adjusts command stubbing. |
docs/platforms.md |
Documents Android/Termux support and platform notes. |
openspec/specs/termux-support/spec.md |
Adds feature specification for Termux support requirements. |
openspec/changes/archive/2026-04-11-termux-compatibility/exploration.md |
SDD exploration artifact for Termux support. |
openspec/changes/archive/2026-04-11-termux-compatibility/proposal.md |
SDD proposal artifact for Termux support. |
openspec/changes/archive/2026-04-11-termux-compatibility/design.md |
SDD design artifact (PathResolver + persistence approach). |
openspec/changes/archive/2026-04-11-termux-compatibility/tasks.md |
SDD task breakdown and test plan for Termux support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix AddToUserPath docstring to reflect Termux PATH persistence - Handle os.ReadFile errors explicitly in persistPathTermux (ignore only NotExist) - Add HOME/fallback chain in engramInstallDir for Android edge case - Clarify engramAssetURL comment: android→linux mapping is URL-only, not runtime - Replace manual os.Setenv/defer with t.Setenv in resolver_test - Remove leftover TDD 'RED:' markers from committed tests - Fix strategy.go comment about PlatformProfile.OS on Termux - Correct docs/platforms.md: Android uses source compilation, not release binaries - Fix spec scenario: detection uses GOOS=android, not TERMUX_VERSION
Alan-TheGentleman
left a comment
There was a problem hiding this comment.
Review: feat(system): add native Termux (Android) support
Solid contribution — the architecture is clean (PathResolver interface, clean detection branching, PIE awareness), the test coverage is good, and the SDD artifacts provide excellent context. Two issues need attention before merge:
Must Fix
1. Inconsistent Termux detection between GOOS=android and GOOS=linux + ID=termux
The case "android" branch in resolvePlatformProfile correctly sets LinuxDistro=termux, but the PR also adds Termux detection in the "linux" branch via detectLinuxDistro. If someone runs on GOOS=linux with ID=termux in os-release (which Termux does report), the profile gets OS=linux + LinuxDistro=termux. But downstream checks in download.go (profile.OS == "android") and engramInstallDir won't trigger, creating a half-detected state.
Recommendation: Remove the Termux case from detectLinuxDistro and the LinuxDistroTermux entry in the linux distro switch — GOOS=android handles the full detection. Or, update all downstream checks to also match on LinuxDistro == "termux".
2. Dead code in engramAssetURL (android→linux mapping)
DownloadLatestBinary returns early for OS=android via installViaGo, so the goos == "android" mapping in engramAssetURL is unreachable. If defensive, add a comment. If not needed, remove it.
Suggestions
persistPathTermux: the\nprefix creates a blank first line when writing to a new RC fileinstallViaGo: usesos.Getenvdirectly instead of the testableosGetenvpattern used elsewhere- Sudo suppression in
ResolveDependencyInstall: the prepend logic is duplicated 3 times — consider a small helper echo ok→go versionin unrelated tests: worth mentioning in the PR description as an incidental fix
Great work on the PathResolver abstraction and the thorough test coverage. Looking forward to the updated version!
…eanup - Remove Termux from Linux distro detection (detectLinuxDistro, resolvePlatformProfile) GOOS=android is now the exclusive Termux detection path, eliminating the half-detected state where OS=linux + LinuxDistro=termux bypassed downstream Android-specific logic (installViaGo, engramInstallDir, PIE flags) - Remove dead android→linux mapping in engramAssetURL DownloadLatestBinary returns early via installViaGo for OS=android, making the goos rewrite unreachable - Fix leading blank line in persistPathTermux for new rc files exportCmd no longer starts with \n when writing to an empty file - Extract withSudo helper in ResolveDependencyInstall Replaces 3 duplicate if-sudo-prepend blocks with a single function - Update tests to match: distro matrix expects unknown for ID=termux, PIE test uses OS=android instead of OS=linux
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…uards - Set GORELEASER_OS='' for android (no release assets exist) - Add fatal guard in detect_install_method when OS=android and Go is missing - Add fatal guard when FORCE_METHOD=binary on Android (glibc incompatible) - Add safety net in install_binary for empty GORELEASER_OS (defense in depth) - Clean up contradictory priority comments into single coherent block
49c17f2 to
deff64b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Tighten TermuxResolver prefix matching to exact directory boundaries (/usr/ not /usrbin, /etc/ not /etcetera) with boundary-safe checks - Add shell-unsafe character guard in persistPathTermux to prevent rc file corruption from backticks, quotes, dollar signs, or newlines - Document engramInstallDir android branch as defensive (currently unused since installViaGo writes to GOBIN) - Include full args in goInstallUpgrade error message for easier debugging of PIE-related failures on Termux - Add engramInstallDir android test case and resolver boundary tests
|
Hey Alan, thanks for the thorough review — every point was valid. Here's what we addressed: Must Fix 1 — Inconsistent Termux detection (
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -216,8 +248,14 @@ install_go() { | |||
|
|
|||
| local go_package="github.com/${GITHUB_OWNER,,}/${GITHUB_REPO}/cmd/${BINARY_NAME}@latest" | |||
There was a problem hiding this comment.
go_package uses Bash 4+ lowercase expansion (${GITHUB_OWNER,,}), which fails on macOS’s default Bash 3.2 when users run --method go (or any environment using older Bash). Consider avoiding ,, (e.g., hardcode the lowercase owner, or lower-case via tr) so the installer works with the shebang’s bash on macOS.
| local go_package="github.com/${GITHUB_OWNER,,}/${GITHUB_REPO}/cmd/${BINARY_NAME}@latest" | |
| local github_owner_lower | |
| github_owner_lower="$(printf '%s' "$GITHUB_OWNER" | tr '[:upper:]' '[:lower:]')" | |
| local go_package="github.com/${github_owner_lower}/${GITHUB_REPO}/cmd/${BINARY_NAME}@latest" |
Snakeblack
left a comment
There was a problem hiding this comment.
Hice los cambios que me propusiste hace unos días, pero no se integro el feature a main
Alan-TheGentleman
left a comment
There was a problem hiding this comment.
Termux support is a real product expansion, not just a small platform patch.
Please move this through a design issue first or split it into smaller approved slices: platform detection, path resolution, install behavior, upgrade behavior, and docs. The current PR is too broad to review safely as one unit.
|
Heads-up: this PR is now showing a merge conflict against Could you rebase against current git fetch upstream main
git rebase upstream/main
# resolve any conflicts
git push --force-with-leaseOnce it's green again I can review for merge. Sorry for the drift — it's the cost of the cleanup velocity. Thanks for sticking with it. |
Integra main actual, preserva la detección Android como frontera canónica y documenta size:exception para el PR existente.
|
Hey Alan, thanks for the heads-up. The branch is updated against current Validated with:
Could you take another look when you have a chance? |
|
Thanks for the rebase and for addressing the earlier review points. I did another full pass. The core Termux direction looks good, but Important fix included in that branch: Android Validation run on the resolved branch:
All passed locally. The remaining policy issue is size: this is now ~1.1k changed lines, so we either need the maintainer-approved |
|
Hi Alan, thanks for preparing #765 and calling out the upgrade edge case. I updated #277 with your validation branch resolution, merged current Validation:
PR #277 is now |
Linked Issue
Closes #276
PR Type
type:feature- New feature (non-breaking change that adds functionality)Summary
Adds native Android/Termux support to
gentle-ai:GOOS=android.$PREFIXaware paths.mainhardening for checksum verification, Windows/Scoop docs, Go availability detection, and pinned GGA upgrade behavior.Changes
internal/system/detect.go, testsinternal/system/resolver.go,internal/system/path.go, testsinternal/installcmd/resolver.go, testsinternal/components/engram/download.go, testsgo installwith PIE flags on Android while preserving checksum verification for binary downloads.internal/update/upgrade/strategy.go, testsscripts/install.shgo install; blocks brew/binary methods on Android.docs/platforms.md,openspec/...Key Technical Decisions
GOOS=android, not through LinuxID=termuxorTERMUX_VERSIONin Go code. This avoids a half-detectedlinux + termuxstate.linux,darwin, andwindows. Android uses source compilation because Linux glibc binaries are incompatible with Android Bionic libc.-ldflags=-extldflags=-pie, required by Android executable loading rules.sudo.Review workload note
This PR exceeds the current 400-line review budget, but it predates the chained-PR policy and keeps one cohesive platform-support unit together: Android/Termux detection, prefix-aware paths, install behavior, upgrade behavior, tests, and docs.
Splitting it now would add review churn and risk losing the existing validation and context. Treating this as a maintainer-approved
size:exceptionis the lower-risk path for this already-open PR.To keep review focused, please review in this order:
internal/system/*platform detection and path resolutioninternal/installcmd/*sudo/rootless install behaviorinternal/components/engram/*Android source install with PIEinternal/update/upgrade/*upgrade strategyTest Plan
go test ./internal/system ./internal/installcmd ./internal/components/engram ./internal/update/upgradegit diff --checkmainafter conflict resolution.Contributor Checklist
Closes #276)type:*label (type:feature)Co-Authored-Bytrailers