build: establish Android beta packaging
This commit is contained in:
@@ -5,6 +5,7 @@ All notable Hermes Mobile source changes are recorded here. Entries are added du
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Added semantic Android beta package metadata coverage and a direct-gateway-only `v0.1.0-beta.1` build, metadata inspection, clean-install, launch, configuration, evidence, and limitations guide.
|
||||
- Added deterministic small-phone, landscape, and tablet layout policy with navigation rail adaptation, tablet two-pane chat, and narrow/large-font control stacking.
|
||||
- Added accessibility semantics for headings, panes, streaming announcements, selected/busy states, and actionable rows, plus 48dp minimum touch targets and bounded large message/code rendering with retained full-copy actions for code and tool output.
|
||||
- Added capability-gated direct gateway tool lifecycle decoding and compact status cards for `tool.started`, `tool.progress`, `tool.completed`, and `tool.failed` SSE events.
|
||||
@@ -32,6 +33,7 @@ All notable Hermes Mobile source changes are recorded here. Entries are added du
|
||||
- Added `PROJECT_PLAN.md` as the project-controlled milestone plan.
|
||||
|
||||
### Changed
|
||||
- Changed Android `versionName` to `0.1.0-beta.1`, monotonic `versionCode` to `10001`, and the debug APK base name to `hermes-mobile-v0.1.0-beta.1`; the npm Android build command now runs the native Gradle project without Capacitor synchronization.
|
||||
- Removed the Android portrait lock, enabled `adjustResize` IME behavior, and suppressed top-level screen slides when the system animator duration scale is disabled.
|
||||
- Kept direct artifact handoff actions gated off because the advertised gateway contract has no verified artifact URI/download capability; no upstream route or backend behavior was inferred.
|
||||
- Changed direct session streaming to publish reducer updates to the owning durable send coordinator while retaining the original immutable route/session lease for the entire OkHttp call.
|
||||
@@ -58,6 +60,10 @@ All notable Hermes Mobile source changes are recorded here. Entries are added du
|
||||
- Fixed companion/mobile lint issues from missing Node globals and an unused React settings value.
|
||||
|
||||
### Verification
|
||||
- `/root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh` — passed; Android `:app:assembleDebug` BUILD SUCCESSFUL (37 tasks, 14 executed).
|
||||
- `GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest :app:assembleDebug` — passed (43 tasks, 5 executed), including `BetaPackageMetadataTest` for application ID `cloud.molberg.hermesmobile`, `versionName` `0.1.0-beta.1`, and `versionCode` `10001`.
|
||||
- `git diff --check` — passed for R2 source packaging.
|
||||
- R2 device installation — not run; ADB daemon sockets are sandbox-prohibited and no emulator executable, AVD, `/dev/kvm`, USB device bus, or running target is available. No APK was published or uploaded, and no release criterion is claimed.
|
||||
- R1 source-level verification: the required recovery preflight passed immediately before this run; direct JUnit execution of the cached, source-current Android unit classes passed all 61 tests, including all 4 `AdaptiveQualityTest` cases; and `git diff --check` passed. `GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:compileDebugKotlin :app:compileDebugUnitTestKotlin :app:assembleDebug` was blocked before project execution by `java.net.SocketException: Operation not permitted`. ADB 37.0.0 is installed at `/opt/android-sdk/platform-tools/adb`, but its daemon cannot create the smart-socket or netlink sockets; no emulator executable, AVD, `/dev/kvm`, USB device bus, or running target exists. No emulator/device matrix evidence exists, so R1 remains incomplete.
|
||||
- Full Android Kotlin/Compose main-source and unit-test compilation through cached Kotlin 2.0.21 plus direct JUnit execution — passed, 57 tests including B5 large-output bounds, advertised tool lifecycle reduction, and rotation/resume expansion restoration.
|
||||
- Recovery preflight for B5 — passed before this run.
|
||||
|
||||
+10
-13
@@ -24,27 +24,20 @@
|
||||
|
||||
Complete the Android/client contract pivot before implementing backend behavior. The next release path targets a remote upstream Hermes Agent gateway/API server directly; `apps/companion` is legacy compatibility only.
|
||||
|
||||
- [ ] **R1 — Execute and document the adaptive/accessibility device matrix**
|
||||
- Small phone, normal phone, tablet/two-pane behavior; portrait/landscape.
|
||||
- Font scaling, TalkBack semantics, contrast, touch targets, reduced motion, IME behavior.
|
||||
- Verification: emulator/device matrix evidence documented in `docs/ROADMAP.md`.
|
||||
- Source-level progress on 2026-07-24: removed the portrait lock, enabled resize-on-IME, added deterministic phone/landscape/tablet layout policy and tablet two-pane chat, stacked dense controls for narrow/large-font layouts, respected the disabled system animator-duration setting for top-level navigation, added headings/live regions/roles/state descriptions, raised interactive targets to at least 48dp, and bounded very large message/code rendering while retaining full-copy actions for code and tool output.
|
||||
- Source verification on 2026-07-24: the required recovery preflight passed immediately before this run; direct JUnit execution of the cached, source-current Android unit classes passed all 61 tests, including all 4 `AdaptiveQualityTest` cases; and `git diff --check` passed. A direct writable-cache Gradle retry was blocked before project execution by `java.net.SocketException: Operation not permitted`. ADB is installed, but its daemon sockets are sandbox-prohibited; no emulator executable, AVD, `/dev/kvm`, USB device bus, or running target is available. R1 remains unchecked because no emulator/device matrix evidence exists.
|
||||
- [ ] **R2 — Verify a clean `v0.1.0-beta.1` install against a direct gateway**
|
||||
- On one named real device or emulator, build the source-current versioned debug APK, confirm package metadata, uninstall prior app data, install and launch it, configure an upstream Hermes gateway directly, and record the connection result plus APK SHA-256.
|
||||
- Verification: required preflight and Android checks pass in the install environment; device/install evidence is recorded in `docs/ROADMAP.md`; no release or final beta criterion is claimed from source-only checks.
|
||||
|
||||
## Externally blocked
|
||||
|
||||
- **R1 — Execute and document the adaptive/accessibility device matrix**
|
||||
- Source safeguards and 61 cached source-current unit tests were verified on 2026-07-24, but small-phone, normal-phone, tablet, TalkBack, contrast, motion, and IME evidence still requires a permitted real device or emulator.
|
||||
- Unblock evidence is maintained in `docs/BLOCKERS.md`; do not mark R1 complete from source review alone.
|
||||
- **B3 — Direct gateway session contract and durable chat state**
|
||||
- Foundation verified 2026-07-24: repository search contract and fake implementation, capability-gated session list/create/get/delete mapping, durable selected-session/draft/pending-send storage, and duplicate-send reducer/UI protection.
|
||||
- Not complete: official upstream documentation still provides no session-search HTTP contract, and the configured local API server was not listening for a live compatibility exercise on 2026-07-24.
|
||||
- Unblock evidence is maintained in `docs/BLOCKERS.md`; do not mark B3 complete until documented search and real gateway behavior are verified.
|
||||
|
||||
## Later beta work
|
||||
|
||||
- **R2 — Beta packaging and install guide**
|
||||
- Version `v0.1.0-beta.1`, reproducible debug/beta APK build, install/run guide, known limitations.
|
||||
- Publish source commit, APK, release notes, and verification result.
|
||||
- Verification: clean install on a real device or emulator plus full required checks.
|
||||
|
||||
## V2 backlog
|
||||
|
||||
- Multiple server profiles and fast switching.
|
||||
@@ -60,6 +53,10 @@ Complete the Android/client contract pivot before implementing backend behavior.
|
||||
|
||||
_Move finished items here with date, commit, and verification. Keep this section factual; do not claim unverified work._
|
||||
|
||||
- [x] **R2a — Establish beta source packaging and install documentation** — 2026-07-24, commit `98b183e` (`build: establish Android beta packaging`).
|
||||
- Set Android package metadata to semantic `versionName` `0.1.0-beta.1` with monotonic `versionCode` `10001`, enabled generated metadata coverage, and named the debug APK `hermes-mobile-v0.1.0-beta.1-debug.apk`.
|
||||
- Added a direct-gateway-only build, metadata inspection, clean-install, launch, configuration, evidence, and known-limitations guide; changed the npm Android build command to run the native Gradle project without Capacitor synchronization.
|
||||
- Source verification on 2026-07-24: required recovery preflight passed; `:app:testDebugUnitTest :app:assembleDebug` passed with the cached offline Gradle setup (43 tasks, 5 executed); and `git diff --check` passed. No APK was published, uploaded, or installed, so the remaining R2 device task and all final release criteria remain unclaimed.
|
||||
- [x] **B5 — Tool, artifact, and output experience** — 2026-07-24, commit `feat: add gated tool output experience`.
|
||||
- Added capability-gated decoding and reduction for the existing `tool.started`, `tool.progress`, `tool.completed`, and `tool.failed` direct gateway SSE events, with compact lifecycle/status cards for referenced and stream-only tools.
|
||||
- Added full-output copy plus deterministic collapsed/expanded display windows capped at 5/80 lines and 24,000 expanded characters, avoiding same-direction nested scrolling while retaining the complete output in state.
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# Hermes Mobile
|
||||
|
||||
Android-first mobile control surface and local companion server for [Hermes Agent](https://github.com/NousResearch/hermes-agent).
|
||||
Android-first native client for a remote [Hermes Agent](https://github.com/NousResearch/hermes-agent) gateway/API server, with a legacy local companion retained for compatibility.
|
||||
|
||||
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.
|
||||
The current beta path is a Kotlin/Jetpack Compose thin client that connects directly to an upstream Hermes gateway. Hermes remains authoritative for authentication, sessions, streaming, tools, and backend behavior.
|
||||
|
||||
## What Works Now
|
||||
## Current Android Beta
|
||||
|
||||
- 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.
|
||||
- Native Kotlin/Compose chat, session, settings, adaptive layout, and accessibility foundations.
|
||||
- Direct HTTPS gateway configuration with bearer/no-auth support and local-first routing.
|
||||
- Capability-gated session streaming and tool lifecycle output.
|
||||
- Semantic Android beta metadata at `v0.1.0-beta.1`.
|
||||
|
||||
Build and clean-install instructions are in [Android Beta Build and Install](docs/ANDROID_BETA_BUILD.md). Device installation and the release criteria remain unverified until recorded on a real device or emulator.
|
||||
|
||||
## Monorepo
|
||||
|
||||
@@ -75,26 +76,13 @@ 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:
|
||||
Build the native direct-gateway client without Capacitor synchronization:
|
||||
|
||||
```bash
|
||||
npm run cap:add:android --workspace @hermes-mobile/mobile
|
||||
npm run android:build:debug --workspace @hermes-mobile/mobile
|
||||
npm run android:build:debug
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
See [Android Beta Build and Install](docs/ANDROID_BETA_BUILD.md) for prerequisites, the versioned APK path, package checks, clean installation, direct-gateway setup, and known limitations.
|
||||
|
||||
## Companion API
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ plugins {
|
||||
id 'org.jetbrains.kotlin.plugin.compose'
|
||||
}
|
||||
|
||||
def betaVersionName = '0.1.0-beta.1'
|
||||
def betaVersionCode = 10001
|
||||
|
||||
android {
|
||||
namespace 'cloud.molberg.hermesmobile'
|
||||
compileSdk 35
|
||||
@@ -12,8 +15,9 @@ android {
|
||||
applicationId 'cloud.molberg.hermesmobile'
|
||||
minSdk 23
|
||||
targetSdk 35
|
||||
versionCode 2
|
||||
versionName '0.2.0-native'
|
||||
versionCode betaVersionCode
|
||||
versionName betaVersionName
|
||||
setProperty('archivesBaseName', "hermes-mobile-v${betaVersionName}")
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
}
|
||||
|
||||
@@ -34,6 +38,7 @@ android {
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
compose true
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package cloud.molberg.hermesmobile
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class BetaPackageMetadataTest {
|
||||
@Test
|
||||
fun generatedMetadataMatchesFirstBetaIdentity() {
|
||||
assertEquals("cloud.molberg.hermesmobile", BuildConfig.APPLICATION_ID)
|
||||
assertEquals("0.1.0-beta.1", BuildConfig.VERSION_NAME)
|
||||
assertEquals(10001, BuildConfig.VERSION_CODE)
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
"cap:add:android": "cap add android",
|
||||
"cap:sync": "npm run build && cap sync android",
|
||||
"android:open": "cap open android",
|
||||
"android:build:debug": "npm run cap:sync && cd android && ./gradlew assembleDebug"
|
||||
"android:build:debug": "cd android && ./gradlew :app:testDebugUnitTest :app:assembleDebug"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hermes-mobile/shared": "file:../../packages/shared",
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# Android Beta Build and Install
|
||||
|
||||
This guide covers the native Kotlin/Compose direct-gateway client at version `v0.1.0-beta.1`. It does not build or require `apps/companion`, publish an APK, or complete the beta release criteria by itself.
|
||||
|
||||
## Package identity
|
||||
|
||||
- Application ID: `cloud.molberg.hermesmobile`
|
||||
- Android `versionName`: `0.1.0-beta.1`
|
||||
- Android `versionCode`: `10001`
|
||||
- Debug APK: `apps/mobile/android/app/build/outputs/apk/debug/hermes-mobile-v0.1.0-beta.1-debug.apk`
|
||||
|
||||
`versionName` is the user-visible semantic version. `versionCode` is an internal monotonically increasing Android package revision and must increase for every later installable build.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- JDK 17 or newer supported by the checked-in Android Gradle Plugin.
|
||||
- Android SDK platform 35, matching build tools, and platform tools.
|
||||
- Network access for the first dependency resolution, or a complete compatible Gradle cache.
|
||||
- For installation, a real Android device with USB debugging enabled or a running emulator visible to `adb`.
|
||||
- For use, an HTTPS upstream Hermes Agent gateway/API server and its bearer token when authentication is enabled.
|
||||
|
||||
Do not run Capacitor synchronization for this client. The beta application source is the native project under `apps/mobile/android`.
|
||||
|
||||
## Build and test
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
cd apps/mobile/android
|
||||
GRADLE_USER_HOME="$PWD/../../../.gradle-user" ./gradlew \
|
||||
:app:testDebugUnitTest \
|
||||
:app:assembleDebug
|
||||
```
|
||||
|
||||
The expected APK is:
|
||||
|
||||
```text
|
||||
app/build/outputs/apk/debug/hermes-mobile-v0.1.0-beta.1-debug.apk
|
||||
```
|
||||
|
||||
Confirm the package metadata before distributing the file:
|
||||
|
||||
```bash
|
||||
aapt dump badging app/build/outputs/apk/debug/hermes-mobile-v0.1.0-beta.1-debug.apk \
|
||||
| sed -n '1p'
|
||||
sha256sum app/build/outputs/apk/debug/hermes-mobile-v0.1.0-beta.1-debug.apk
|
||||
```
|
||||
|
||||
Expected badging includes package `cloud.molberg.hermesmobile`, `versionCode='10001'`, and `versionName='0.1.0-beta.1'`.
|
||||
|
||||
The debug APK is signed with the local Android debug key. It is suitable for beta verification, not a production signing or store-release workflow. APKs and build output must remain untracked.
|
||||
|
||||
## Clean install and run
|
||||
|
||||
Confirm that exactly one intended target is attached:
|
||||
|
||||
```bash
|
||||
adb devices -l
|
||||
```
|
||||
|
||||
Remove any prior installation, then install the newly built APK. Uninstalling clears existing Hermes Mobile app data and stored gateway credentials.
|
||||
|
||||
```bash
|
||||
adb uninstall cloud.molberg.hermesmobile || true
|
||||
adb install app/build/outputs/apk/debug/hermes-mobile-v0.1.0-beta.1-debug.apk
|
||||
adb shell monkey -p cloud.molberg.hermesmobile -c android.intent.category.LAUNCHER 1
|
||||
```
|
||||
|
||||
In Hermes Mobile Settings, configure the upstream gateway directly:
|
||||
|
||||
1. Enter the required Remote HTTPS gateway base URL and, optionally, a Local HTTPS URL for the same trusted gateway.
|
||||
2. Select bearer authentication and enter the gateway token when required, or select no authentication only when the gateway is configured that way.
|
||||
3. Save and test the connection. The client probes `/health`, validates compatibility through the authenticated gateway surface, and displays the active Local or Remote route.
|
||||
4. Exercise chat/session behavior only where the gateway advertises the required capabilities.
|
||||
|
||||
Do not enter a legacy companion URL or companion access key. The beta path is the direct upstream Hermes gateway architecture described in `docs/DIRECT_GATEWAY_ARCHITECTURE.md`.
|
||||
|
||||
## Required install evidence
|
||||
|
||||
Record all of the following before claiming R2 installation verification or a beta release:
|
||||
|
||||
- The source commit used for the build.
|
||||
- Passing Android unit tests and APK assembly.
|
||||
- `aapt` package/version output and the APK SHA-256.
|
||||
- A successful clean `adb install` on a named real device or emulator.
|
||||
- App launch plus direct-gateway configuration and connection result.
|
||||
- Any observed limitations or failures, without treating source-only checks as device evidence.
|
||||
|
||||
## Known limitations
|
||||
|
||||
- R1 adaptive/accessibility verification still requires the documented real-device/emulator matrix.
|
||||
- B3 remains blocked on an official session-search contract and live upstream gateway compatibility evidence.
|
||||
- Direct gateway chat, streaming, tools, artifacts, and recovery remain capability-gated; unsupported or unverified routes are not inferred.
|
||||
- The debug APK is not a published release artifact. No beta release exists until all release criteria in `docs/ROADMAP.md` are genuinely satisfied.
|
||||
@@ -6,6 +6,14 @@ R1 cannot be marked complete from the current sandbox. On 2026-07-24, the requir
|
||||
|
||||
Required unblock evidence: run the required preflight and focused Android tests in an environment that permits them, then record the small-phone, normal-phone, and tablet checks in `docs/ROADMAP.md` across portrait/landscape, font scaling, TalkBack, light/dark contrast, touch targets, reduced motion, and IME behavior. Source review, `git diff --check`, and direct execution of cached test classes are supporting evidence only and do not complete R1.
|
||||
|
||||
## R2 — Clean beta build/install verification
|
||||
|
||||
The `v0.1.0-beta.1` Android package metadata and direct-gateway build/install guide are present in source. On 2026-07-24, the required recovery preflight passed and the source-current offline Gradle `:app:testDebugUnitTest :app:assembleDebug` command passed. Installation verification cannot be completed in the current sandbox.
|
||||
|
||||
ADB is installed, but the R1 evidence above confirms that its daemon sockets are prohibited and that no emulator executable, AVD, `/dev/kvm`, USB device bus, or running target is available. Therefore no source-current beta APK package inspection, clean uninstall/install, launch, or direct-gateway device connection was verified here. No APK was published or uploaded, and no final release criterion is claimed.
|
||||
|
||||
Required unblock evidence: in a permitted environment, run the preflight and Android checks from `docs/ANDROID_BETA_BUILD.md`, record `aapt` package/version output and the APK SHA-256, clean-install on one named real device or emulator, launch the app, configure the upstream Hermes gateway directly, and record the connection result in `docs/ROADMAP.md`.
|
||||
|
||||
## Stable gateway identity binding
|
||||
|
||||
The documented direct gateway routes currently available to Hermes Mobile (`GET /health` and authenticated `GET /v1/models`) do not expose a verified stable gateway instance identifier.
|
||||
|
||||
+5
-2
@@ -12,6 +12,7 @@ Done:
|
||||
- Capability-gated session streaming binds each OkHttp call to an immutable route/session lease, parses SSE into authoritative final responses, ignores cross-session events, and reports transport failure only against the failed lease.
|
||||
- Chat UI supports conversation list/thread navigation, native composer, busy state, selectable replies, error bubbles, and new-chat reset.
|
||||
- Direct gateway compatibility contract is documented in `docs/DIRECT_GATEWAY_ARCHITECTURE.md`.
|
||||
- Android source packaging identifies the first beta as `versionName` `0.1.0-beta.1` / `versionCode` `10001`, produces a versioned debug APK name, and has a direct-gateway build/install guide in `docs/ANDROID_BETA_BUILD.md`.
|
||||
- Legacy companion chat, terminal, and file utilities remain in the repo during migration but are not the target architecture.
|
||||
- Local build artifacts, Android transient build output, `.gradle-user/`, and `.dev/` are ignored.
|
||||
- Companion and workspace TypeScript typecheck, build, and lint pass as of 2026-07-24.
|
||||
@@ -22,9 +23,9 @@ Remaining for beta:
|
||||
- Exercise a real device or emulator against a running upstream Hermes gateway/API server.
|
||||
- Verify direct gateway behavior end to end beyond B2: chat request/response, session continuity expectations, streamed/final output handling, and failure recovery.
|
||||
- Verify or revise provisional session, streaming, tool-event, artifact, and cancellation route assumptions against official upstream docs.
|
||||
- Add or run focused Android UI validation for chat/settings flows on small and large screens.
|
||||
- Add or run focused Android UI validation for chat/settings flows on small and large screens in an environment with a permitted emulator or real device.
|
||||
- Confirm adaptive accessibility: font scaling, TalkBack labels, contrast, keyboard/IME behavior, and reduced-motion tolerance.
|
||||
- Document beta install/run steps after the native build is verified.
|
||||
- Build the source-current `v0.1.0-beta.1` APK, verify its package metadata, and record a clean install, launch, and direct-gateway connection on a named real device or emulator.
|
||||
|
||||
## R1 Adaptive/Accessibility Matrix
|
||||
|
||||
@@ -42,6 +43,8 @@ Source-level evidence without device verification: orientation is no longer mani
|
||||
|
||||
## Beta Release Criteria
|
||||
|
||||
No beta release is claimed. Source packaging and documentation are complete, but APK assembly in this sandbox, clean installation, direct-gateway device exercise, R1, and B3 remain unverified or externally blocked.
|
||||
|
||||
- Native Kotlin/Compose Android app is the shipped beta client.
|
||||
- No WebView, Capacitor runtime dependency, fake backend, embedded secrets, or new external infrastructure is introduced for beta.
|
||||
- Direct gateway transport and auth are exercised against the upstream Hermes gateway/API server.
|
||||
|
||||
Reference in New Issue
Block a user