Bash scripting toolkit. Main deliverable is install.sh. No app runtime here — package.json is lint-only infrastructure.
pnpm install # Install linter deps (pnpm@10.32.1 enforced via packageManager field)
pnpm run lint:all # Full lint gate: ESLint → Stylelint → Markdownlint → shellcheck (read-only, does NOT --fix)
python3 scripts/self_heal.py # Strips unused `catch (err)` params from JS/MJS only- Lint config:
eslint.config.mjs(flat/v10, Node/browser/jest globals),.stylelintrc.json(Tailwind-aware),.markdownlint.json(line length & inline HTML allowed),.shellcheckrc(bash linting). - CI (
lint.yml) runs on Node 22 and blocks PRs tomain/master.
- Pre-commit (
npx lint-staged) auto-fixes staged*.{js,mjs},*.css, and*.md. - Run
pnpm run lint:alllocally before pushing; it is the PR gate. - Do not assume
lint:allauto-fixes — it reports only.
- Never use native update commands (
openclaw update, etc.) — they overwrite Android patches. - Safe update path: re-run
install.sh, choose [R] Repair (2-second patch-only) or [U] Update (latest verified version). - UI Engine: v1.13.0+ uses
gum(charm.sh) for color-rich, touch-friendly menus with visual separators; falls back towhiptailif unavailable.ensure_depsauto-installsgum. - Uses
$PREFIXdynamically; never hardcode/data/data/com.termux/files/usr. - Memory guard: Node.js heap limit is set to
min(2048, max(512, RAM * 0.75))via--max-old-space-size. - PM2 is killed during updates to prevent OOM on low-RAM devices.
- Zero-latency navigation: v1.13.0+ caches Bash variables for
get_configandpnpm_root_g, and eliminates redundant Node.js /jqspawns during menu rendering. - Koffi kernel patch:
renameat2→renameto avoid kernel crashes. - Gemini CLI patch:
fs.promises.rename→copyFile + unlinkto avoid AndroidENOENT.
install.sh: Single source of truth for toolkit logic and version (v1.15.7).package.jsonversion (1.0.0) is stale — ignore it.scripts/self_heal.py: Lightweight Python refactor; only strips unused catch variables.package.json: Dev-only. Defines lint scripts,lint-staged, and Husky prepare hook.
The [U] Update path for Hermes was rewritten to work around upstream bugs:
-
Upstream
hermes updateusesuvinternally, which is broken on Termux:- Downloads a glibc-linked
uvbinary → fails on bionic libc - Falls back to
pip install uv→ no aarch64 wheel → compiles 100K+ lines of Rust → OOM uvthen rejects Android-built wheels as "not compatible with Android aarch64"- PR #39138 fixed extras group selection (
termux-allvsall) but explicitly left the managed-uv bootstrap unfixed ("out of scope")
- Downloads a glibc-linked
-
Our fix — the toolkit now:
- Skips
hermes updateentirely on Termux - Runs
git pull origin mainmanually - Calls
_hermes_ensure_termux_deps()which usespip(notuv) - Cleans stale
gateway.lock/gateway.pidafterpkill -9 - Force-reinstalls editable metadata (
--force-reinstall --no-deps -e .) to prevent stale.pthfiles - Smoke-tests imports (
import agent.prompt_builder) to verify the venv is coherent - Exports Rust build env (
ANDROID_API_LEVEL,CARGO_BUILD_JOBS=1, etc.) before any pip call
- Skips
-
Post-update cryptography check — Hermes v0.19.0's
setup.pypinscryptography==48.0.1, but the wheel cache may only have46.0.7. The toolkit does not force-upgrade cryptography to avoid a 30–90 minute source build. If you need the newer version, run manually:export ANDROID_API_LEVEL=$(getprop ro.build.version.sdk) ~/.hermes/hermes-agent/venv/bin/pip install cryptography==48.0.1 --no-build-isolation
| Tool | Method | Architecture Notes |
|---|---|---|
| OpenClaw | npm/pnpm global + koffi kernel patch + path redirection (/tmp, /bin/npm, etc.) |
All architectures |
| Pi Agent | RECOMMENDED — npm/pnpm global (@earendil-works/pi-coding-agent) + ~/.pi/agent/AGENTS.md context setup. Legacy @mariozechner/pi-coding-agent is detected and migrated. |
All architectures |
| Gemini CLI | npm/pnpm global + rename → copyFile+unlink patch |
All architectures |
| n8n | npm/pnpm global + watchdog cron + NODE_OPTIONS memory cap + optional GCP bridge |
All architectures |
| Ollama | pkg install ollama (Termux native) |
All architectures |
| Hermes | curl installer from hermes-agent.nousresearch.com + automatic wheel-cache (~/.hermes/wheel-cache) for fast reinstalls |
❌ Not supported on armv8l/armv7l (maturin/jiter incompatibility) |
| Nanobot | pip3 install nanobot-ai with --no-build-isolation |
❌ Not supported on armv8l/armv7l (maturin/jiter incompatibility) |
| Paperclip | Delegates to paperclip_manual_install.sh (clone + pnpm + prebuilt tarballs + PostgreSQL) |
All architectures (experimental, ~2GB RAM recommended) |
The toolkit supports installing a specific OpenClaw version (e.g. 2026.6.30) via the [V] Install Specific Version option in the OpenClaw menu. This is useful for:
- Pinning to a known-good release
- Testing older versions before upgrading
- Avoiding breaking changes in
@latest
A dedicated sub-menu [Z] Zulip Plugin under AGENTS → OpenClaw provides:
- [I] Install Latest —
openclaw plugins install clawhub:@niyazmft/openclaw-zulip - [U] Update to Latest —
openclaw plugins update zulip - [S] Install Specific Version —
openclaw plugins install clawhub:@niyazmft/openclaw-zulip@2026.7.0 - [X] Uninstall —
openclaw plugins uninstall zulip
⚠️ Node 24 Compatibility: The Zulip plugin may fail on Node 24 with anERR_REQUIRE_ESM_RACE_CONDITIONdue to a worker-thread module loader race in OpenClaw's plugin SDK. This affects both pnpm and npm installs. The only guaranteed fixes are: (1) wait for an OpenClaw upstream patch, or (2) skip Zulip by settingplugins.allowinopenclaw.json.
- Path Awareness: Automatically creates
~/.pi/agent/AGENTS.mdduring installation. - Environment: Injects
$HOME,$PREFIX, and Android-specific URL opening commands (termux-open-url) to prevent hallucination of standard Linux paths.
- Smart Repair: Detects existing installs and offers [R] Repair or [U] Update.
- Uninstallation: Modular menu (UNINSTALL → individual tool or WIPE ALL). Preserves system
pkgpackages. Deep vs Soft uninstalls available. - n8n bridge: Option 7 configures
autosshtunnel to a GCP VM. Monitor script is at~/n8n_server/scripts/n8n-monitor.sh.
-
Koffi:
sedinside compiled.node/.csources replacesrenameat2(...)withrename(...). -
Hermes/Nanobot armv8l/armv7l limitation:
jiter(a dependency ofanthropic, which both Hermes and Nanobot depend on) requires Rust compilation viamaturin. Thematurinbuild tool hard-codes an architecture check that rejectsarmv8landarmv7l. Additionally, pre-builtjiterwheels are compiled for glibc Linux (manylinux) and requirelibgcc_s.so.1andld-linux-armhf.so.3, which do not exist on Android's bionic libc. The only fix is upstream support from thejiter/maturinprojects. The toolkit now displays a graceful error message and skips installation on these architectures. -
Hermes wheel cache (v1.15.3+): After a successful install, compiled Python wheels (
cryptography,Pillow,pydantic-core,jiter,httptools,uvloop,watchfiles, etc.) are copied from pip's ephemeral cache to~/.hermes/wheel-cache. ThePIP_FIND_LINKSenvironment variable is set before any Hermes pip operation, so future reinstalls or updates on the same device reuse prebuilt wheels and skip the 30–90 minute Rust/C compilation phase. This cache is device-specific because compiled wheels link against the device's bionic libc, OpenSSL, and Python ABI. -
Path redirection:
grep -rlEfinds hardcoded/tmp/openclaw,/usr/bin/npm,/bin/nodereferences in installed JS, thensedreplaces them with$HOME/.openclaw/tmpand$TERMUX_BINpaths. -
Process termination: uses port-specific signatures (e.g.,
pkill -f "autossh.*5678"). -
Paperclip install: The inline Paperclip install in
install.shhas been replaced by delegation topaperclip_manual_install.sh. This standalone script handles: clone + pre-install patches (removeembedded-postgres, dropuiworkspace, delete stale lockfile), pnpm install with LMK-kill detection and retry,.binsymlink repair (tsc,tsx,esbuild), prebuiltcli-dist,dist/, andui-disttarball download from GitHub releases, PostgreSQL bootstrap with stale-process cleanup, randomized secret generation, and PM2 ecosystem file creation. The server and UI are not built on-device (Vite/tscrequires ~4–6 GB transient RSS and is unreliable). Paperclip installs enforce a per-device heap cap (--max-old-space-size=1024), single-concurrencypnpm install, and rely on pre-built assets to survive Android Low Memory Killer (LMK). PostgreSQL (pg_ctl) must be running before starting Paperclip. Note: On some devices,pm2may fail to start the server due to a Node.js module resolution bug (ERR_MODULE_NOT_FOUND). If this occurs, run the server manually:cd ~/paperclip && node server/dist/index.js.Known gotchas with pnpm in Termux: For Paperclip installation,
pnpm v10can fail to correctly link workspace dependencies, leading to build failures. It is strongly recommended to use pnpm v9.x (npm i -g pnpm@9.15.4) before attempting the Paperclip install. The installer manually repairs.binsymlinks fortsc,tsx, andesbuild, and ensuresnode_modules/.binis prepended to$PATH. Thesync; sleep 5; node -e "global.gc()"pattern that was previously used between build steps is removed entirely — it was causing LMK kills on loaded systems. Thesafe_execute()helper useseval(nobash -cfork) and appends directly to the main log.
ATTRIBUTIONS.md governs third-party redistribution rules. n8n is under the Sustainable Use License; commercial resale or embedding as a paid service requires an Enterprise license. Do not remove or alter ATTRIBUTIONS.md without legal review.