From 8dfc280b947c889c3ca5fd12e8e10a6414c7e042 Mon Sep 17 00:00:00 2001 From: M57 <41645758+Hy4ri@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:30:48 +0300 Subject: [PATCH] Docs/refactor readme (#430) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: improve and shorten README Update app name to Hermes Mobile, correct JDK/dependency versions, and simplify structure. * docs: extract contributing guidelines to CONTRIBUTING.md Move the contributing workflow, code style, and PR checklist to its own file and update README.md to reference it. * docs: link to LICENSE file instead of raw text Simplify the License section in README.md to reference the LICENSE file directly. * docs: remove emojis from features list Clean up visual clutter in README.md by removing emojis from the features section. * docs: add authentication setup guide to README * docs: fix authentication section — matches actual code paths --------- Co-authored-by: M57 --- CONTRIBUTING.md | 49 ++++++++ README.md | 315 ++++++++++++------------------------------------ 2 files changed, 125 insertions(+), 239 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..cb360fbb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contributing to Hermes Mobile + +Thank you for your interest in contributing to Hermes Mobile! To maintain high code quality and consistency, we ask all contributors to follow the workflow and guidelines outlined below. + +--- + +## PR Workflow + +All code changes must go through a pull request (PR). Directly pushing to `main` is not allowed. + +1. **Pick or open an issue** to discuss the changes you want to make. +2. **Create a branch** off `main` using the following naming convention: + - Features: `feat/issue-N-description` + - Bug fixes: `fix/issue-N-description` +3. **Implement your changes** and format them locally. +4. **Submit a PR** targeting the `main` branch. +5. **Ensure all CI checks pass** (formatting, linting, and unit tests). +6. **Maintainers will squash-merge** your PR into `main`. + +--- + +## Code Style + +We enforce Kotlin coding conventions and Jetpack Compose best practices. + +### Kotlin Formatting +- Code formatting is checked and enforced by **ktlint 1.2.1**. +- Run formatting check locally before committing: + ```bash + ./ktlint # Check one file + ./ktlint --format # Auto-fix formatting issues + ``` +- Import ordering is strictly ASCII-lexicographic (uppercase before lowercase: e.g., `LaunchedEffect` before `collectAsState`). + +### Compose Guidelines +- Standard screen structures must use `HermesScaffold` rather than raw Material3 `Scaffold`. +- Composable parameters must follow the standard order: `modifier` first, then event callbacks, and finally children content. + +--- + +## PR Checklist + +Before submitting your PR, please verify: + +- [ ] Your branch is up-to-date with `main`. +- [ ] Local build and `ktlint` checks pass successfully. +- [ ] No unused imports, unused parameters, or dead code. +- [ ] Every `Image` and `Icon` element has a descriptive `contentDescription` for accessibility. +- [ ] New components match the UI/UX style of similar existing screens. diff --git a/README.md b/README.md index 3a682c70..56368e4c 100644 --- a/README.md +++ b/README.md @@ -7,23 +7,12 @@

-

Hermes Control

-

Remote control for your Hermes AI agent — from your pocket.

- -

- Features • - Screenshots • - Quick Start • - Project Structure • - Tech Stack • - Contributing • - Releases -

+

Hermes Mobile

+

Native Android companion app for your Hermes AI agent.

Latest Release CI - Last Commit minSdk 26 targetSdk 36

@@ -32,274 +21,122 @@ ## Overview -**Hermes Control** is a native Android companion app for [Hermes Agent](https://hermes-agent.nousresearch.com) — the open-source, multi-platform AI assistant by Nous Research. - -Instead of pulling out a laptop or switching to Telegram/Discord, you can manage your Hermes agent directly from your phone: - -- 💬 Chat with your agent in real time -- 🔧 Inspect and reconfigure system settings, profiles, and plugins -- 📊 Monitor gateway status, MCP servers, and webhook health -- 📋 Manage cron jobs, environment keys, and toolsets -- 🗂️ Track kanban boards and agent achievements -- 🔄 Pull-to-refresh every data screen - -All this with a **Material You** design that adapts to your device's dynamic color theme. +**Hermes Mobile** is the native Android client for [Hermes Agent](https://hermes-agent.nousresearch.com). It connects securely to your local Hermes gateway (REST API and WebSocket TUI Gateway) over LAN, giving you pocket control over your AI assistant. --- ## Features -### 🤖 Agent Chat -- Real-time message exchange with your Hermes agent -- Session management with profile switching -- Message history with persistent storage (Room) - -### ⚙️ System Management -- **Profiles** — View and switch between Hermes agent profiles -- **Skills** — Browse installed skills with inline descriptions -- **Plugins** — Manage active plugins and their configurations -- **Toolsets** — See which toolsets are enabled per profile - -### 🛠️ Operations -- **Cron Jobs** — View scheduled tasks, their schedules, and last-run status -- **Webhooks** — Configure and test webhook endpoints -- **Keys & Credentials** — Securely manage environment variables -- **Logs** — Stream and filter agent logs - -### 📡 Connectivity -- **Gateway Status** — Monitor WebSocket and API gateway health -- **MCP Servers** — Manage Model Context Protocol server connections -- **Channels** — View connected messaging platform status - -### 📊 Productivity -- **Kanban Boards** — Track tasks across boards, columns, and cards -- **System Info** — Runtime environment and configuration overview -- **Achievements** — Agent milestone tracker - -### 🎨 UX -- **Material You** — Dynamic color theming from your wallpaper -- **Pull-to-Refresh** — Swipe down on any data screen to reload -- **Shared Scaffold** — Consistent navigation and layout across all screens -- **Scroll-aware TopBar** — Collapsing top bar on scroll - ---- - -## Screenshots - -> 📸 Screenshots coming soon. Build the app and see it in action! - -| Chat | System | Profile | Kanban | -|:---:|:---:|:---:|:---:| -| 🔲 | 🔲 | 🔲 | 🔲 | +- **Real-Time Chat:** Message your agent with Room-backed local database history. +- **System Config:** Manage active profiles, installed skills, plugins, and LLM model selections. +- **Operations:** Stream and filter live logs, manage cron jobs, edit environment keys, and test webhooks. +- **Gateway Status:** Monitor WebSocket connection, MCP servers, and messaging channel status. +- **Productivity:** View and manage tasks via integrated Kanban boards and track agent milestones. +- **Modern UX:** Native Material You design supporting dynamic color theming, scroll-aware TopBar, and pull-to-refresh. --- ## Quick Start ### Prerequisites +- **JDK 21+** (required for Kotlin compilation and the Gradle toolchain) +- **Android Studio** (Ladybug+) or a **Nix** development environment -| Tool | Version | Reason | -|------|---------|--------| -| [JDK](https://adoptium.net/) | 17+ | Kotlin/JVM compilation | -| [Android Studio](https://developer.android.com/studio) | Hedgehog+ | IDE + SDK management | -| Android SDK | 36 (compile), 26 (min) | Via Android Studio SDK Manager | -| Git | any | Clone the repo | +### Build & Deploy +1. **Clone the repository:** + ```bash + git clone https://github.com/Hy4ri/hermes-mobile.git + cd hermes-mobile + ``` +2. **Build the debug APK:** + ```bash + ./gradlew assembleDebug + ``` +3. **Install on your emulator/device:** + ```bash + adb install app/build/outputs/apk/debug/app-debug.apk + ``` -### Clone & Build +*Note: For release builds, ensure keystore environment variables (`KEYSTORE_PATH`, `KEYSTORE_PASSWORD`, `KEY_ALIAS`, `KEY_PASSWORD`) are configured, or let the GitHub Actions release workflow handle it on tag push (`v*`).* + +--- + +## Authentication + +Once the app is installed, you need to point it at your Hermes gateway. The app auto-detects which auth mode the dashboard is using — just fill in the fields it shows. + +### 1. Start the dashboard + +On your host machine, start the dashboard: ```bash -git clone https://github.com/Hy4ri/hermes-mobile.git -cd hermes-mobile -./gradlew assembleDebug +hermes dashboard # loopback (127.0.0.1:9119) — no auth needed +hermes dashboard --host 0.0.0.0 # LAN — requires auth ``` -The debug APK will be at `app/build/outputs/apk/debug/app-debug.apk`. +For LAN access, configure credentials in `~/.hermes/config.yaml`: -### Build with custom version - -```bash -./gradlew assembleRelease -PversionName="1.2.0" -PversionCode="120" +```yaml +dashboard: + basic_auth: + username: admin # pick your own + password: hermes # pick your own ``` -> **Note:** Release builds require proper signing configuration. Ensure the environment variables `KEYSTORE_PATH`, `KEYSTORE_PASSWORD`, `KEY_ALIAS`, and `KEY_PASSWORD` are set before building. +### 2. Connect the app -### Install +Tap **Sign in** on the landing screen and enter the dashboard host and port. The app probes the dashboard and reveals the fields you need: -```bash -adb install app/build/outputs/apk/debug/app-debug.apk -``` +| Auth mode | When | What you fill | +|-----------|------|---------------| +| **Token only** | Dashboard on same machine (loopback) | **Token** — grab from `~/.hermes/dashboard-token.txt` or `~/.hermes/.env` (`HERMES_DASHBOARD_SESSION_TOKEN`). The app can also auto-extract it from the dashboard page | +| **Basic auth** | Dashboard on LAN with password gate | **Username** + **Password** (default `admin` / `hermes`). The app logs in, gets a session cookie, and mints a WebSocket ticket automatically | -Or open the project in Android Studio and hit **Run ▶**. +> The app communicates over plain HTTP — it's designed for **trusted local networks only**. Do not expose your Hermes gateway to untrusted networks. + +### Connection profiles + +Have multiple gateways? Switch between them in **Settings → Connection profiles**. Each profile stores its own host, port, and token — just tap to swap. + +### Pairing (admin) + +The **Pairing** screen lets you approve or revoke agents and services that are trying to connect to your gateway, such as Telegram or Discord sessions. --- ## Project Structure ``` -hermes-mobile/ -├── app/ -│ ├── src/ -│ │ ├── main/ -│ │ │ ├── java/com/m57/hermescontrol/ -│ │ │ │ ├── Navigation.kt # Drawer + NavDisplay + entry wiring -│ │ │ │ ├── NavigationController.kt # Central navigation guard (dedup) -│ │ │ │ ├── NavigationKeys.kt # Screen key definitions -│ │ │ │ ├── MainActivity.kt # Single activity entry point -│ │ │ │ ├── data/ -│ │ │ │ │ ├── model/ # API models / DTOs (20+ files) -│ │ │ │ │ ├── remote/ # Retrofit + OkHttp API client -│ │ │ │ │ ├── local/ # Room DB (Dao, Entity, Mapper) -│ │ │ │ │ └── ws/ # WebSocket TUI Gateway (JSON-RPC 2.0) -│ │ │ │ ├── notification/ -│ │ │ │ │ └── ChatNotificationService.kt # Foreground service for reply alerts -│ │ │ │ ├── theme/ -│ │ │ │ │ ├── Theme.kt # Material You dynamic theming -│ │ │ │ │ ├── Color.kt # Color palette definitions -│ │ │ │ │ ├── HermesStatusColors.kt # Semantic status colours (CompositionLocal) -│ │ │ │ │ ├── Type.kt # Typography scale -│ │ │ │ │ ├── Motion.kt # Shared transition animations -│ │ │ │ │ ├── Spacing.kt # Spacing tokens (CompositionLocal) -│ │ │ │ │ └── Shapes.kt # Shape tokens -│ │ │ │ ├── ui/ -│ │ │ │ │ ├── common/ # Shared components -│ │ │ │ │ │ ├── HermesScaffold.kt # Standardised screen layout -│ │ │ │ │ │ ├── StateViews.kt # Loading, error, empty placeholders -│ │ │ │ │ │ └── SharedComponents.kt # SearchBar, FilterChips, ToggleRow, etc. -│ │ │ │ │ ├── chat/ # Chat screen + view model -│ │ │ │ │ ├── settings/ # Settings screen + view model -│ │ │ │ │ ├── connect/ # Connect / pairing screen -│ │ │ │ │ ├── profiles/ # Profile management -│ │ │ │ │ ├── skills/ # Skills browser -│ │ │ │ │ ├── plugins/ # Plugin management -│ │ │ │ │ ├── toolsets/ # Toolset viewer -│ │ │ │ │ ├── cron/ # Cron job viewer -│ │ │ │ │ ├── webhooks/ # Webhook management -│ │ │ │ │ ├── logs/ # Log stream viewer -│ │ │ │ │ ├── keys/ # Environment variable manager -│ │ │ │ │ ├── gateway/ # Gateway health monitor -│ │ │ │ │ ├── mcp/ # MCP server manager -│ │ │ │ │ ├── model/ # LLM model selector -│ │ │ │ │ ├── channels/ # Messaging channels -│ │ │ │ │ ├── pairing/ # Device pairing -│ │ │ │ │ ├── config/ # Raw config viewer -│ │ │ │ │ ├── system/ # System info screen -│ │ │ │ │ ├── kanban/ # Kanban board viewer -│ │ │ │ │ └── achievements/ # Agent achievements -│ │ │ │ └── util/ # Utility classes -│ │ │ │ └── CronExpressionFormatter.kt -│ │ │ ├── res/ -│ │ │ │ ├── values/ -│ │ │ │ │ └── strings.xml # String resources -│ │ │ │ ├── drawable/ # Vector icons & drawables -│ │ │ │ └── mipmap-*/ # Launcher icons -│ │ │ └── AndroidManifest.xml -│ │ └── test/ # Unit tests -│ │ └── kotlin/com/m57/hermescontrol/ -│ └── build.gradle.kts # App-level build config -├── gradle/ -│ └── libs.versions.toml # Version catalog -├── .github/ -│ └── workflows/ -│ ├── android.yml # CI (ktlint + unit tests) -│ └── release.yml # Release APK builder -├── build.gradle.kts # Root build config -├── settings.gradle.kts # Project settings -└── gradlew # Gradle wrapper +app/src/main/java/com/m57/hermescontrol/ +├── data/ # Local (Room, EncryptedSharedPreferences) & Remote (Retrofit, OkHttp WS) +├── notification/ # Foreground service for message notifications +├── theme/ # Material You design system, status colors, spacing, and typography +└── ui/ # Compose screens (Chat, Settings, Profiles, Kanban, etc.) + Navigation ``` -\n--- - -## Tech Stack - -| Category | Library | Purpose | -|----------|---------|---------| -| **Language** | [Kotlin 2.3+](https://kotlinlang.org/) | Primary language | -| **UI** | [Jetpack Compose](https://developer.android.com/develop/ui/compose) (BOM 2026.03.01) | Declarative UI | -| **Design** | [Material3](https://m3.material.io/) (Compose) + Material You | Dynamic theming | -| **Navigation** | [Navigation3](https://developer.android.com/develop/ui/compose/navigation) | Screen routing | -| **Networking** | [Retrofit 2](https://square.github.io/retrofit/) + [OkHttp 4](https://square.github.io/okhttp/) | REST API calls | -| **Persistence** | [Room](https://developer.android.com/training/data-storage/room) (SQLite) | Local message history | -| **Encryption** | AndroidX Security Crypto | Secure key storage | -| **Background** | Foreground Service | Notification polling (`ChatNotificationService`) | -| **Serialization** | [Gson](https://github.com/google/gson) | JSON parsing | -| **Testing** | jUnit 5 + [MockK](https://mockk.io/) + [OkHttp MockWebServer](https://github.com/square/okhttp/tree/master/mockwebserver) | Unit testing | -| **Linting** | [ktlint](https://ktlint.github.io/) | Kotlin code style | --- -## Architecture +## Tech Stack -The app follows a **single-activity, Compose-first** architecture with MVVM: - -``` -View (Composable) → ViewModel → ApiClient (Retrofit) → Hermes Agent (HTTP) -``` - -- **Screens** are pure Compose functions that observe `StateFlow` from their ViewModel -- **ViewModels** manage UI state and call the API client -- **ApiClient** is a Retrofit-based HTTP client that talks to the Hermes Agent REST API -- **Navigation** uses a custom NavHost with drawer-based routing +- **Language:** Kotlin 2.4.0 with KSP compiler plugin +- **UI & Layout:** Jetpack Compose (BOM 2026.03.01) & Material 3 / Material You +- **Navigation:** Navigation3 (Compose-first Routing) +- **Networking:** Retrofit 3.0.0, OkHttp 5.4.0, Gson 2.14.0 +- **Database:** Room 2.7.1 with SQLCipher encryption +- **Security:** `EncryptedSharedPreferences` (AES256-GCM) +- **Formatting:** `ktlint` style rules (checked automatically in CI) --- ## Contributing -PRs are welcome! Here's the workflow: +Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for our branch workflow, code style guidelines, and PR checklist. -1. **Pick an issue** — or create one first to discuss the change -2. **Branch** from `main` — use `feat/issue-N-description` or `fix/issue-N-description` -3. **Implement** — one PR per logical change -4. **CI must pass** — ktlint + lintDebug + unit tests run on every PR -5. **Squash merge** into `main` - -### Code style - -- ktlint enforces consistent formatting (`./gradlew ktlintCheck`) -- Use `HermesScaffold` for new screens (never raw Material3 `Scaffold`) -- Compose parameters follow the standard order: `modifier`, callbacks, content - -### PR checklist - -- [ ] Branch from `main` and target `main` -- [ ] CI is green (ktlint, lint, tests) -- [ ] No unused imports or dead code -- [ ] `contentDescription` on all `Image`/`Icon` elements (accessibility) -- [ ] Follows the existing pattern for similar screens - ---- - -## Releases - -Pre-built APKs are available on the [Releases page](https://github.com/Hy4ri/hermes-mobile/releases). - -Each release is built automatically by CI when a maintainer pushes a `v*` tag: - -```bash -git tag v1.2.0 -git push origin v1.2.0 -``` - -The `release.yml` workflow will: -1. Run full CI (ktlint, lint, tests) -2. Build a release APK with the correct version -3. Create a GitHub Release with auto-generated notes -4. Attach the APK as a downloadable asset +For developer-specific details, code conventions, and project architecture notes, refer to [AGENTS.md](AGENTS.md). --- ## License -``` -Copyright 2026 Hy4ri - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` +This project is licensed under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for details. +renamed '/tmp/hermes-snap-800bd6e0cc89.sh.tmp.17855' -> '/tmp/hermes-snap-800bd6e0cc89.sh'