feat: add companion API and Android APK shell

This commit is contained in:
Hermes Agent
2026-07-09 04:43:00 +00:00
parent bd0cf34aa3
commit 7eb9648eb7
92 changed files with 7907 additions and 877 deletions
+93 -131
View File
@@ -1,156 +1,118 @@
# Hermes Mobile
Native Android app, installable PWA fallback, and companion server for [Hermes Agent](https://github.com/NousResearch/hermes-agent).
Android-first mobile control surface and local companion server for [Hermes Agent](https://github.com/NousResearch/hermes-agent).
Hermes Mobile is not a generic LLM chat UI. It is a self-hosted, Hermes-native control surface designed for phone use: prompt by text or voice, upload files, watch tool calls live, approve actions, manage cron jobs, and get notified when long-running agent work is done.
Hermes Mobile is a self-hosted phone UI for running Hermes from Android: chat prompts, browse/edit workspace files, run terminal commands, and check companion/Hermes status over a simple HTTP API.
Repo: https://git.molberg.cloud/bonzi/hermes-mobile
## What Works Now
## Status
- Vite React mobile app with Chat, Files, Terminal, Status, and Settings screens.
- Capacitor configuration and scripts for generating/building an Android APK.
- Fastify companion server with bearer-token auth and safe workspace-root file/terminal access.
- Local setup command that generates and persists an access key.
- HTTP API communication between the mobile app and companion server.
Phase 1 skeleton is underway. The repo now contains a pnpm monorepo with a shared TypeScript package, a Fastify companion server exposing `/api/health`, and a Vite React mobile shell with bottom navigation. Hermes prompting, pairing/auth, persistence, realtime streams, Capacitor Android, and installer productionization are still upcoming roadmap items.
## Product Goals
- Feel like a real Android app, not a web page pretending to be chat.
- Run privately on the same Linux machine as Hermes Agent.
- Keep Hermes Agent untouched where possible; operate as a companion layer above/alongside it.
- Expose Hermes-specific concepts: tool calls, sessions, jobs, generated files, approvals, background tasks.
- Make installation one-liner simple for a homelab machine.
- Stay modular enough that the app, companion server, Hermes integration, notification providers, and install scripts can evolve independently.
## Planned Components
## Monorepo
```text
Android app (Capacitor native shell)
|
| HTTPS + WebSocket/SSE + native push
v
Hermes Mobile App (native Android first, PWA fallback)
|
v
Hermes Companion Server
|
+-- Hermes CLI / Python AIAgent bridge
+-- Hermes API server bridge
+-- Hermes session DB reader
+-- Hermes cron manager
+-- Upload/file store
+-- Push notification provider
apps/mobile Vite React + Capacitor Android app
apps/companion Fastify local companion server
packages/shared Shared TypeScript API schemas/types
docs Product, architecture, install, and API notes
```
## MVP Feature Set
## Install Dependencies
1. Native Android-first app shell
- Capacitor Android wrapper around the shared web UI
- APK/release build installable directly on Android
- PWA/web build retained as fallback and fast dev target
- Native-style bottom navigation, status bar, splash screen, haptics, push, share target later
- Offline-friendly shell
- Dark, playful visual system inspired by happy.engineering / Happy app
This repo works with npm workspaces:
2. Chat / prompt screen
- Text prompts
- Voice note recording
- File uploads: zip, png, jpg, pdf, txt, logs, folders later
- Streaming responses
- “Agent is working” state
- Completion notification
```bash
npm install
```
3. Hermes-native activity timeline
- Tool call started / finished
- Terminal commands
- File reads/writes
- Browser actions
- Home Assistant actions
- Cron changes
- Subagent delegation
- Expand/collapse raw output
## Companion Setup and Run
4. Sessions
- Recent sessions
- Resume session
- Rename / pin / archive
- Per-session attachments and generated files
Generate/persist a local access key:
5. Cron
- List cron jobs
- Run now
- Pause/resume/remove
- View last output
- Delivery target: app notification / in-app inbox
```bash
npm run companion:setup
```
6. Approvals
- Push approval to phone for dangerous commands
- Approve / deny with short audit log
The command prints:
7. Companion settings
- Connect to a companion server URL
- Pair using one-time code or passkey
- Configure notification backend
- View Hermes health/status
- Config path, normally `~/.config/hermes-mobile/companion.json`
- Safe workspace root
- Access key such as `hm_...`
Start the companion server:
```bash
npm run companion:dev
```
The server listens on `0.0.0.0:8787` by default. Useful overrides:
```bash
PORT=8787 HOST=0.0.0.0 HERMES_MOBILE_WORKSPACE_ROOT=/path/to/workspace npm run companion:dev
```
All non-health endpoints require `Authorization: Bearer <access-key>`.
## Mobile Development
Run the browser/PWA development shell:
```bash
npm run mobile:dev
```
Open Settings in the app and use:
- Android emulator URL: `http://10.0.2.2:8787`
- Physical device URL: `http://<your-computer-lan-ip>:8787`
- Access key: value printed by `npm run companion:setup`
Tap **Test connection** to validate the server and key.
## Android APK Build
Install Android Studio/SDK/JDK, then generate the native Android project and build a debug APK:
```bash
npm run cap:add:android --workspace @hermes-mobile/mobile
npm run android:build:debug --workspace @hermes-mobile/mobile
```
APK output:
```text
apps/mobile/android/app/build/outputs/apk/debug/app-debug.apk
```
For later rebuilds after the native project exists:
```bash
npm run cap:sync --workspace @hermes-mobile/mobile
cd apps/mobile/android
./gradlew assembleDebug
```
## Companion API
- `GET /api/health` — no token required; returns service, Hermes CLI, workspace, and uptime.
- `GET /api/auth/validate` — validates `Authorization: Bearer <key>`.
- `POST /api/chat` — sends `{ "prompt": "..." }` to local `hermes` CLI when available.
- `GET /api/files?path=.` — lists workspace files/directories.
- `GET /api/files/read?path=README.md` — reads UTF-8 file content.
- `POST /api/files/write` — writes `{ "path": "notes.txt", "content": "..." }`.
- `GET /api/files/metadata?path=README.md` — returns download-style file metadata.
- `POST /api/terminal/run` — runs `{ "command": "pwd && ls", "cwd": ".", "timeoutMs": 10000 }` under the workspace root.
## Docs
- [Product Plan](docs/PRODUCT_PLAN.md)
- [Architecture](docs/ARCHITECTURE.md)
- [Design System](docs/DESIGN_SYSTEM.md)
- [Companion Server](docs/COMPANION_SERVER.md)
- [Mobile App Structure](docs/MOBILE_APP.md)
- [Architecture](docs/ARCHITECTURE.md)
- [Product Plan](docs/PRODUCT_PLAN.md)
- [Install Strategy](docs/INSTALL.md)
- [Testing Strategy](docs/TESTING.md)
- [Roadmap](docs/ROADMAP.md)
## Proposed Stack
Frontend:
- TypeScript
- React + Vite
- Tailwind CSS
- Zustand or TanStack Query for client state
- Capacitor Android from the start for genuine phone-app feel
- PWA/service-worker build kept as fallback and for desktop/LAN access
- Native plugins: Push Notifications, Haptics, Filesystem/Share, Status Bar, Splash Screen
Companion server:
- TypeScript Node.js initially, because file uploads, WebSocket/SSE, install scripts, and PM2/systemd are straightforward
- Fastify or Hono
- SQLite for app metadata
- Local filesystem upload store
- Python bridge subprocess or direct Hermes module calls where safe
Why not Open WebUI/LibreChat:
- They are model chat UIs.
- Hermes needs agent-native events, cron, approvals, file artifacts, process logs, sessions, and tool timelines.
- Forking a generic app would probably become more work than a clean, small purpose-built app.
## One-liner install target
Final goal:
```bash
curl -fsSL https://git.molberg.cloud/bonzi/hermes-mobile/raw/branch/main/install.sh | bash
```
or, for local/self-hosted raw auth limitations, a release artifact URL:
```bash
curl -fsSL https://hermes-mobile.molberg.cloud/install.sh | bash
```
The installer should:
- Detect Hermes Agent install and config path
- Create a system user or use current user depending mode
- Install Node runtime if missing
- Download release bundle
- Create config at `/etc/hermes-mobile/config.yaml` or `~/.config/hermes-mobile/config.yaml`
- Configure systemd service `hermes-mobile-companion`
- Print pairing URL / one-time setup code
## Development Philosophy
- Companion server owns mobile UX state, not Hermes core.
- Hermes remains the agent runtime/source of truth for actual work.
- Every Hermes integration goes through an adapter interface so we can switch between CLI, API server, direct Python, or future Hermes-native event APIs.
- Tool-call UI should prefer structured events, but gracefully degrade to parsed CLI/API logs during early versions.
- Keep secrets out of repo. Use environment/config files and future vault integration.