horus
Health Gecti
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 13 GitHub stars
Code Basarisiz
- spawnSync — Synchronous process spawning in __tests__/codexSandboxProbe.test.js
- fs module — File system access in __tests__/codexSandboxProbe.test.js
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Run Claude Code, Codex, and OpenCode on Android in a real Alpine Linux workspace. No root or Termux required.
Horus
Horus puts a real Alpine Linux ARM64 workspace on an Android phone and runs
coding agents in it: Claude Code, Codex, and OpenCode, or a plain
zsh shell. No root and no Termux are required. The app ships its own PRoot
runtime, a native PTY, and a native terminal renderer.
Plug the phone into a computer and you can also use it like a small cloud VM:
SSH in, forward ports, and sync files over USB with the optionalhorus CLI.
Website ·
Documentation ·
F-Droid ·
horus-cli on npm ·
Issues
Get Horus
- F-Droid: install from
f-droid.org/packages/com.scariflabs.horus
or search for Horus in the F-Droid app. - From source: see Build from source.
You need an ARM64 (arm64-v8a) phone running Android 7.0 (API 24) or newer.
New to Horus? Start with the
beginner's guide.
For F-Droid maintainers
Everything needed to find, build, and verify the app is listed here. The
build recipe ismetadata/com.scariflabs.horus.yml
in fdroiddata. New versions are picked up automatically from vX.Y.Z tags.
| Package ID | com.scariflabs.horus |
| License | MIT; bundled components in THIRD_PARTY_NOTICES.md |
| Source | https://github.com/scarif-labs/horus |
| Issue tracker | https://github.com/scarif-labs/horus/issues |
| Releases | Git tags vX.Y.Z; versionName and versionCode are in android/app/build.gradle |
| Store metadata | fastlane/metadata/android/en-US/ (description, screenshots, changelogs by versionCode) |
| ABI | arm64-v8a only |
| Min / target SDK | 24 / 36 |
Anti-features
- NonFreeNet. Horus downloads Alpine Linux, its packages, and the coding
agents from their upstream servers. Claude Code and Codex need accounts with
their providers. - NonFreeAdd. Horus offers to install Claude Code, which is proprietary.
Codex (Apache-2.0), OpenCode, and the plain shell are free software. Horus
never handles provider credentials; sign-in happens inside each CLI.
What is built from source
PRoot, talloc, and libandroid-shmem are compiled during the Gradle build
byscripts/native/build-proot-runtime.sh:native/proot: submodule, termux/proot v5.1.107.92, GPL-2.0-or-later;native/libandroid-shmem: submodule, termux/libandroid-shmem v0.7, BSD-3-Clause;native/talloc: talloc 2.4.3 core sources, vendored, LGPL-3.0-or-later.
Horus's own changes are in
native/patches/. The build
writes a runtime manifest with each binary's SHA-256, and the app refuses to
start PRoot if the installed binaries don't match it.The PTY is
android/app/src/main/cpp/terminal_pty.c
(JNI).Hermes bytecode compiler. Gradle uses
node_modules/hermes-compiler's
bundledhermescby default. Sethorus.hermesCommand(seeandroid/app/build.gradle) to use one built from
source instead. The F-Droid recipe buildshermescfrom the Hermes srclib
and deletes the prebuilt one.
No binaries are committed except android/gradle/wrapper/gradle-wrapper.jar.
Network, tracking, and permissions
No analytics, crash reporting, ads, or Google Play Services. The diagnostic
log stays on the device and records lifecycle metadata only, never terminal
input or output.Downloads at runtime: a pinned Alpine minirootfs from
dl-cdn.alpinelinux.org, checked against a SHA-256 inAlpineRootfsCatalog.kt.
After that it downloads Alpine packages, and each agent from its publisher
the first time it is opened.Permissions:
Permission Why INTERNET,ACCESS_NETWORK_STATEDownload Alpine, packages, and agents; show network state on the home screen FOREGROUND_SERVICE,FOREGROUND_SERVICE_SPECIAL_USEKeep terminal sessions running in a separate :terminalprocess while the UI is closedPOST_NOTIFICATIONSOne notification per running session, and "waiting for you" when an agent finishes a turn WAKE_LOCKKeep the CPU awake while a session is running REQUEST_IGNORE_BATTERY_OPTIMIZATIONSAsked for during setup so Android doesn't pause long agent runs VIBRATEShort haptic feedback on button taps WRITE_EXTERNAL_STORAGE(API ≤ 28 only)Copy a folder to Download/Horuson old Android versions
Features
- Alpine workspace on first launch. Horus downloads a pinned Alpine
minirootfs, checks its SHA-256 digest, and extracts it into app-private
storage. Base tools such asgit,curl,jq,rg,python3, and Node
are provisioned on demand. - Coding agents in one tap. Each agent is installed into its own home
directory the first time you open it, with the installer output visible in
the terminal. Later launches reuse the install. - Projects. Create a local folder, clone any HTTPS/SSH Git URL, or pick one
of your GitHub repositories. The GitHub CLI's device login opens in the
Android browser. Projects live under/workspace/projects. - Real terminal. The native PTY supports resize, Ctrl‑C, and job control.
An extra key bar provides Esc, Tab, arrows, and sticky Ctrl/Alt. - Sessions survive the UI. PTYs run in a foreground service in a separate
:terminalprocess, so they keep running when you switch apps, when the app
locks, or when Android reclaims the UI. - Local lock. A password protects the app, and only a salted
PBKDF2-HMAC-SHA256 verifier is stored. The workspace locks after 15 minutes
in the background. - Read-only file browser for your home directory and
/workspace, with
text previews and a copy-to-Downloads action. - Optional remote access over USB with the
horusCLI:
SSH,scp/rsync, port forwarding, and commands across several phones. It
is off by default and nothing else depends on it.
The documentation walks through each of
these step by step.
Build from source
Requirements: Node.js ≥ 22.11, JDK 17, and the Android SDK and NDK (the
standard React Native environment).
The native runtime also needs make, bash, and git.
git clone --recurse-submodules https://github.com/scarif-labs/horus.git
cd horus
npm ci
npm run build:android:debug # or build:android:release
adb install -r android/app/build/outputs/apk/debug/app-debug.apk
If you cloned without --recurse-submodules, rungit submodule update --init for the PRoot and libandroid-shmem sources.
Debug builds embed the JavaScript bundle, so they start without Metro. They
also skip the password screens and open straight into a development terminal.
Release builds enable the full onboarding and lock flow.
Release builds are unsigned unless you pass a keystore through Gradle
properties, for example in ~/.gradle/gradle.properties:
horus.releaseStoreFile=/path/to/release.keystore
horus.releaseStorePassword=...
horus.releaseKeyAlias=...
horus.releaseKeyPassword=...
Tests
npm run typecheck
npm run lint
npm run test:unit # Jest (TypeScript / React Native)
npm run test:kotlin # JVM unit tests for the native layer
npm run test:android:connected # instrumented tests on a connected device
Remote access (optional)
Horus works entirely on the phone. To also use it from a Mac or Linux
computer, install the CLI, turn on USB debugging on the phone, and pair:
npm install -g horus-cli
horus pair
horus ssh
cli/README.md lists every command, and the
CLI guide covers setup from scratch.
How it's secured:
- The phone runs
dropbearinside Alpine, bound to its loopback only
(127.0.0.1:8022). Computers reach it throughadb forward; nothing
listens on Wi-Fi. - Logins are key-only and only as the profile user; root is refused.
horus pairsends the computer's key throughadb shell content call. The
app accepts that call only from the adb shell, and it needs the Horus
password, which shares the lock screen's attempt limit. - The SSH server has its own notification with a Turn off action.
Settings → Remote access turns it off and lists paired computers, which
you can revoke.
How it works
React Native UI (App.tsx, src/)
│ TerminalRuntime TurboModule + TerminalCanvas / TerminalInput native views
▼
Kotlin native layer (android/app/src/main/java/com/scariflabs/horus/terminal)
├─ DistroStore* rootfs download → verify → extract → promote
├─ ProotSessionLauncher builds the PRoot command line and guest environment
├─ TerminalSessionService foreground service in the :terminal process
└─ NativeTerminalEngine / TerminalCanvasView VT parsing and rendering
│
▼
terminal_pty.c (JNI) ── PRoot (native/, built from source) ── Alpine rootfs
Each agent runs as its own locked guest user (UIDs 61001–61003) with a private
home. All of them share workspace GID 1000, so they can work on the same
projects.
Security notes
- Android's app sandbox is the only real security boundary. PRoot emulates
user IDs but gives no kernel isolation between agent users. Don't run code
you don't trust. - Codex's own Linux sandbox doesn't work under PRoot, so the shell wraps
codexwith--sandbox danger-full-access. Codex's approval prompts still
apply. - Remote access is off until you pair a computer or turn it on. When on, it
listens on the phone's loopback only, accepts only paired keys, and refuses
root. Any app on the phone can reach loopback ports, so the key is the
boundary.
License
MIT. Bundled third-party components (xterm.js, PRoot, talloc,
libandroid-shmem, fonts, agent marks) are listed with their licenses in
THIRD_PARTY_NOTICES.md.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi