M0: toolchain, monorepo scaffold, gateway plugin skeleton, CMP app

- gateway-plugin/: android platform plugin (plugin.yaml + adapter.py
  register(ctx) + no-op AndroidAdapter) + stub modules for M1-M5
- app/: Compose Multiplatform project (shared KMP + androidApp +
  desktopApp) with Gradle wrapper; builds :androidApp:assembleDebug
  and :desktopApp:compileKotlin
- scripts/guard_hermes_agent.sh + pre-commit hook: fail if hermes-agent/
  is staged (read-only reference, never committed)
- .gitignore excludes hermes-agent/; docs/ reference library
This commit is contained in:
ARIA committed 2026-08-19 11:27:02 +02:00
commit 59acf66c89
49 files changed
+3950

No files matched your search

+93
View File
@@ -0,0 +1,93 @@
# 00 — Overview
## Vision
A **native, Telegram-quality chat experience** for a personal hermes-agent:
install an app on your phone (and a desktop app on your PC), pair it to your
running `hermes gateway`, and talk to your agent with streaming replies,
visible reasoning, structured tool activity, channels/threads, media, search,
and push notifications — with cron jobs able to post into any channel you
create.
## Goals
- **Native feel.** Real Android app (Kotlin/Compose), not a WebView. Desktop
app that is the same app, resized for a big screen.
- **First-class gateway citizen.** The app is a hermes *messaging platform*, so
everything the gateway already does "just works": slash commands, cron
delivery, `send_message` routing, coexistence with Telegram/Discord/etc.
- **Full agent transparency.** Streaming text, reasoning shown *before* the
answer, structured tool events (the app chooses how much to show), and
intermediate assistant beats.
- **Organized by default.** A default chat with optional threads, plus
user-created channels that cron jobs can target.
- **Reachable anywhere.** Live over a WebSocket; background push via FCM
(primary) or ntfy (fallback).
## In scope (v1)
Everything in the feature checklist below.
## Out of scope / stretch (v1)
- **Standalone-cron delivery while the gateway process is fully down** —
best-effort FCM/ntfy only (the outbox is served by the running gateway).
- **Multi-user / group chat** — this is a *personal* 1-user agent.
- **End-to-end encryption** — transport security (WSS) only.
- **iOS** — Android + Desktop only (the protocol is transport-agnostic, so an
iOS client is a future port, not a v1 goal).
## Feature checklist → where it's handled
| Requirement | Gateway plugin | App |
|---|---|---|
| Input box, auto-grow (max height) | — | Compose `TextField` + bounded `heightIn` |
| Menu button → all slash commands | Dispatches `/…`; serves command catalog | Bottom-sheet menu + `/` autocomplete |
| Tool output (app decides how much) | Emits **structured** tool events | App setting: everything / truncated / nothing |
| Reasoning shown before message | Captures + splits reasoning | Collapsible "Reasoning" block above message |
| Intermediate messages | Forwards `Commentary` events | Distinct dimmed bubble |
| Threading + channels; default chat; user channels for cron | `chat_id`/`thread_id` model; cron `deliver=android:<chat>[:<thread>]` | Channel list, thread toggle, "new channel" |
| Search ("everywhere" / "this chat/channel") | FTS5 session search bridge | Search UI + scope toggle |
| Attach media (music/video/images/docs) | Inbound cache; outbound `send_*` | Pickers + chunked upload + preview |
| Push notifications | FCM (primary) / ntfy (fallback) | FCM token / ntfy topic + notification service |
| Live playback of AI-sent music/video | Serves media bytes over WS | ExoPlayer inline player |
## Locked decisions (from planning)
| Decision | Choice |
|---|---|
| Desktop app tech | **Compose Multiplatform** (shares Android code; "tweaked" for big screen) |
| Push backend | **Both** — FCM primary, ntfy fallback (`ANDROID_PUSH_BACKEND`) |
| Media transport | **Over the WebSocket** (chunked binary frames; no extra Python deps) |
| Phone default layout | **User-toggleable, single-pane default** (auto two-pane on large screens) |
## Disclaimers (hard rules)
1. **`hermes-agent/` is a read-only research reference.** It lives next to this
folder for study only. It is **git-ignored** and must **never** be committed,
pushed, or included in any artifact. Our plugin is *installed* into a live
hermes home (`~/.hermes/plugins/android`); we never edit hermes core files.
2. **ADB is available and a device is connected** (`a5ca2a4b`, Xiaomi MIX 2S,
Android 10 / API 29). Use `adb install` / `adb logcat` / `adb shell am start`
to install, launch, and debug the app on-device throughout the build.
## Verified environment state (2026-08-19)
| Item | State |
|---|---|
| OS | CachyOS (Arch-based), `pacman` present |
| JDK | **Not installed** → Milestone M0 (`pacman -S jdk17-openjdk`) |
| Android SDK | **Not installed** → M0 (cmdline-tools + sdkmanager) |
| Gradle | Via project wrapper (`gradlew`), no system install |
| ADB | Installed; device `a5ca2a4b` (MIX 2S, API 29) connected |
| Python | 3.14.7; `uv` 0.12.3 present |
| hermes venv | **Not created** → M0 (`cd hermes-agent && uv sync`) |
| hermes core deps | `websockets==15.0.1` and `httpx` are **core** deps → plugin needs **zero new Python deps** |
| Disk / RAM | 522 GB free / 62 GB RAM — ample |
## Naming
- Product/effort name: **Iris × Hermes** (folder `iris_x_hermes`).
- hermes platform name: **`android`** (the plugin registers `Platform("android")`).
- WS default port: **8790** (configurable).
- Default chat id: **`android:default`** (the home channel).