• v0.1.3 8657e6afc6

    CI / Kotlin tests (android host + desktop) (push) Successful in 5m48s
    CI / Gateway plugin tests (push) Successful in 7m40s
    Stable

    ARIA released this 2026-08-31 21:44:41 +00:00 | 2 commits to master since this release

    Iris Release Notes — v0.1.3

    Covers the last 5 commits (b065d17 → 8657e6a).

    Bug Fixes

    HTTP fallback transport

    • Port-conflict pre-check now actually fires (8657e6a)
      acquire_scoped_lock returns (acquired, existing_record), but the old
      if not acquire_scoped_lock(...) tested the tuple — which is always
      truthy — so the "port in use by another profile" pre-check never ran and a
      conflict surfaced as a generic bind failure. The code now unpacks and tests
      the first element, matching the canonical usage in
      gateway/platforms/base.py.

    Gateway version reporting

    • Gateway no longer advertises unknown version in production installs
      (0f5b5a1)
      hermes plugins install <repo>#gateway-plugin ships only the
      gateway-plugin/ subdirectory into ~/.hermes/plugins/iris, so the
      repo-root VERSION file is absent there and plugin_version() fell back
      to unknown — causing the app to show a false "App and gateway versions
      differ" warning.
      • version.py: resolution chain is now repo-root VERSION (dev/symlink
        install) → plugin.yaml version field (production install) → unknown;
        stdlib-only parse, with a base= param for tests.
      • plugin.yaml: bumped stale 0.1.0 → 0.1.2 to match VERSION.
      • Added regression test simulating the production layout.

    App notifications

    • Fixed double notification + double unread count for cron deliveries
      (ea375fd)
      A cron delivery emits two frames (high-priority notification banner +
      message). When backgrounded, each posted its own system notification
      (Cron: <job_id> and the channel name), and the message frame's
      redelivery (live SSE + sync replay after the push-triggered reconnect)
      incremented the unread badge twice.
      • Records when a high-priority banner (cron/approval/clarify) was posted
        per lane; suppresses the message frame's system notification within a
        5 s window (mirrors the gateway's push-coalesce window).
      • Dedupes unread counting per lane by message id so a redelivered frame
        only counts once (recorded only when the message actually counts as
        unread).

    Documentation

    • Clarified ntfy privacy (b065d17)
      The docs claimed ntfy keeps push metadata on your own infrastructure, but
      the default NTFY_SERVER_URL is the public https://ntfy.sh cloud
      service. README.md, docs/08-push.md, docs/install.md, and
      docs/playstore-listing.md now make explicit that push metadata (topic,
      notification title) passes through ntfy.sh unless you self-host ntfy.

    • Refreshed AGENTS.md to match the current codebase (5b78e15)

      • Removed hardcoded ADB serial (differs per developer/machine).
      • Added the second pre-commit hook (check_version_sync) to hard rules.
      • Documented tests/, scripts/, backdrops/, and CI-SETUP.md in the
        layout.
      • Noted the committed tests/test_android.py copy and
        test_android_http.py.

    Tooling / Internal

    • New pre-commit hook: version sync guard (0f5b5a1)
      scripts/check_version_sync.sh (wired into .pre-commit-config.yaml)
      fails any commit where gateway-plugin/plugin.yaml version drifts from the
      repo-root VERSION file.

    Version

    • Bumped VERSION / plugin.yaml to 0.1.3 (8657e6a).
    Downloads
  • v0.1.2 fb980d12b4

    CI / Gateway plugin tests (push) Successful in 5m19s
    CI / Kotlin tests (android host + desktop) (push) Successful in 7m0s
    Stable

    ARIA released this 2026-08-25 13:15:38 +00:00 | 7 commits to master since this release

    v0.1.2

    ✨ Features

    • Release version management — single VERSION file at the repo root is now the source of truth; the release workflow reads it automatically (no manual input, with an empty-file guard).
    • App & gateway version reporting — the app shows its version in Settings (generated AppVersion.kt from VERSION) and sends it to the gateway via the X-Iris-App-Version header on SSE open; the gateway reports its own version in hello.ack (server_caps.app_version) and stores the app version in the device registry (merge, not overwrite).
    • Update hint in Settings — app + gateway version rows with a mismatch hint, plus a best-effort Gitea latest-release check with an "update available" badge.
    • Smooth streaming markdown — incremental parser (no full re-parse per snapshot) with a client-side typewriter reveal: steady reveal rate with rate-relative catch-up (jumps when backlog exceeds 2s), cursor drawn via annotator, and the streaming renderer stays alive until the reveal catches up.
    • New "Streaming speed" setting (0.2–0.8s) in Settings, persisted per device via SecureStore and live-updatable.
    • Thread topic chips ordered newest-first — the gateway now sends a created timestamp per channel/thread over the wire; the topic switcher sorts threads newest-first right beneath General (name as tie-break).

    🐛 Fixes

    • Pairing was impossible after iris setup — interactive_setup() generated a fresh IRIS_TOKEN and saved it to .env, but the local token variable was never updated, so the pairing URL/QR were built with an empty token. The generated value is now embedded in the pairing URL/QR. Regression test added.
    • Plugin install blocked by security scanner — the install-time scanner flagged test/dev fixtures in gateway-plugin/ (hardcoded tokens, /tmp paths, ~/.hermes/.env literal) as DANGEROUS ("19 findings"). Tests moved to top-level tests/, the .env path is now built at runtime, and the scanner verdict on gateway-plugin/ is SAFE (0 findings); fresh installs with scan enabled succeed.

    📚 Docs & Protocol

    • frames.schema.json and docs/04-wire-protocol.md updated for app_version and the thread created field.
    • docs/05-streaming.md documents the new rate mapping, catch-up, and wait-for-reveal semantics.
    • CI-SETUP.md, README, and docs updated for the new tests/ location and VERSION-based releases.
    Downloads
  • v0.1.1 c7a16d51e3

    CI / Gateway plugin tests (push) Successful in 4m55s
    CI / Kotlin tests (android host + desktop) (push) Successful in 6m58s
    Stable

    ARIA released this 2026-08-24 21:13:30 +00:00 | 12 commits to master since this release

    Changelog

    New features

    • Per-device tokens with revocation (#11) — Each paired device now receives its own token (delivered in hello.ack) instead of sharing the global IRIS_TOKEN. A leaked or compromised device can be isolated without rotating the shared token.
      • New operator CLI: tools/iris_devices.py (list / revoke / unrevoke / reissue)
      • hermes gateway setup now offers a "Remove a paired device?" menu
      • App stores the device token in the secure store and presents it from then on
    • TLS fingerprint-confirm flow for self-signed gateway certs (#14) — SSH-host-key-style flow: on first pairing against a self-signed cert, the app shows the SHA-256 fingerprint; "Confirm & pin" stores it (EncryptedSharedPreferences / desktop keyring) and allows the connection. Anything else is rejected. Pin is cleared on "forget device".
    • Self-signed TLS cert generation in hermes gateway setup — When IRIS_HTTP_CERT is not set, setup now offers to generate a 10-year RSA-2048 self-signed cert (with proper SANs) using hermes' existing cryptography dependency — no openssl needed. Prints the fingerprint in the format the app's confirm dialog expects; pairing URL/QR advertise https:// automatically.
    • Push backend defaults to ntfy (#10) — IRIS_PUSH_BACKEND now defaults to ntfy, keeping push metadata on your own infrastructure. FCM is opt-in (IRIS_PUSH_BACKEND=fcm) with a privacy warning during setup (metadata routed via Google's servers).

    Changes

    • HTTP-only transport cleanup — Renamed IRIS_WS_HOST → IRIS_HTTP_HOST (clean rename, no compat fallback); dropped dead DEFAULT_PORT=8790. ws_probe.py / e2e.py default to http://127.0.0.1:8791 and honor IRIS_HTTP_URL.
    • Refactor: split adapter.py monolith (#12) — The 3,493-line adapter.py is now ~857 lines plus focused modules (hooks, classify, pickers, commands, setup, secrets, and 7 frame-handler mixins). Ruff complexity ceilings restored to built-in defaults; genuinely complex functions carry explicit # noqa as frozen, reviewed exceptions.

    Fixes

    • README limit claims corrected to match reality (#13): uploads are 100 MB default (configurable via max_upload_bytes), and there is a 1 MiB hard frame-body cap (no 4,096-character limit like Telegram). Limits are set on the gateway side.

    Documentation

    • New end-to-end install guide (docs/install.md) for non-technical users: gateway install, app install, LAN/TLS/remote connection, push, options, troubleshooting.
    • README gained an "Install the gateway" section; pairing section updated for HTTP transport (port 8791, QR scan on Android).
    • Replaced stale "android" name mentions with "iris" across docs; fixed stale WS-era references in docs 03/09/12/19.
    • New docs/playstore-listing.md with the FCM/ntfy privacy note.

    Tests

    • 5 new Python tests for cert generation (incl. openssl fingerprint cross-check)
    • 8 new Python tests for per-device token issuance/revocation/isolation
    • New Kotlin TlsPinningTest + TlsPinningIntegrationTest (real TLS handshake: unpinned → confirm data, pinned → 200)
    • Live E2E verified on the phone: self-signed cert pairing, pinning, chat, auto-reconnect after gateway restart⏎
    Downloads
  • v0.1.0 70282dfb65

    First stable working Android version (Desktop still unpolished)
    CI / Gateway plugin tests (push) Successful in 4m55s
    CI / Kotlin tests (android host + desktop) (push) Successful in 6m48s
    Stable

    ARIA released this 2026-08-23 18:20:48 +00:00 | 21 commits to master since this release

    Release Notes — Iris × Hermes 0.1.0

    First public release. Iris is a native Android + desktop chat app for
    hermes-agent, built with Compose
    Multiplatform and paired with your own hermes gateway over a private WebSocket.
    Everything stays on your own infrastructure.

    Highlights

    • One codebase, two apps — native Android app and desktop app (Linux, macOS,
      Windows) sharing a single Kotlin/Compose codebase.
    • Telegram-quality chat experience — streaming replies, markdown rendering
      (tables, syntax-highlighted code, tap-to-copy), reasoning and tool activity
      shown in the bubble, media in both directions, search from everywhere.
    • Channels & threads — organize reports, cron jobs, and webhook output into
      channels; create threads manually or let the agent auto-thread topics.
    • Push notifications — FCM (primary) or ntfy (fallback), with offline
      catch-up and deduplication.
    • HTML artifact preview — agent-sent HTML/CSS/JS rendered in an in-app
      WebView (Android WebView / desktop JCEF).
    • Fully in-app settings — appearance, font size, streaming, tool/reasoning
      verbosity, and more; no hermes config.yml editing required.

    Gateway plugin (gateway-plugin/)

    • New hermes platform plugin (iris) with zero new Python dependencies and
      zero hermes-core changes; the app is a first-class hermes messaging platform
      (slash commands, cron delivery, send_message routing all work).
    • http SSE server with token pairing, outbox sync, and full channel/thread
      management (create/rename/favorite/icon/delete, hard deletes).
    • Push backends: FCM and ntfy; hello.ack reports the active backend so the
      app only runs its ntfy listener when needed.
    • Push dedupe: gateway tracks the highest outbox cursor delivered per device
      via push (devices.last_pushed_cursor); replayed frames at/below the
      watermark are not re-notified. 5s per-chat push coalescing.
    • Channel automation: channel.set_automation marks a channel read-only for
      cron/webhook output (composer hidden, message.send rejected, flag synced
      to all devices).
    • Official hermes-gateway status messages as a dedicated comment category.
    • MAX_MESSAGE_LENGTH raised to 1 MB so long replies and complete HTML
      artifacts are no longer chunked.
    • History frames omit null media (schema-conformant).

    Android app

    • Pairing flow (manual URL + token or QR Code), connection status bubble in the header.
    • Chat: streaming with toggle, markdown bubbles, single-newline preservation,
      timestamps + delivery checkmarks, back-to-bottom FAB, history pagination,
      long-press message selection and delete (synced to all devices).
    • Media upload/download/playback in both directions.
    • HTML artifact cards with full-screen WebView preview (DOM storage enabled).
    • Push: FCM handler + ntfy foreground listener (started/stopped based on the
      gateway's backend), background notifications.
    • Local message cache (SQLDelight) for instant start and offline reading.
    • Settings: appearance (bubble colors, background color/image), app-wide font
      scale (0.8x–1.5x), streaming and tool/reasoning display options.
    • Winged-bubble adaptive app icon.

    Desktop app

    • Two-pane layout, system tray, keyboard shortcuts, inspector, window icon.
    • Packaged via jpackage (app-image, or .deb with -PjpackageType=deb).

    Channels, threads & search

    • Channels: create, rename, favorite, change color/icon, delete (default
      channel is rename-only); flat Material star/heart badges; context menu on
      long-press/right-click; favorites and icons synced across devices.
    • Threading: topic switcher, Ctrl+T, auto-threading (default channel only).
    • Global message search.
    • Cron delivery to channels, including automation (read-only) channels with a
      tappable chat_id pill for delivery targeting.

    Quality, tooling & docs

    • Lint/LSP cleanup across gateway, Android, and desktop (alpha → stable).
    • Gitea CI + release workflows (builds APK and AAB; keystore guidance in
      CI-SETUP.md).
    • E2E test driver (gateway-plugin/tests/e2e.py) and WS probe; Python test
      suite for the gateway plugin; Kotlin host-side tests.
    • Numbered reference library in docs/ (start with 00-overview.md),
      frames.schema.json as the frame source of truth, security and setup docs.
    • User-facing README rewrite + Apache-2.0 LICENSE.

    Requirements

    • hermes-agent with the gateway (hermes gateway setup → hermes gateway).
    • Android: Android device + adb for development; JDK 17 for builds.
    • Desktop: Linux, macOS, or Windows.
    • Push: FCM requires google-services.json (optional — without it, ntfy is
      the push path; self-hosting ntfy is recommended).
    Downloads