feat: add companion API and Android APK shell
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user