Files
2026-07-25 01:40:08 +00:00

21 KiB

Changelog

All notable Hermes Mobile source changes are recorded here. Entries are added during the same work loop as their implementation; release artifacts are only listed after source commit, checks, and APK upload are verified.

Unreleased

Added

  • Added a first-run Compose Setup Wizard with welcome/privacy guidance, required Remote HTTPS and optional Local HTTPS routes, None/Bearer/username-password authentication, local-first connection testing, and completion gating on a successful test.
  • Added direct password login with allowlisted session-cookie handling, encrypted credential/session storage, redacted credential models, and focused reducer, login, cookie-storage, migration, and routing tests.
  • 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.
  • Added bounded collapsed/expanded large-output windows with full-output copy, plus durable expanded-tool restoration across rotation/process resume.
  • Added a durable direct-gateway SSE send coordinator that captures the selected session, draft, request ID, and immutable route lease before asynchronous execution.
  • Added deterministic coordinator tests for successful SSE completion, upstream gateway failure, transport failure, and stale request IDs.
  • Added an OkHttp-backed Android session stream repository that executes the capability-advertised SSE request and reduces decoded frames through the existing lease-bound foundation.
  • Added deterministic fake HTTP/SSE repository tests for authoritative completion, original-lease transport failure, and gateway error events that do not invalidate the route.
  • Added a capability-gated direct session SSE foundation with structured {method, path} endpoint parsing, immutable route/session leases, documented input request encoding, and core event decoding.
  • Added deterministic stream tests for token deltas, authoritative final-response reconciliation, cross-session rejection, missed-start recovery, and capability-gated structured tool events.
  • Added B3 foundation contracts for session search plus capability-negotiated session list/create/get/delete requests, without enabling unadvertised gateway routes.
  • Added durable Android selected-session, per-session draft, and pending-send state with fake repository/reducer coverage for duplicate-send protection and restoration.
  • Added one securely stored Hermes gateway profile with optional Local HTTPS and required Remote HTTPS routes, bearer/no-auth configuration, and visible active-route diagnostics.
  • Added bounded, redirect-disabled GET /health probes plus authenticated GET /v1/models compatibility checks and deterministic route, retry, connection-state, and HTTP-header tests.
  • Added foreground, explicit reconnect, connectivity-change, and failed-request re-evaluation hooks backed by immutable per-request route leases.
  • Added docs/DIRECT_GATEWAY_ARCHITECTURE.md to define the direct upstream Hermes gateway architecture, documented endpoints, unverified assumptions, and legacy companion compatibility policy.
  • Added transport DTOs and domain repository contracts for server profiles, authentication, sessions, messages, stream events, tool results, and artifacts.
  • Added DTO-to-domain/UI mappers, stream reducer behavior, and a fake Hermes repository with unit coverage for mappings, stream reduction, and repository fixtures.
  • Added a fake-data Compose chat proving ground with local session rail/list, context controls, keyboard-safe composer, send/cancel/retry, and seeded empty/loading/reconnecting/error states.
  • Added typed user, assistant, system, error, and streaming chat models; selectable markdown-friendly text, copyable horizontally scrollable code blocks, expandable tool results, and reducer unit tests.
  • Added a Compose design-system package with color, semantic status, spacing, typography, shape, elevation, and motion tokens.
  • Added light and dark Hermes Compose themes backed by Material 3 color schemes.
  • Added Compose previews for small phone, normal phone, tablet width, light theme, and dark theme component coverage.
  • Added native Android chat, workspace, settings, local defaults, companion health, and file editing surfaces for the beta client.
  • Added PROJECT_PLAN.md as the project-controlled milestone plan.

