ai-app: a phone interface to Claude Code and llama.cpp sessions

A Rust backend that owns the sessions and an Android app that reads them.
The server spawns and adopts CLI processes, normalises everything they emit
into one event model, keeps the transcript, and serves it over pinned TLS on
a WireGuard interface; the phone streams that, replies, sends images, and
imports conversations the machine already has.

`AGENTS.md` is the working guide -- what runs where, what has been measured,
and the faults that were expensive to find. `PLAN.md` is the design record.

History before this point was squashed away. It was a personal project's
running commentary and carried a name and a couple of machine paths that
have no business in a public repository; the tree is what mattered and the
tree is here.
This commit is contained in:
iris committed 2026-08-31 20:29:07 -04:00
commit b172c464ea
100 files changed
+31795

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
#!/bin/sh
# Android SDK environment for this app's Gradle build: locates the SDK and
# exports the PATH/env vars the build needs. Pure Kotlin/Gradle, so nothing
# Rust/NDK-specific belongs here.
#
# Source this directly for one-off commands instead of going through the
# full run-android.sh (which also creates/boots the emulator, builds,
# installs, and launches):
#
# . ./android-env.sh
# ./gradlew :androidApp:assembleDebug
# adb devices
#
# Safe to source repeatedly. Intentionally does NOT `set -e`/`set -u`: this
# file is meant to be sourced into whatever shell is already running --
# including a long-lived one a session reuses for unrelated commands -- and
# changing that shell's error-handling options as a side effect of sourcing
# would be surprising. run-android.sh, which does want strict mode, sets its
# own `set -eu` before sourcing this.
# Hardcoded (not derived from an inherited ANDROID_HOME) so this doesn't
# silently follow whatever that happens to be set to elsewhere -- e.g. this
# sandbox's own profile exports ANDROID_HOME=/opt/android-sdk system-wide, a
# root-owned install this user can't write to. Everything needed lives under
# the path below instead, matching Android Studio's own default SDK location
# convention on Linux.
SDK_ROOT="$HOME/Android/Sdk"
ANDROID_HOME="$SDK_ROOT"
ANDROID_SDK_ROOT="$SDK_ROOT"
# ~/.local/bin is where the `android` CLI itself installs to (see its own
# installer); adding it here too means sourcing this script guarantees a
# working `android` command even in a shell that hasn't picked up
# ~/.profile yet.
PATH="$HOME/.local/bin:$SDK_ROOT/cmdline-tools/latest/bin:$SDK_ROOT/platform-tools:$SDK_ROOT/emulator:$PATH"
# Pin the AVD directory explicitly so avdmanager (creation) and the emulator
# binary (lookup at start time) are guaranteed to agree on where the AVD
# lives -- left to their own defaults they can resolve different locations
# and disagree on whether it exists.
ANDROID_AVD_HOME="${ANDROID_AVD_HOME:-$HOME/.android/avd}"
mkdir -p "$ANDROID_AVD_HOME"
export ANDROID_HOME ANDROID_SDK_ROOT ANDROID_AVD_HOME PATH
echo "==> Ensuring required SDK packages are installed in $SDK_ROOT"
# $SDK_ROOT is user-owned (unlike /opt/android-sdk), so this genuinely
# installs anything missing rather than just probing for it -- still
# best-effort (`|| echo`) so a transient network hiccup doesn't abort a
# script sourcing this under `set -e`.
#
# build-tools is needed twice over: by Gradle for this app's own build, and
# by ../server at runtime for `aapt2` (reading a discovered APK's package
# name) and `llvm-strip`/`apksigner` (the slim-APK pipeline).
android sdk install "cmdline-tools/latest" "platform-tools" "emulator" \
"platforms/android-37.0" "build-tools/37.0.0" \
"system-images/android-36/google_apis/x86_64" \
|| echo " (non-fatal: see above)"