Changed

  • Corrected the Android beta install guide so clean installs enter the mandatory Setup Wizard, document all three authentication modes, require a successful test before completion, and reserve Settings for post-setup editing/retesting.
  • Corrected the recorded Setup Wizard and beta packaging commit references and documented the source-current Task 5 verification attempt without adding device, release, installation, or credential claims.
  • Changed Settings to edit the same Setup Wizard profile, while valid existing configurations skip first-run setup and legacy/current profiles receive a one-time setup-version migration.
  • Changed gateway probing to support None, Bearer, and password-session cookie authentication without exposing raw credentials in connection forms, diagnostics, or logs.
  • 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.
  • Changed direct session streaming so one immutable route/session lease owns the request and every decoded event for the full OkHttp call.
  • Changed streamed assistant reduction so deltas can recover a missing start event and the final upstream response replaces accumulated partial text.
  • Restructured the delivery plan so externally blocked B3 remains incomplete while durable chat-send integration with the completed SSE repository is the sole current atomic task.
  • Changed Android gateway routing to prefer a compatible Local route and deterministically fall back to Remote without switching an in-flight lease.
  • Changed the Android shell to stop calling undocumented legacy companion /api/* routes; unavailable workspace/chat utilities now remain gated until direct upstream contracts are verified.
  • Changed Android networking to reject cleartext, credential-bearing, path-bearing, duplicate, or missing gateway URLs and disabled application cleartext traffic.
  • Pivoted planning and Android connection/domain terminology toward direct gateway auth, sessions, streaming, and later legacy companion removal.
  • Changed Android transport/domain capability models and fake repository data to describe direct gateway support first, with legacy companion compatibility explicitly flagged.
  • Changed the fake chat seed path to reuse the fake Hermes repository preview state.
  • Extracted shared Compose cards, rows, buttons, text fields, notices, message bubbles, list scaffolds, and code surfaces out of MainActivity.kt.
  • Updated the native Appearance screen to describe system light/dark theming and design tokens.
  • Updated companion /api/chat to call hermes chat -Q --source tool -q <prompt>, sanitize CLI banners/help/control output, truncate large mobile replies, and return structured failures.
  • Reconciled docs/ROADMAP.md to the current native Android beta state.
  • Ignored .gradle-user/ and .dev/ alongside existing generated build artifacts.

Fixed

  • Fixed the first-run gate so an uncompleted Bearer profile cannot self-migrate after a failed/offline test and bypass setup on restart; only profiles with recorded legacy provenance migrate.
  • Fixed the setup gate so valid pre-wizard bearer profiles already stored under the current connection keys receive the one-time completion migration; untested no-auth first-run profiles remain gated.
  • Fixed first-run setup so a profile saved by a failed/offline compatibility test cannot bypass mandatory setup after process restart; only completed or migrated valid profiles skip the wizard.
  • Fixed durable stream completion so a stale request ID cannot publish a terminal state or clear a newer reservation.
  • Fixed stream failure handling so HTTP, I/O, and malformed-SSE failures are reported and reduced only against the original lease, while upstream error events remain session failures rather than route failures.
  • Fixed bearer handling so /health is checked without credentials and the token is sent only to the documented authenticated /v1/models compatibility route.
  • Fixed legacy stored HTTP URLs so they cannot become active routes, and sanitized connection/request diagnostics so tokens and internal URLs are not emitted.
  • Fixed companion/mobile lint issues from missing Node globals and an unused React settings value.

Verification

  • Task 5 delivery verification on 2026-07-25: /root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh passed; from apps/mobile/android, 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, 1 executed); git diff --check passed. Current Gradle XML reports record 107 tests with 0 failures/errors/skips. The ignored debug APK reports package cloud.molberg.hermesmobile, version 0.1.0-beta.1 (10001), size 17,710,960 bytes, and SHA-256 714e8e9cdd3f2eed93b285f233b1f4573d5d13fc2078bb717631f9b38f8428d4. ADB reports no attached devices; no emulator/AVD or /dev/kvm is available. No device installation, release, or gateway end-to-end verification is claimed.
  • Focused wizard regression: ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest --tests 'cloud.molberg.hermesmobile.onboarding.SetupWizardReducerTest' :app:assembleDebug — passed (43 tasks, 9 executed), including the Bearer restart regression.
  • ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest --tests 'cloud.molberg.hermesmobile.onboarding.SetupWizardReducerTest' :app:assembleDebug — passed (43 tasks, 9 executed), including the new current-key migration regression.
  • Task 5 source-current re-verification on 2026-07-24: /root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh passed; ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest :app:assembleDebug passed (43 tasks, 1 executed); the generated Gradle XML report records 106 tests with 0 failures/errors, including 29 SetupWizardReducerTest cases; a localhost gateway health probe returned HTTP 200, establishing reachability only; the debug APK reports package cloud.molberg.hermesmobile, version 0.1.0-beta.1 (10001), and SHA-256 45e4ab4783a74eb766070b0f670a2631a9ebdc044468bbe03087788f8106f150; and git diff --check passed. No ADB device/emulator or /dev/kvm was available; no device installation, real authentication, release, or end-to-end gateway verification is claimed.
  • Later Task 5 current-sandbox rerun on 2026-07-24: the exact guide Gradle command was blocked before project execution because no usable wildcard IP was available; the offline/no-daemon variant was blocked because Gradle could not open its daemon TCP socket (java.net.SocketException: Operation not permitted). Direct JUnit execution of the existing source-current compiled SetupWizardReducerTest classes passed all 29 tests. The existing XML reports remain 106 tests with 0 failures/errors, and the existing ignored APK remained unchanged; aapt and SHA-256 inspection reconfirmed package cloud.molberg.hermesmobile, version 0.1.0-beta.1 (10001), and SHA-256 45e4ab4783a74eb766070b0f670a2631a9ebdc044468bbe03087788f8106f150. ADB 37.0.0 could not start its daemon, and /dev/kvm plus /dev/bus/usb were absent. This adds fresh focused reducer execution only; no fresh Gradle compilation/test task, APK assembly, device, authentication, release, or end-to-end evidence is claimed.
  • ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest --tests 'cloud.molberg.hermesmobile.onboarding.SetupWizardReducerTest' — passed (28 tests), after the new regression first failed as expected.
  • ./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest :app:assembleDebug — passed (43 tasks, 4 executed).
  • git diff --check — passed for the setup restart-bypass fix.
  • First-run Setup Wizard source verification: the source-current generated Gradle report records 106 tests (0 failures/errors), including 29 Setup Wizard reducer tests; an offline Android :app:testDebugUnitTest :app:assembleDebug rerun passed on 2026-07-24 (43 tasks, 1 executed). git diff --check passed. No device, release, or real gateway credential test is claimed.
  • /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.
  • 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 — attempted for B5 but blocked before project execution because the sandbox prohibits Gradle's TCP control socket (java.net.SocketException: Operation not permitted).
  • git diff --check — passed for B5.
  • /root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh — passed; Android :app:assembleDebug BUILD SUCCESSFUL (35 tasks, 4 executed).
  • Full Android Kotlin/Compose main-source and unit-test compilation through the cached Kotlin compiler plus direct JUnit execution — passed, 52 tests including B4c coordinator success, gateway-failure, transport-failure, and stale-request-ID coverage.
  • git diff --check — passed for B4c.
  • Full Android Kotlin/Compose main-source and unit-test compilation through the cached Kotlin compiler plus direct JUnit execution — passed, 48 tests including the B4b reducer, stream-contract, and fake HTTP/SSE repository coverage.
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew --no-daemon -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest :app:assembleDebug — blocked before project compilation because this sandbox prohibits Gradle's TCP control socket (java.net.SocketException: Operation not permitted).
  • git diff --check — passed for B4b.
  • /root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh — blocked before execution because this sandbox denies read/execute access to the required script (Permission denied).
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew --no-daemon -Pkotlin.compiler.execution.strategy=in-process :app:compileDebugUnitTestKotlin :app:assembleDebug — blocked before project compilation because the Gradle daemon cannot open its sandbox-prohibited TCP control socket (java.net.SocketException: Operation not permitted).
  • Focused cached Kotlin compilation plus direct JUnit execution of HermesStreamReducerTest and GatewayStreamingContractTest — passed, 12 tests.
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew :app:testDebugUnitTest --tests 'cloud.molberg.hermesmobile.domain.HermesStreamReducerTest' --tests 'cloud.molberg.hermesmobile.streaming.GatewayStreamingContractTest' — blocked before compilation because the sandbox cannot determine a usable wildcard IP.
  • Full Android Kotlin/Compose source and unit-test compilation through the cached Kotlin compiler plus direct JUnit execution — passed, 37 tests including B3 session capability mapping, durable chat JSON/state, fake chat reducer, and fake repositories.
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew :app:testDebugUnitTest — blocked before compilation because this sandbox prohibits Gradle daemon/control sockets (java.net.SocketException: Operation not permitted).
  • npm run typecheck && npm run lint && npm run build — passed for all workspaces.
  • Direct Kotlin/JUnit execution of ConnectionStateTest and GatewayHttpProbeTest — passed, 12 tests.
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew --no-daemon -Pkotlin.compiler.execution.strategy=in-process :app:compileDebugUnitTestKotlin :app:assembleDebug from apps/mobile/android — passed with temporary restored sandbox-only Gradle socket shims; 37 tasks, 6 executed.
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew :app:testDebugUnitTest — test sources compiled, but Gradle's forked test worker could not open its sandbox-prohibited TCP control socket; the same compiled test classes passed through direct JUnit execution.
  • git diff --check — passed for direct gateway planning/contract milestone.
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew :app:testDebugUnitTest :app:assembleDebug from apps/mobile/android — passed for direct gateway planning/contract milestone.
  • Parent preflight immediately before B1 completion — script PASS; Android :app:assembleDebug BUILD SUCCESSFUL, 35 tasks total and 6 executed.
  • Parent preflight immediately before B1 completion — git diff --check passed.
  • git diff --check — passed
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew :app:testDebugUnitTest :app:assembleDebug from apps/mobile/android — passed
  • GRADLE_USER_HOME=/root/hermes-mobile/.gradle-user ./gradlew :app:assembleDebug from apps/mobile/android — passed
  • npm run typecheck --workspace @hermes-mobile/companion — passed
  • npm run lint --workspace @hermes-mobile/companion — passed
  • npm run build --workspace @hermes-mobile/companion — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npm run build — passed

Release history

No versioned APK releases yet.

Entry format

## [v0.1.0-beta.1] - YYYY-MM-DD

### Added
- Concise user-visible change.

### Changed
- Concise refinement or architectural change.

### Fixed
- Concise defect fix.

### Verification
- `command` — passed

### APK
- `hermes-mobile-v0.1.0-beta.1.apk` — Telegram release topic message <id>