RELEASE-NOTES.md
Rama main · réplica de lectura del repositorio original.
# Ethora SDK — Release Notes
## Legend
| Tag | Meaning |
|-----|---------|
| **New** | Brand new feature or component |
| **Improved** | Enhancement to existing functionality |
| **Fixed** | Bug fix |
| **Restored** | Previously available feature brought back |
| **Refactored** | Code restructuring (no user-facing change) |
| **Docs** | Documentation updates |
| **Testing** | Test coverage additions |
| **API** | Backend/API-facing change |
| **Milestone** | Version or release landmark |
---
## Week 45 (Nov 2 – 8, 2026) — Apps get outgoing webhooks and a send-as-user API; live updates move onto the chat connection and Centrifugo leaves the stack; agents can reply only when mentioned, per room; the MCP server publishes a server card and can hand over the App Secret
**Contributors:** Borys Bordunov, Yurii T., Dmytro Berberov, Roman Leshchuh, Taras Filatov
**Total commits:** 27 across public SDK/app repos + 63 platform/server (excluding submodule bumps and install-mirror syncs) | **Active repos:** 12
### Theme
A platform week. The first line is **integration**: an App can now register **outgoing webhooks** and receive a signed JSON event when a message is created, edited, deleted or left unread, when a user signs up, signs in or out, comes online or goes offline, and when a chat is created or deleted. The admin console has a **Webhooks tab** to add endpoints, pick events, send a test event, see the last delivery and rotate the signing secret. In the other direction, an integration backend can now **post a message into a chat as one of the App's users**, and clients render it exactly like a message the user typed.
The second line is **one connection instead of two**. The chat server now publishes its module events to a **Redis stream** that the platform consumes (events raised while the API restarts are handled once it is back), and the admin console takes its live App statistics and crawler progress from **events on the chat connection it already has open**. That let the team **remove Centrifugo** from the API, the admin console, every deploy form and the monitoring rules: one service fewer to run on every install.
The third line is **agents and the MCP server**. An agent in a group room can be set to **reply only when mentioned** (or smart, or always) for that room alone; the MCP server answers the **MCP Server Card** paths (SEP-2127) and the AI catalog, can **return the App Secret** to the App's owner on request so a script can provision an App end to end, and records usage events so the platform can see sessions and tool calls; the admin console, the consent page and the connector landing page offer **three starter prompts** for a freshly connected assistant.
Smaller items: the web and React Native SDKs treat a message the server already has as delivered (no false "Failed"), the React Native SDK waits longer for the server's ping and echo while it is busy with a burst of sends (26.11.1 and 26.11.2 published), the chat server caps the time a translation may take, and archiving a user or an App now also ends their open chat sessions.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 1 commit
- **Fixed:** **A message the server already holds counts as delivered.** When the chat server reports a resent message as a duplicate, the bubble is marked delivered instead of failing ([`d154cf0`](https://github.com/dappros/ethora-chat-component/commit/d154cf0))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 5 commits / 26.10.12 → 26.11.2
- **Fixed:** **No false "Failed" during a burst of sends.** The SDK waits longer for the server's ping reply and message echo while the server is busy with the user's own sends, so a slow moment no longer triggers a reconnect and a resend ([`c90efd1`](https://github.com/dappros/ethora-chat-component-rn/commit/c90efd1))
- **Fixed:** A resent message that the server reports as a duplicate is shown as delivered ([`a953fab`](https://github.com/dappros/ethora-chat-component-rn/commit/a953fab))
- **Improved:** Outgoing messages declare their language for translation only when translations are enabled for the App, the same rule as the web SDK, so an App without translation stores messages as typed ([`813aa93`](https://github.com/dappros/ethora-chat-component-rn/commit/813aa93))
- **Milestone:** **`@ethora/chat-component-rn` 26.11.1 (3 Nov) and 26.11.2 (4 Nov) published** ([`cf2a8d1`](https://github.com/dappros/ethora-chat-component-rn/commit/cf2a8d1), [`0d04356`](https://github.com/dappros/ethora-chat-component-rn/commit/0d04356))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 12 commits / branch 2610
- **New:** **App settings > Webhooks.** List the App's webhooks with status and last delivery or error, add and edit them (URL, description, events), send a test event, enable or disable, rotate the signing secret and delete; the signing secret is shown once, after creation and after rotation; labels for the message, user, presence, unread and chat events; strings in English, French and Spanish ([`15f1818`](https://github.com/dappros/ethora-app-reactjs/commit/15f1818), [`4f69d7c`](https://github.com/dappros/ethora-app-reactjs/commit/4f69d7c), [`e12106b`](https://github.com/dappros/ethora-app-reactjs/commit/e12106b), [`b0bc1f3`](https://github.com/dappros/ethora-app-reactjs/commit/b0bc1f3), [`341eae9`](https://github.com/dappros/ethora-app-reactjs/commit/341eae9))
- **New:** **Per-room agent reply mode.** An agent in a group room can reply only when mentioned, in smart mode or always, set for that room; the direct chat link text is neutral ([`a785309`](https://github.com/dappros/ethora-app-reactjs/commit/a785309))
- **New:** **Starter prompts on the AI Assistants tab:** three paste-ready first prompts next to the MCP endpoint, in English, French and Spanish ([`a1c348e`](https://github.com/dappros/ethora-app-reactjs/commit/a1c348e))
- **Improved:** **Live App statistics and crawler progress arrive on the chat connection.** The apps list updates its cards in place from server events and re-reads the list after a reconnect; the separate Centrifugo socket and its settings are gone ([`605ad66`](https://github.com/dappros/ethora-app-reactjs/commit/605ad66), [`aa2de6e`](https://github.com/dappros/ethora-app-reactjs/commit/aa2de6e))
- **Improved:** Password reset asks for the second factor on accounts that use MFA ([`e923522`](https://github.com/dappros/ethora-app-reactjs/commit/e923522))
- **Fixed:** Saving App settings no longer sends empty bot fields ([`7a85935`](https://github.com/dappros/ethora-app-reactjs/commit/7a85935))
- **Infrastructure:** The image's OS package layer is rebuilt daily ([`3a38d2c`](https://github.com/dappros/ethora-app-reactjs/commit/3a38d2c))
### MCP Server (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 7 commits on main (ships with the next hosted release)
- **New:** **MCP Server Card (SEP-2127) and AI catalog.** One card (registry name, version, the open, OAuth and personal-key entry points, icon, repository) answers `/mcp/server-card`, `/.well-known/mcp/server-card.json` and `/.well-known/ai-catalog.json`, with the extension media types, ETag and 304, and CORS; the discovery document points to it. ethora.com serves the same card and catalog ([`1f4a76b`](https://github.com/dappros/ethora-mcp-server/commit/1f4a76b))
- **New:** **`ethora-app-credentials-reveal` can return the App Secret** with `secret: true` (App owner only, `confirm: true` still required), so a script can provision an App and its backend integration end to end ([`81e8cc0`](https://github.com/dappros/ethora-mcp-server/commit/81e8cc0))
- **New:** **Usage events and starter prompts.** One event per session open and per tool call (tool, outcome, duration, client) is posted to the platform in batches, off the tool call's path; the connector landing page shows three starter prompts and the server instructions tell the model to offer them when a request is too vague to act on ([`73b0b6c`](https://github.com/dappros/ethora-mcp-server/commit/73b0b6c))
- **Improved:** `ETHORA_MCP_DOTENV_OVERRIDE` lets the rendered `.env` file take precedence over inherited environment on hosted installs, so an edited value reaches the process on the next restart; the stdio CLI is unchanged ([`576fa02`](https://github.com/dappros/ethora-mcp-server/commit/576fa02))
- **Infrastructure:** Placeholder values in the code and tests are built so directory scanners do not mistake them for credentials ([`be74a4c`](https://github.com/dappros/ethora-mcp-server/commit/be74a4c), [`30e4c6e`](https://github.com/dappros/ethora-mcp-server/commit/30e4c6e), [`0d4b35e`](https://github.com/dappros/ethora-mcp-server/commit/0d4b35e))
### Platform API & AI Service (`platform`)
> Platform API, AI service and push | 29 commits on release line 2610
- **New:** **App webhooks.** An App admin registers HTTPS endpoints and picks events; the platform signs and delivers a JSON payload for `message.created`, `message.updated`, `message.deleted`, `message.unread` (a member's first unread message in a room, 30 seconds after it arrives, checked against the read marker, muted members skipped), `user.created`, `user.login`, `user.logout`, `user.deleted`, `user.online`, `user.offline`, `chat.created` and `chat.deleted`. `GET/POST /v2/apps/:appId/webhooks`, `PATCH/DELETE /v2/apps/:appId/webhooks/:id` and `POST .../:id/test`; the latency of every delivery is logged.
- **New:** **Send a message on behalf of a user.** `POST /v2/apps/:appId/chats/:chatId/messages` with a server token posts into a chat as one of the App's users (`fromUserId`, `text`, optional `messageId` and `metadata`); the message comes from the user's own address, so every client shows it as the user's own, and it goes through the usual archive, last-message and push processing. The user does not need to be online.
- **New:** **Per-room agent reply mode:** `POST /v2/bot-instances/:id/status` takes `roomResponseMode: { chatJid, responseMode }` (mentioned, smart or always); the agent-wide mode stays the default, the room setting overrides it there only, and leaving the room clears it.
- **New:** **MCP usage events** are recorded by the platform with the assistant client's name and appear as a section in the weekly report; the OAuth consent page shows starter prompts.
- **Improved:** **Live updates over the chat server.** App statistics (summed over five seconds) and crawler progress are sent to the App's owner as events on their chat session; the platform consumes the chat server's event stream in its jobs runner; the Centrifugo client is removed.
- **Improved:** **Archiving a user or an App also ends their open chat sessions**, and restoring reopens access (for an App, across all its users in the background); the message archive keeps the chat server's own time as the message time and scopes duplicate detection to the App and the chat.
- **Improved:** Invalid ids, failed validation and upload errors are answered with a 4xx status; a message sent while the AI service reconnects to the chat server no longer stops the service.
- **Infrastructure:** The rendered `.env` takes precedence over inherited environment in the API, the AI service and the push service; images rebuild their OS package layer daily.
### Chat Server & Deployment (`platform`)
> Chat server, installers, images and monitoring | 34 commits
- **New:** **Chat server events to a Redis stream.** When `redis_server` is set, the custom modules publish their events to a stream the platform consumes, instead of one HTTP request each; without it the same callbacks work as before. Callbacks to the platform no longer run on the room or session process.
- **New:** **Presence events:** a new module reports a user's first session opening and last session closing (feeding the `user.online` / `user.offline` webhooks); edit and delete stanzas are no longer archived as messages.
- **Improved:** **App isolation is enforced in the production configuration**, and the service directory lists only the App's own items.
- **Improved:** **Translation never holds up a conversation:** the time a translation may take is capped (8 s by default), a message resent while its first copy is still being translated is dropped instead of reaching readers twice, the sender is told when a duplicate is dropped, and translation runs after duplicate detection (on the 2610 and 2609 lines).
- **Fixed:** The author of a room message no longer receives a push for it.
- **Changed:** **Centrifugo removed from every deploy form**; ejabberd is pointed at Redis for its event stream; the presence module is rendered by the installer and App webhooks are documented for operators.
- **Improved:** Cloudron, Umbrel and CasaOS packages pinned to images 2610.71; every image rebuilds its OS package layer daily; the release-image checks fail on a missing frontend or widget value and verify the generated secrets; a local stack can be built from the checkout's own submodules.
- **Improved:** Team members can issue their own internal test licences.
- **New:** Monitoring alerts for AI provider failures (a rejected API key, repeated failed model calls); the core-container rules no longer expect Centrifugo.
- **Docs:** Archiving closes API and chat access, not only sign-in.
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 1 commit (plus daily submodule bumps)
- **Docs:** Week 44 release notes ([`96c7f0e`](https://github.com/dappros/ethora/commit/96c7f0e))
---
## Week 44 (Oct 26 – Nov 1, 2026) — Version 26.11 is cut; calls go peer to peer and reach group rooms, and can be scheduled into a calendar; the Android, Swift and Flutter SDKs catch up with the web; agents write their own flows and collect submissions; Apps are isolated from each other on the chat server
**Contributors:** Roman Leshchuh, Dmytro Berberov, Borys Bordunov, Yurii T., Taras Filatov
**Total commits:** 33 in the week across public SDK/app repos + 94 merged on Oct 26 from the calls and web-parity feature branches (authored Oct 16 – 22) + 47 platform/server (excluding submodule bumps and install-mirror syncs) | **Active repos:** 16
### Theme
The week opened with the merge of a month of feature-branch work. **Calls** are the first line: a 1:1 call now runs **peer to peer** over the clients' own WebRTC connection when the server says so, with TURN and STUN servers handed out by the platform (and a TURN server the installer can run next to the stack), while **group calls** in members-only rooms run over LiveKit with a grid of everyone in the room. A call can also be **scheduled**: a "Schedule call" button in the chat header books a call with a title, time and duration, every member gets an invite card with Google Calendar, Outlook and .ics links, a reminder push goes out before the start, and a `/call/<slug>` join link opens a pre-join screen (camera and microphone stay off until "Join call") on the web, in the installed web app and in the mobile app through universal links. The same calls, booking and report fixes shipped in the web SDK (26.10.8 – 26.10.10) and the React Native SDK (26.10.11 – 26.10.12).
The second line is **parity across the native SDKs**. The Android and Swift SDKs received the current web feature set in one merge each (calls, encrypted rooms with sealed attachments, albums and multi-file messages, delivery and read receipts, reactions and threads, message search and jump, room management and the public chats directory, push registration and credential recovery, message translation, a dark palette, and a side-by-side layout on tablets and iPad), and a **Flutter SDK** repository went public with the same set ported, including calls, push and a production example app.
The third line is **agents and administration**. In the admin console an agent's flow can now be **generated with AI**, previewed on a map and tried in a simulator; completed flow runs are recorded as **submissions** with a webhook, a pull API, CSV export and a retention setting; the apps list gained search, a last-activity sort and an Inactive count; an App's chat component look is edited with a **live preview** and applied to open chats without a reconnect; and an admin can **invite colleagues** to manage an App, with an onboarding checklist and a shareable link that opens a private chat with an agent. On the chat server, **Apps are now isolated from each other on XMPP** (no stanza crosses between Apps, federation is off), rooms are hidden from directory discovery by default with a migration for existing rooms, and busy widget agents leave quiet visitor rooms and come back when the visitor does.
**Milestone:** **Version 26.11 was tagged on Nov 1** (`v26.11` on the monorepo, `@ethora/mcp-server` 26.11.0). Production stays on the 2610 line for now; no 2611 iteration branch has been opened yet.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 16 commits in the week + 16 merged from the calls branch / 26.10.7 → 26.10.10
- **New:** **Peer-to-peer 1:1 calls and group calls.** A 1:1 call runs over the clients' own WebRTC connection when the server answers `mode=p2p`: offer, answer, ICE candidates and hang-up travel as direct chat messages, TURN/STUN servers come from the platform and are refreshed before an ICE restart, and the peer's avatar is shown when they turn the camera off. Members-only group rooms get the call buttons and run over LiveKit with a grid layout. The LiveKit URL, ICE list and caller's name are taken only from the App's system account, and the caller's display name is shown instead of a raw chat name ([`a67663c`](https://github.com/dappros/ethora-chat-component/commit/a67663c), [`2c08b73`](https://github.com/dappros/ethora-chat-component/commit/2c08b73), [`7f53e53`](https://github.com/dappros/ethora-chat-component/commit/7f53e53), [`0ec8a13`](https://github.com/dappros/ethora-chat-component/commit/0ec8a13), [`e51a13f`](https://github.com/dappros/ethora-chat-component/commit/e51a13f), [`d563793`](https://github.com/dappros/ethora-chat-component/commit/d563793), [`b9210b1`](https://github.com/dappros/ethora-chat-component/commit/b9210b1), [`175eb40`](https://github.com/dappros/ethora-chat-component/commit/175eb40), [`13faef5`](https://github.com/dappros/ethora-chat-component/commit/13faef5), [`76a30fd`](https://github.com/dappros/ethora-chat-component/commit/76a30fd))
- **New:** **Scheduled calls (booking).** A "Schedule call" button next to the call buttons opens a form (title, date and time, duration, video or audio, description); every member sees one invite card per call (upcoming, open to join from 15 minutes before the start, ended or cancelled) with Google Calendar, Outlook and .ics links, Join, and Edit and Cancel for the creator and the room owner. Join opens a pre-join panel; nothing uses the camera or microphone until "Join call". `scheduledCallSlug`, `openScheduledCall(slug)` and `parseScheduledCallLink(url)` open a call from a `/call/<slug>` link; `config.scheduledCalls` controls the feature; strings in en, fr, es, pt, ht and zh ([`88e4a34`](https://github.com/dappros/ethora-chat-component/commit/88e4a34), [`cc1ae0b`](https://github.com/dappros/ethora-chat-component/commit/cc1ae0b))
- **New:** **Live chat component config.** `config.remoteAppearance: { appId }` makes the chat read the App's saved look at start and again whenever the server announces a new version, applying colours, typography, background and the display switches to the open chat without reconnecting; `onChatComponentConfigUpdated` lets a host that fetches the config itself refetch ([`6d6f11f`](https://github.com/dappros/ethora-chat-component/commit/6d6f11f), [`eb3205f`](https://github.com/dappros/ethora-chat-component/commit/eb3205f))
- **New:** **Edit a group or public chat's name, description and picture** from the chat profile, with moderator actions in the profile (report and leave hidden for moderators) and room labels kept stable while metadata refreshes ([`530f09a`](https://github.com/dappros/ethora-chat-component/commit/530f09a), [`b129286`](https://github.com/dappros/ethora-chat-component/commit/b129286), [`c48b443`](https://github.com/dappros/ethora-chat-component/commit/c48b443), [`789ac60`](https://github.com/dappros/ethora-chat-component/commit/789ac60))
- **New:** `useXmppClient` is exported and a room's access is checked through `disco#info` before a shared link opens it; the push token is registered with the reader's language so push texts follow it ([`d0e3652`](https://github.com/dappros/ethora-chat-component/commit/d0e3652), [`31982f6`](https://github.com/dappros/ethora-chat-component/commit/31982f6))
- **Improved:** **An explicit leave of a configured App room now sticks** across reconnects and sign-ins; the new `removable` policy on a configured room decides whether Leave is offered at all ([`88044a3`](https://github.com/dappros/ethora-chat-component/commit/88044a3))
- **Fixed:** **Reporting a chat works again**: the report sends the server's category values and a non-empty text, with a toast for the outcome ([`917f860`](https://github.com/dappros/ethora-chat-component/commit/917f860))
- **Fixed:** A call no longer hangs on after the other side drops it, and a late signal from an earlier call in the same room no longer ends the current one; an incoming call stops ringing after 45 s and a dial nobody joins ends with "No answer" (part of the calls merge)
- **Fixed:** Forced removal from a room is handled, presence and profile flows after membership changes, the group modal and member menu, a chat profile crash after its room was deleted, square avatar cropping before upload (with cancel and full-resolution output) and the chat profile layout for long names, and shared chat links that now open reliably in the same tab ([`1d2481e`](https://github.com/dappros/ethora-chat-component/commit/1d2481e), [`3158403`](https://github.com/dappros/ethora-chat-component/commit/3158403), [`893093e`](https://github.com/dappros/ethora-chat-component/commit/893093e), [`00fbf79`](https://github.com/dappros/ethora-chat-component/commit/00fbf79), [`65fdafd`](https://github.com/dappros/ethora-chat-component/commit/65fdafd), [`b3de5b1`](https://github.com/dappros/ethora-chat-component/commit/b3de5b1))
- **Milestone:** **`@ethora/chat-component` 26.10.8 (28 Oct), 26.10.9 (29 Oct) and 26.10.10 (30 Oct) published** ([`1033630`](https://github.com/dappros/ethora-chat-component/commit/1033630), [`8cf8f8b`](https://github.com/dappros/ethora-chat-component/commit/8cf8f8b), [`351fb00`](https://github.com/dappros/ethora-chat-component/commit/351fb00))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 3 commits in the week + 9 merged from the calls branch / 26.10.10 → 26.10.12
- **New:** **1:1 calls over peer-to-peer WebRTC and group calls over LiveKit**, ported from the web SDK: rings, CallKit and ConnectionService screens and VoIP pushes work for both; a phone already in a call declines a second one to its caller; group rooms get the call buttons (`videoCalls.allowedRoomTypes` defaults to private and group) and a call grid with the speaker outlined ([`a8c5401`](https://github.com/dappros/ethora-chat-component-rn/commit/a8c5401), [`474192b`](https://github.com/dappros/ethora-chat-component-rn/commit/474192b), [`762a86e`](https://github.com/dappros/ethora-chat-component-rn/commit/762a86e))
- **New:** **Scheduled calls and deep links:** a Schedule a call button and sheet, an invite card per call with Add to Google / Outlook / .ics, a pre-join sheet, reminder pushes routed to the call, and `/call/<slug>` links parsed from universal links and the custom scheme (with `hosts` and `schemes` to narrow them) ([`be9a95d`](https://github.com/dappros/ethora-chat-component-rn/commit/be9a95d), [`0c31afe`](https://github.com/dappros/ethora-chat-component-rn/commit/0c31afe), [`c1cbaa2`](https://github.com/dappros/ethora-chat-component-rn/commit/c1cbaa2))
- **New:** **The install's translation languages** (`config.translates.languages` from `get-config`) drive the globe picker and the language settings; the push token carries the reader's language; the **app icon badge follows the unread count in the foreground** ([`c947587`](https://github.com/dappros/ethora-chat-component-rn/commit/c947587))
- **Fixed:** Reporting a chat sends a server-valid category and a non-empty reason; an explicit leave of a configured App room sticks; the Android keyboard in the chat ([`8cfad5b`](https://github.com/dappros/ethora-chat-component-rn/commit/8cfad5b), [`0f3fe25`](https://github.com/dappros/ethora-chat-component-rn/commit/0f3fe25), [`d2abe16`](https://github.com/dappros/ethora-chat-component-rn/commit/d2abe16))
- **Testing:** `deleteMe` sends the token header ([`a13533a`](https://github.com/dappros/ethora-chat-component-rn/commit/a13533a))
- **Milestone:** **`@ethora/chat-component-rn` 26.10.11 (26 Oct) and 26.10.12 (31 Oct) published**
### Android SDK (`sdk-android`)
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android) | 22 commits merged from the web-parity branch
- **New:** **The current web chat feature set on Android, in one merge:** 1:1 audio and video calls with the web signalling, peer-to-peer 1:1 calls, group calls with a grid, audio routing, a foreground service and an incoming-call notification; OMEMO 2 end-to-end encryption for rooms marked `e2ee` with sealed attachment uploads and the web's known-answer vectors as tests; multi-file messages with secure file tokens, an album grid and a multi-file composer; delivery receipts and read markers; reactions, reply threads and a thread panel; message search and jump to message; room management, the public chats directory, room reports and member management; device push registration, token refresh and XMPP credential recovery; message translation, UI captions and account settings; and the web dark palette with `colorScheme` and font size config ([`6342943`](https://github.com/dappros/ethora-sdk-android/commit/6342943), [`c30e107`](https://github.com/dappros/ethora-sdk-android/commit/c30e107), [`f75779a`](https://github.com/dappros/ethora-sdk-android/commit/f75779a), [`e543402`](https://github.com/dappros/ethora-sdk-android/commit/e543402), [`f86249d`](https://github.com/dappros/ethora-sdk-android/commit/f86249d), [`d852dfd`](https://github.com/dappros/ethora-sdk-android/commit/d852dfd), [`ff9c3d9`](https://github.com/dappros/ethora-sdk-android/commit/ff9c3d9), [`668c259`](https://github.com/dappros/ethora-sdk-android/commit/668c259), [`1a202a3`](https://github.com/dappros/ethora-sdk-android/commit/1a202a3), [`4bb62f1`](https://github.com/dappros/ethora-sdk-android/commit/4bb62f1), [`ec11151`](https://github.com/dappros/ethora-sdk-android/commit/ec11151), [`b8cddb7`](https://github.com/dappros/ethora-sdk-android/commit/b8cddb7), [`fbeddac`](https://github.com/dappros/ethora-sdk-android/commit/fbeddac), [`018e8a1`](https://github.com/dappros/ethora-sdk-android/commit/018e8a1), [`57b0e88`](https://github.com/dappros/ethora-sdk-android/commit/57b0e88), [`6d998f9`](https://github.com/dappros/ethora-sdk-android/commit/6d998f9))
- **Testing:** Unit tests for reaction stanzas, thread helpers and the reaction store; a two-device OMEMO round trip ([`3889445`](https://github.com/dappros/ethora-sdk-android/commit/3889445), [`2457121`](https://github.com/dappros/ethora-sdk-android/commit/2457121))
- **Infrastructure:** The build root can be overridden with `ETHORA_BUILD_ROOT`; hex colours parsed and palette colours mixed without Android dependencies ([`95c35d5`](https://github.com/dappros/ethora-sdk-android/commit/95c35d5), [`f5da8d3`](https://github.com/dappros/ethora-sdk-android/commit/f5da8d3))
### Swift SDK (`sdk-swift`)
> [ethora-sdk-swift](https://github.com/dappros/ethora-sdk-swift) | 23 commits merged from the web-parity branch
- **New:** **The current web chat feature set on iOS, in one merge:** 1:1 call signalling with a call overlay, active-call screen and header buttons, peer-to-peer 1:1 calls, group calls over LiveKit with a CallKit bridge and in-call controls; OMEMO 2 end-to-end encryption ported from the web; multi-file send and receive with secure file tokens, a multi-file composer and album tap index; delivery receipts, read markers, typing and send states; reactions, reply quotes, a thread panel and edit/delete polish; message search with a search sheet and jump to message; `ethora-event` headlines, membership and room REST parity, the public chats directory, room reports and member management, a system message pill and a gated mute swipe; push registration, refresh rotation and XMPP credential recovery; i18n tables, message translation and account settings; `colorScheme`, typography and the web dark palette; and a **side-by-side room list and chat on iPad** ([`64fee18`](https://github.com/dappros/ethora-sdk-swift/commit/64fee18), [`27a207d`](https://github.com/dappros/ethora-sdk-swift/commit/27a207d), [`72d0a94`](https://github.com/dappros/ethora-sdk-swift/commit/72d0a94), [`e8c27d7`](https://github.com/dappros/ethora-sdk-swift/commit/e8c27d7), [`5ef6d9a`](https://github.com/dappros/ethora-sdk-swift/commit/5ef6d9a), [`8b7a5d1`](https://github.com/dappros/ethora-sdk-swift/commit/8b7a5d1), [`af2e49f`](https://github.com/dappros/ethora-sdk-swift/commit/af2e49f), [`0342136`](https://github.com/dappros/ethora-sdk-swift/commit/0342136), [`84e95df`](https://github.com/dappros/ethora-sdk-swift/commit/84e95df), [`e7e0554`](https://github.com/dappros/ethora-sdk-swift/commit/e7e0554), [`37df27c`](https://github.com/dappros/ethora-sdk-swift/commit/37df27c), [`556b20a`](https://github.com/dappros/ethora-sdk-swift/commit/556b20a), [`0b6b29f`](https://github.com/dappros/ethora-sdk-swift/commit/0b6b29f), [`81894dd`](https://github.com/dappros/ethora-sdk-swift/commit/81894dd), [`c3151fe`](https://github.com/dappros/ethora-sdk-swift/commit/c3151fe), [`8eeb780`](https://github.com/dappros/ethora-sdk-swift/commit/8eeb780), [`2c7357e`](https://github.com/dappros/ethora-sdk-swift/commit/2c7357e), [`21ac2be`](https://github.com/dappros/ethora-sdk-swift/commit/21ac2be), [`e235c89`](https://github.com/dappros/ethora-sdk-swift/commit/e235c89))
- **Testing:** Signalling round-trip and call state tests; unit tests for `ethora-event`, membership, lookup and invites; attachment, secure URL, upload route and stanza attribute coverage ([`4422505`](https://github.com/dappros/ethora-sdk-swift/commit/4422505), [`256d3c8`](https://github.com/dappros/ethora-sdk-swift/commit/256d3c8), [`c7d8c7a`](https://github.com/dappros/ethora-sdk-swift/commit/c7d8c7a))
### Flutter SDK (`sdk-flutter`)
> [ethora-sdk-flutter](https://github.com/dappros/ethora-sdk-flutter) | new public repository, 10 commits merged from the web-parity branch
- **Milestone:** **A Flutter chat SDK with the web feature set.** An XMPP runtime built like the web's (SASL with resource bind, the web stanza parser for edits, deletes, reactions, receipts and typing, archive cursors, de-duplication, a send watchdog with tap to retry, secure credential storage); reactions, reply threads, edit and delete, delivery and read ticks; multi-file messages with an album grid, viewer and secure file URLs; search and jump to message, room swipe actions, the public chats directory and member management; light, dark or system scheme, a tablet split layout, six built-in languages and message translation; refresh-token rotation, credential recovery, change password, export and delete account; push registration and MucSub subscriptions with call push wake-up; and audio and video calls over LiveKit and peer-to-peer WebRTC, off by default, with CallKit, tones and screen share. Ships with a CHANGELOG, a README calls section and a production example app ([`0cd941a`](https://github.com/dappros/ethora-sdk-flutter/commit/0cd941a), [`e4f7a28`](https://github.com/dappros/ethora-sdk-flutter/commit/e4f7a28), [`1aa7ea4`](https://github.com/dappros/ethora-sdk-flutter/commit/1aa7ea4), [`f56fd4e`](https://github.com/dappros/ethora-sdk-flutter/commit/f56fd4e), [`1f24082`](https://github.com/dappros/ethora-sdk-flutter/commit/1f24082), [`d388635`](https://github.com/dappros/ethora-sdk-flutter/commit/d388635), [`554084b`](https://github.com/dappros/ethora-sdk-flutter/commit/554084b), [`b14b269`](https://github.com/dappros/ethora-sdk-flutter/commit/b14b269), [`99f410a`](https://github.com/dappros/ethora-sdk-flutter/commit/99f410a), [`8ea5f57`](https://github.com/dappros/ethora-sdk-flutter/commit/8ea5f57))
### Ethora Mobile App (`app-react-native`)
> [ethora-app-react-native](https://github.com/dappros/ethora-app-react-native) | 3 commits in the week + 1 merged / branch new-project
- **New:** **Scheduled calls open from universal links, the custom scheme and reminder pushes** ([`ac7029f`](https://github.com/dappros/ethora-app-react-native/commit/ac7029f))
- **Fixed:** A launch crash on Android, a splash screen with the app logo, pushes that stop after sign-out, Android fixes, and the SDK bumped to 26.10.12 ([`ce21f9f`](https://github.com/dappros/ethora-app-react-native/commit/ce21f9f), [`12554ad`](https://github.com/dappros/ethora-app-react-native/commit/12554ad), [`85e3b80`](https://github.com/dappros/ethora-app-react-native/commit/85e3b80))
### Ethora Web App, installable (`pwa`)
> Live at pwa.chat.ethora.com | 1 commit
- **Fixed:** Session cleanup on sign-out and back navigation in the installed app.
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 3 commits / 26.10.1 → 26.10.30
- **Fixed:** **The opening greeting stays at the beginning** of a restored conversation when a visitor reloads or moves between pages; the launcher is drawn from the cached appearance at once and refreshes its settings in the background ([`3cd7a67`](https://github.com/dappros/ethora-ai-chat-widget/commit/3cd7a67))
- **Fixed:** **A visitor who comes back to a panel left open** (reopening it, returning to the tab, typing) renews the session in the background, at most every five minutes, so the agent is back in the conversation after the server let a quiet room go; the same visitor and room are kept ([`77a5377`](https://github.com/dappros/ethora-ai-chat-widget/commit/77a5377))
- **Milestone:** **Widget 26.10.30 released (30 Oct)** ([`667720c`](https://github.com/dappros/ethora-ai-chat-widget/commit/667720c))
### WordPress Plugin (`wp-plugin`)
> [ethora-wp-plugin](https://github.com/dappros/ethora-wp-plugin) | 1 commit / 1.8.1
- **Milestone:** **Plugin 1.8.1 bundles widget 26.10.30**: the greeting stays at the start after a reload or navigation, and the launcher uses cached appearance while the latest settings load ([`0680a57`](https://github.com/dappros/ethora-wp-plugin/commit/0680a57))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 5 commits in the week + 13 merged from the admin branch / branch 2610
- **New:** **Flows written by AI.** Describe what an agent should do and the console generates a flow, shows it on a map and lets you try it in a simulator before it goes live; flow lines are numbered for edits ([`9b5c1c1`](https://github.com/dappros/ethora-app-reactjs/commit/9b5c1c1), [`9c7a8f5`](https://github.com/dappros/ethora-app-reactjs/commit/9c7a8f5))
- **New:** **Submissions.** Every completed flow run is recorded; a Submissions tab lists them (as cards on phones), sends them to a webhook with a retry count, exports CSV, and keeps them for a retention period you set ([`6901618`](https://github.com/dappros/ethora-app-reactjs/commit/6901618), [`fd73970`](https://github.com/dappros/ethora-app-reactjs/commit/fd73970), [`8779477`](https://github.com/dappros/ethora-app-reactjs/commit/8779477))
- **New:** **Chat component appearance editor with a live preview**, and the console's own chat follows the saved config live without a restart ([`29211e8`](https://github.com/dappros/ethora-app-reactjs/commit/29211e8), [`781c5f9`](https://github.com/dappros/ethora-app-reactjs/commit/781c5f9))
- **New:** **Agent onboarding:** a setup checklist for a new agent, invites for colleagues to manage the App, and a shareable link that opens the signed-in user's own private chat with the agent; shared chat links join and open in place after sign-in, with an explanation when a chat is private or missing, a next step for the owner, and a mention-only toggle for an agent in a room ([`0a26e98`](https://github.com/dappros/ethora-app-reactjs/commit/0a26e98), [`82348aa`](https://github.com/dappros/ethora-app-reactjs/commit/82348aa), [`8bb2841`](https://github.com/dappros/ethora-app-reactjs/commit/8bb2841))
- **New:** **Calls and scheduling in group rooms**, a `/call/:slug` join page with a return path after sign-in, and the app link files served from `/.well-known` so phone links open the app ([`c5fd843`](https://github.com/dappros/ethora-app-reactjs/commit/c5fd843), [`b588ef8`](https://github.com/dappros/ethora-app-reactjs/commit/b588ef8), [`46051b5`](https://github.com/dappros/ethora-app-reactjs/commit/46051b5))
- **New:** The apps list has search, a last-activity sort and an Inactive stat ([`36a7f10`](https://github.com/dappros/ethora-app-reactjs/commit/36a7f10))
- **Fixed:** Dark mode contrast in the admin pages, the avatar edit control (initial stays visible, control on hover or focus, image type preserved), and the app view in chat users ([`d8b5ef2`](https://github.com/dappros/ethora-app-reactjs/commit/d8b5ef2), [`693f0aa`](https://github.com/dappros/ethora-app-reactjs/commit/693f0aa), [`6da6349`](https://github.com/dappros/ethora-app-reactjs/commit/6da6349))
- **Infrastructure:** Chat SDK bumped to 26.10.7 ([`71f0d77`](https://github.com/dappros/ethora-app-reactjs/commit/71f0d77))
### MCP Server (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 1 commit / 26.11.0 tagged
- **Milestone:** **`@ethora/mcp-server` 26.11.0 tagged on Nov 1** with the October work in its release notes (agents and widget tools, web index refresh tools, account memory, the ChatGPT plugin package and review materials, explicit annotation hints on every tool); the npm publish follows the tag ([`01c9ffb`](https://github.com/dappros/ethora-mcp-server/commit/01c9ffb))
### Platform API & AI Service (`platform`)
> Platform API, AI service and push | 14 commits in the week + 18 merged from the calls and flows branch, on release lines 2610 and 2609
- **New:** **Peer-to-peer 1:1 calls with TURN/ICE and group calls over LiveKit.** The call-token carries the call mode, the platform's own LiveKit URL and the caller's name; `GET /v1/calls/ice-servers` hands out the TURN and STUN list; call pushes carry the mode and group fields.
- **New:** **Scheduled calls** in chat rooms (`POST /v1/chats/calls/scheduled`, announced in the room with calendar and .ics links built by the server), a `scheduledCallReminder` push type and `POST /api/v2/push/scheduled-call` for the reminder, with the reminder's title and a localised sealed fallback.
- **New:** **Per-App chat component config** with licence-gated options, versioned on save, with online clients told about the new version.
- **New:** **Agent flows:** generate, simulate and map endpoints, a flow simulator and flow drafts in the AI service; completed runs recorded as **submissions** with a webhook, a pull API and CSV, attempt counts kept on manual sends, old submissions purged daily. A trigger phrase that appears inside an answer no longer restarts a flow.
- **New:** **App collaborators:** invite a colleague by email to manage an App with a role, list who manages it and remove access (`POST/GET/DELETE /v2/apps/:appId/collaborators`); a caller grants only what they administer themselves, and new accounts count against the licence's user cap.
- **New:** `POST /v2/agents/:idOrAddress/my-chat` returns the signed-in user's own private chat with an agent, behind the chat app's shareable `/agent/<address>` link; archived users are no longer listed as members of group rooms, and server tokens can remove members from the App's own chats.
- **New:** Search and last activity on `GET /v1/apps`; Gemma compatibility on the OpenAI-compatible model endpoint.
- **Improved:** **Widget agents stay under the chat server's room limit:** a bot leaves quiet visitor rooms after an idle period, caps the rooms it holds, rejoins its live rooms after a reconnect, and on a resumed visitor session reads the room's tail so a message sent while it was away is answered.
- **Improved:** A deep crawl of a documentation site is scoped to the seed page's section (a seed that points at a single document now reaches its siblings), and overlay removal is no longer applied, which keeps content extraction working on JS-heavy sites.
- **Fixed:** **Unread counts exclude the message the reader has just viewed** in both forms of the read marker, so badges are no longer one too high; generic push texts count the unread messages ("You have received N new messages") in English, French and Spanish, and a device language without fixed texts falls back to the profile language, then English.
- **Fixed:** A widget session returns the room's creation time so the client keeps the opening greeting before restored messages, and a failed appearance lookup is no longer cached as an empty look; the creator's other signed-in devices receive the invite when a group room is created; `DELETE /v1/chats` documented as the owner-scoped delete it is.
- **Infrastructure:** The error tracker no longer reports connection failures to the install's own services (a redeploy of the databases no longer floods it).
### Chat Server & Deployment (`platform`)
> Chat server, installers, images and monitoring | 15 commits
- **New:** **Apps are isolated from each other on the chat server.** No message, presence or iq crosses between Apps (users and rooms alike, including room subscriptions and archives); an anonymous session reaches only its own address; the unused MQTT listener and user search are gone. `isolation_mode: log | enforce` (enforce by default; production ships with log for a first rollout). **XMPP federation is off:** outbound server-to-server connections are refused and the s2s listener is removed, since nothing in the deployment or the clients uses it.
- **Improved:** **Rooms are hidden from directory discovery by default** (`public: false`, `public_list: false`), so a room is reached by its address and its member list is not shown to non-members. Existing rooms are migrated on the next update (through the chat server's HTTP API with parallel workers, so a stack with ~12k rooms migrates in minutes instead of hours) and, for container installs that never run the update script, in the init step on each start.
- **New:** **A TURN server for peer-to-peer calls:** `services.coturn` in `deploy.yml` runs coturn next to the stack, derives the URLs, generates the secret once and writes the TURN settings to the API; coturn accepts its own address as a relay peer; the compose bundle gains a calls module.
- **Improved:** **One install or update at a time:** a lock in the deploy state keeps a second `install.sh` or `update.sh` from overlapping the first, and every `.deploy.env` writer renames a temp file over the original so no reader sees it half written; restoring multi-line secrets is documented.
- **Changed:** The SDK playground is off by default and, when enabled, runs as the App named in `deploy.yml` with its own credentials.
- **New:** **Monitoring alerts when a core container is missing or restarted:** a database, cache, object store, chat server or realtime container that Docker stops listing for over five minutes raises a critical alert, and more than one restart in 15 minutes a warning; the chat server is left out of the restart rule because every update restarts it.
- **Docs:** The per-bot room cap settings (`AI_BOT_MAX_ACTIVE_ROOMS`, `AI_BOT_ROOM_IDLE_SEC`, `AI_BOT_CATCHUP_MAX_AGE_SEC`) in the AI service templates and the operator notes; App isolation and the federation switch in the platform overview and the 2610 notes.
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 1 commit (plus daily submodule bumps)
- **Docs:** Week 43 release notes ([`84abd8e`](https://github.com/dappros/ethora/commit/84abd8e))
- **Milestone:** **`v26.11` tagged on Nov 1** (GitHub release "v26.11")
---
## Week 43 (Oct 19 – 25, 2026) — The Ethora app installs from the browser; pushes that can stay generic, ring a call on the web or carry a reaction; blocking reaches group chats; a PHP SDK for server integrations takes shape
**Contributors:** Roman Leshchuh, Borys Bordunov, Dmytro Berberov, Yurii T., Taras Filatov
**Total commits:** 55 across SDK/app repos + 25 in the new installable web app + 33 platform/server (excluding automated submodule bumps and install-mirror syncs) | **Active repos:** 14
### Theme
A quieter week by volume and a busy one for **notifications**. On the platform, an App can now choose a **generic push content mode**: every chat push then says only "New message", with no text, names or pictures, and child Apps inherit the setting from their parent, so one switch covers a whole tenant. Pushes learned three new things in the same days: a **push for a reaction** to your message (silent, rate limited per sender, never replacing the chat's message notification, and switchable per install), the **sender's avatar** next to the text the way messengers show it, and fixed texts in the **device's own language** (English, French, Spanish). The unread total behind the app badge stopped counting the message you had just read.
The web chat SDK caught up on the same surface: **incoming call pushes on the web ring like on mobile**, with Answer and Decline on a sticky notification even when the tab is hidden, a "Missed call" when the ring has gone stale, and one tab acting for all of them. The React Native SDK took **incoming calls from VoIP pushes** on iOS (CallKit, never ringing twice) and from a host's call notification on Android, plus sender avatars and reaction pushes.
The second line was a **new surface: the Ethora app as an installable web app (PWA)**, the same workspace, sign-in and chat flow as the mobile app, built on the web chat SDK, with web push, an unread badge on the app icon, tenant branding taken from the App's config, and an Add to Home Screen guide on iOS. **Blocking** reached group chats (Block user from a member's profile, their messages replaced by a placeholder, live and after a reload), and owners can now edit a chat's title, description and picture through the API so the change survives a refresh. A **PHP client for the Platform API's server-token surface** was started, and both SDKs and the widget moved to tagged release workflows with package checks.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 14 commits (17 with release commits) / 26.10.4 → 26.10.7
- **New:** **Incoming call pushes on the web.** The service worker shows a sticky "Incoming call" notification with Answer and Decline when no visible page is ringing (a hidden tab with a dead socket included); Answer opens the app and accepts the call, Decline tells the caller. A push whose call token has expired shows "Missed call" instead and never rings, several tabs ringing for one call settle on one outcome, and logout clears any held call push ([`e6bbc49`](https://github.com/dappros/ethora-chat-component/commit/e6bbc49))
- **Improved:** **Web push taps land where they should:** a tap on a cold start keeps its target until the page is ready, a tap with the app already open focuses the existing tab without reloading it, `pushNotifications.clickPath` sets the landing path, and photo and video pushes show their thumbnail ([`e6bbc49`](https://github.com/dappros/ethora-chat-component/commit/e6bbc49))
- **New:** **Pushes for reactions.** Adding an emoji to someone else's message asks the server for a push to its author (the quoted text is cut to 120 characters and left out of encrypted rooms); reaction pushes arrive silent and replace the chat's previous reaction notification, not its message notification ([`251c5cd`](https://github.com/dappros/ethora-chat-component/commit/251c5cd))
- **New:** **Block a user from a group chat.** Block user sits in a member's profile, their messages in every group show as "Blocked user. Unblock to see messages.", blocked senders are excluded from unread counts, and a toast after blocking points to Settings > Privacy & Data where the list lives. The block items appear when a host sets `config.features.userBlock: true` ([`18d262d`](https://github.com/dappros/ethora-chat-component/commit/18d262d), [`cb1989a`](https://github.com/dappros/ethora-chat-component/commit/cb1989a), [`0152bee`](https://github.com/dappros/ethora-chat-component/commit/0152bee), [`229da8e`](https://github.com/dappros/ethora-chat-component/commit/229da8e))
- **New:** **Compatibility switches for servers on an earlier release:** `config.attachments.captionMode` (`'separate'` default sends the caption as its own message, `'inline'` keeps it on the media message), `config.uploads.endpoint` (`'auto'`, `'legacy'`, `'secure'`) and `config.features.userBlock` ([`af3ff4b`](https://github.com/dappros/ethora-chat-component/commit/af3ff4b))
- **Fixed:** **1:1 chats show the other person's photo** in the room list, the header and the chat profile instead of initials; clicking an avatar opens the profile with current details; edits to a chat's title, description and picture are saved on the server and survive a page refresh ([`b59d522`](https://github.com/dappros/ethora-chat-component/commit/b59d522), [`5b1146f`](https://github.com/dappros/ethora-chat-component/commit/5b1146f), [`3c360db`](https://github.com/dappros/ethora-chat-component/commit/3c360db), [`cc73576`](https://github.com/dappros/ethora-chat-component/commit/cc73576), [`ead1a9e`](https://github.com/dappros/ethora-chat-component/commit/ead1a9e))
- **Fixed:** Holding a bubble while scrolling or swiping no longer opens the context menu ([`c3b86b3`](https://github.com/dappros/ethora-chat-component/commit/c3b86b3))
- **Testing:** Render-scope tests made deterministic ([`7be3e4b`](https://github.com/dappros/ethora-chat-component/commit/7be3e4b))
- **Milestone:** **`@ethora/chat-component` 26.10.5 (19 Oct), 26.10.6 (20 Oct) and 26.10.7 (22 Oct) published** ([`4ebc5e2`](https://github.com/dappros/ethora-chat-component/commit/4ebc5e2), [`44471db`](https://github.com/dappros/ethora-chat-component/commit/44471db), [`3168224`](https://github.com/dappros/ethora-chat-component/commit/3168224))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 13 commits / 26.10.7 → 26.10.10
- **New:** **Incoming calls from VoIP pushes (iOS) and from a host's call notification (Android).** A host whose PushKit code reports the VoIP push to CallKit uses `callKitUuid(callId)`, and the SDK reports the same call under the same UUID, so the push and the chat invite never ring twice; adding an emoji to someone's message now asks the server for a reaction push to its author ([`9e45712`](https://github.com/dappros/ethora-chat-component-rn/commit/9e45712))
- **New:** **The sender's avatar in chat pushes**, next to the text with the app icon as the small badge (on iOS as a communication notification through the SDK's notification service extension), plus a refreshed push icon ([`352339f`](https://github.com/dappros/ethora-chat-component-rn/commit/352339f))
- **Improved:** Chat UI updates across the room list, header, album grid and media messages, and search in the chat ([`d46de1b`](https://github.com/dappros/ethora-chat-component-rn/commit/d46de1b))
- **Infrastructure:** **Tagged release workflow, as in the web SDK:** a release script that moves the CHANGELOG's Unreleased section into the new version and tags it, CI on the release commit, a check of the npm tarball's file list, npm publish with provenance and a GitHub release with the CHANGELOG section; `npm run publish:npm` runs the same checks from a developer's machine; `npm run build` no longer starts `expo prebuild` (the script is now `prebuild:native`) ([`c89db3e`](https://github.com/dappros/ethora-chat-component-rn/commit/c89db3e), [`2fffe2a`](https://github.com/dappros/ethora-chat-component-rn/commit/2fffe2a), [`da21c68`](https://github.com/dappros/ethora-chat-component-rn/commit/da21c68), [`74f329c`](https://github.com/dappros/ethora-chat-component-rn/commit/74f329c), [`d3bcb8b`](https://github.com/dappros/ethora-chat-component-rn/commit/d3bcb8b), [`277738b`](https://github.com/dappros/ethora-chat-component-rn/commit/277738b), [`3710b27`](https://github.com/dappros/ethora-chat-component-rn/commit/3710b27))
- **Testing:** A repeatable encrypted-messaging interop check script; lint errors on main cleared; `deleteMe` token header covered ([`d1fa054`](https://github.com/dappros/ethora-chat-component-rn/commit/d1fa054), [`365cb9f`](https://github.com/dappros/ethora-chat-component-rn/commit/365cb9f), [`07632f5`](https://github.com/dappros/ethora-chat-component-rn/commit/07632f5))
- **Milestone:** **`@ethora/chat-component-rn` 26.10.8 (20 Oct), 26.10.9 (21 Oct) and 26.10.10 (22 Oct) published**
### Ethora Mobile App (`app-react-native`)
> [ethora-app-react-native](https://github.com/dappros/ethora-app-react-native) | 4 commits / branch new-project
- **New:** VoIP push notifications for incoming calls and push notifications for reactions in the Ethora mobile app; push handling fixed and the version bumped ([`9950ac7`](https://github.com/dappros/ethora-app-react-native/commit/9950ac7), [`9988339`](https://github.com/dappros/ethora-app-react-native/commit/9988339), [`c961f7f`](https://github.com/dappros/ethora-app-react-native/commit/c961f7f), [`f0bccea`](https://github.com/dappros/ethora-app-react-native/commit/f0bccea))
### Ethora Web App, installable (`pwa`)
> New surface, live at pwa.chat.ethora.com | 25 commits
- **New:** **The Ethora app as an installable progressive web app,** with the same flow as the mobile app: enter a workspace (any tenant address, including a self-hosted cluster), sign in with email or Google, and chat on the web chat SDK with calls, inline translation and the built-in profile, settings and logout menu. An install banner on Android and desktop, a tap-to-expand Add to Home Screen guide on iOS, and an offline banner.
- **New:** **Web push and an unread badge on the app icon:** the push worker comes from the chat SDK (one notification per room, incoming calls with Answer and Decline, silent reaction pushes), and the icon badge shows the unread total (muted rooms excluded) while the app runs and counts up from notifications while it is closed.
- **New:** **Tenant branding:** a tenant App opens with its own name, logo and primary colour (the chat uses the colour too); `?workspace=` preselects a tenant, recent workspaces appear as chips, and white-label builds can set a default workspace.
- **Improved:** On iOS the chat fills the real screen with the composer above the keyboard; back gestures and browser back close the open room; chat QR share links open the room in the app; reset-password links open the workspace's web app; Google sign-in works in the installed app and on iOS Safari.
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 5 commits / 26.10.1
- **Milestone:** **Widget 26.10.1 released (21 Oct)** with the language picker, resizable panel and quick-reply buttons, the appearance saved in the admin's AI Widget tab, a visitor session created on first open and resumed on return, and pdf.js loaded only when a PDF is shown ([`2b27a87`](https://github.com/dappros/ethora-ai-chat-widget/commit/2b27a87))
- **Infrastructure:** Pull-request checks, a type-check ratchet, a package check and a dry-run release that attaches the bundle, pdf.js and SHA256 checksums to the GitHub release; workflow docs ([`25e54b9`](https://github.com/dappros/ethora-ai-chat-widget/commit/25e54b9), [`0e90b9c`](https://github.com/dappros/ethora-ai-chat-widget/commit/0e90b9c), [`8ea6f88`](https://github.com/dappros/ethora-ai-chat-widget/commit/8ea6f88), [`c21e83f`](https://github.com/dappros/ethora-ai-chat-widget/commit/c21e83f))
### WordPress Plugin (`wp-plugin`)
> [ethora-wp-plugin](https://github.com/dappros/ethora-wp-plugin) | 7 commits / 1.8.0
- **Milestone:** **Plugin 1.8.0 bundles widget 26.10.1** ([`fc74e9e`](https://github.com/dappros/ethora-wp-plugin/commit/fc74e9e))
- **Docs:** **A refreshed WordPress.org listing:** six real screenshots (one of three pages crawled and indexed on the live app), a new banner and a use-case-first description ([`bad7bc5`](https://github.com/dappros/ethora-wp-plugin/commit/bad7bc5), [`8b154af`](https://github.com/dappros/ethora-wp-plugin/commit/8b154af), [`8c1a644`](https://github.com/dappros/ethora-wp-plugin/commit/8c1a644))
- **Infrastructure:** Publishing to WordPress.org starts on a merged version change or a tag (versions already tagged are skipped) and now uploads the listing assets; the widget update step verifies checksums and takes the pdf.js files ([`c90cbf3`](https://github.com/dappros/ethora-wp-plugin/commit/c90cbf3), [`a682f5d`](https://github.com/dappros/ethora-wp-plugin/commit/a682f5d), [`f50ae32`](https://github.com/dappros/ethora-wp-plugin/commit/f50ae32))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 5 commits / branch 2610
- **New:** User blocking turned on in the web app's chat, with a toast after Unblock in Settings > Privacy & Data ([`f5824b1`](https://github.com/dappros/ethora-app-reactjs/commit/f5824b1), [`179831e`](https://github.com/dappros/ethora-app-reactjs/commit/179831e))
- **Fixed:** Users without a profile picture can upload their first one ([`3fa0427`](https://github.com/dappros/ethora-app-reactjs/commit/3fa0427))
- **Infrastructure:** The image can be built against a local chat SDK checkout; chat SDK bumped to 26.10.4 ([`1c684ae`](https://github.com/dappros/ethora-app-reactjs/commit/1c684ae), [`4e456e0`](https://github.com/dappros/ethora-app-reactjs/commit/4e456e0))
### Platform API & Push (`platform`)
> Platform API and push service | 19 commits across release lines 2610 and 2609
- **New:** **Generic push content mode per App** (`PUT/GET /v1/push/content-mode/:appId`, `full` or `generic`). In generic mode a chat push says only "New message" with ids, no text, names or pictures, while grouping, priority and badge stay; calls are not affected. Child Apps inherit their parent's mode, so one call on a tenant's base App covers all of them.
- **New:** **Reaction pushes:** the push names who reacted and to what, goes out silent on a separate Android channel with its own collapse key, is limited to one per sender and receiver every 10 seconds, and becomes "Someone reacted to your message" in generic mode; an install can switch reaction pushes off.
- **New:** **The sender's avatar in chat pushes,** with a per-App switch (`/v1/push/sender-avatar/:appId`).
- **New:** **Push texts in the device's language** (English, French, Spanish): a device can register its language, which also picks the translated message text.
- **API:** `PATCH /v1/chats/my/:chatName` lets a chat's owner change its title, description and picture (other members' room lists refresh); `GET /v1/chats/my` returns the caller's blocked users alongside the chats.
- **Fixed:** Unread counts no longer include the message the reader has just viewed, so push badges are no longer one too high.
### Chat Server & Deployment (`platform`)
> Chat server, installers, images and QA deployment | 12 commits
- **Improved:** A blocked member's messages in group rooms are delivered live and shown as the "Blocked user" placeholder, while blocking still stops delivery in 1:1 chats.
- **New:** `features.reaction_pushes` install setting (default on) for reaction pushes.
- **Improved:** Release images are built weekly or on demand and only for the components that changed, with arm64 builds for the monthly stable release; the web image is built against the pinned chat SDK; QA deployment gained a web-only scope and waits for the install mirror before updating.
### Server Integrations (`sdk-php`, `shopify`)
> New, in development | 2 commits
- **New:** **A PHP SDK for the Platform API's server-token surface:** it signs the server token locally from the App id and secret (no login round trip), offers typed resources for the v1 and v2 APIs, pages and batch jobs, typed errors carrying Ethora's error code and request id, and retries on rate limits and server errors.
- **New:** **A Shopify app backend** for the chat widget: OAuth install, an embedded App Home, and the GDPR data webhooks.
### Design System (`design-system`)
> [ethora-design-system](https://github.com/dappros/ethora-design-system) | 3 commits
- **Docs:** Caught up with the live website theme (tokens, partials, docs) and added eight site partials with screenshots to the catalog: FAQ accordion, short answer, migration steps, video embed, onboarding call, glossary term, case-study styles and the hero chat demo ([`ef423eb`](https://github.com/dappros/ethora-design-system/commit/ef423eb), [`bbaa30a`](https://github.com/dappros/ethora-design-system/commit/bbaa30a), [`a2e10ef`](https://github.com/dappros/ethora-design-system/commit/a2e10ef))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 1 commit (plus daily submodule bumps)
- **Docs:** Week 42 release notes ([`aabab62`](https://github.com/dappros/ethora/commit/aabab62))
---
## Week 42 (Oct 12 – 18, 2026) — Push notifications that carry the message without showing it to anyone else; albums, captions and read receipts on web and mobile; end-to-end encrypted calls; a Server settings console for operators; websites kept fresh in an agent's knowledge
**Contributors:** Roman Leshchuh, Yurii T., Taras Filatov, Borys Bordunov, Dmytro Berberov
**Total commits:** 134 across SDK/app repos (191 with the web SDK's generated-lib and submodule-bump commits) + 55 platform/server (77 with submodule bumps) | **Active repos:** 12
### Theme
The first line of the week was the **conversation itself**. The web chat SDK shipped 26.10.1 through 26.10.4 in four days: up to ten files in one message, laid out as an album with the text as its caption; delivery and read ticks on your own messages with a tooltip that names who has read them; a redesigned full-screen viewer that pages through pictures, videos and a continuously scrolling PDF; redesigned reactions and message bubbles with tails; media previews in the room list; and, from 26.10.4, Block user on a 1:1 chat. The React Native SDK received the same three features (albums with captions, receipts, and sending several files at once) in the same week, plus **encrypted push notifications**: the device registers a key, the push service seals every chat push for it, and Google and Apple relay only ciphertext, which the iOS extension or an Android task opens on the phone.
The second line was **privacy on calls and pushes at the platform level**. Call media is now end-to-end encrypted when a call happens in an encrypted room (the media key travels over the chat's OMEMO channel, so the server never sees it, with no new toggle). Message pushes were reworked end to end: one notification per chat that updates in place, the unread total as the app badge, an attachment thumbnail as the notification picture, high priority on Android, no push for an empty or signalling stanza, and messages a dead session had swallowed now reach offline delivery instead of being dropped.
The third line was **operating a server**. The Server settings page grew tabs (Chats, Users, AI, Email and reports, System, API), module cards that show each Enterprise module's state, licence and install command, new settings for uploads, translation languages, contacts and log retention, and operator switches that turn AI agents or App-level encryption off for a whole install. A fresh install now has a super admin from the first boot, seeds the standard agent templates, names the right file for its install kind, and keeps the uptime module's synthetic apps out of the licence counts; the compose bundle logs in to the module registry with the licence's credential and names any image it cannot reach before anything starts.
Alongside: agents' **Web Index sites are re-crawled on a schedule** (weekly by default, daily, or off) with a Refresh now and a publish hook that the WordPress plugin 1.8.0 calls the moment a page is published; a per-App **AI usage ledger** with a breakdown by purpose, agent and model under the AI tokens chart; the website widget gained a language picker, a resizable panel and quick-reply buttons; and the MCP server's 26.10.1 and 26.10.2 carry reviewed annotation hints on every tool and the ChatGPT plugin's review materials.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 67 commits (112 with generated-lib commits) / 26.10.0 → 26.10.4
- **New:** **Up to ten files in one message, with a caption.** Images and videos form an album grid (layouts for 1, 2, 3, 4 and +N), documents sit below as file cards, files upload four at a time and go out as one ordered message, each tile shows its own progress with a retry, and the text typed with the files travels inside the media message (sealed with it in encrypted rooms). `config.attachments.maxFiles` caps it ([`dd93799`](https://github.com/dappros/ethora-chat-component/commit/dd93799), [`7b9de4d`](https://github.com/dappros/ethora-chat-component/commit/7b9de4d), [`4d44aeb`](https://github.com/dappros/ethora-chat-component/commit/4d44aeb), [`56683ce`](https://github.com/dappros/ethora-chat-component/commit/56683ce), [`44aa22a`](https://github.com/dappros/ethora-chat-component/commit/44aa22a))
- **New:** **Delivery and read receipts with ticks** (XEP-0184 / XEP-0333): one tick while sending, two once another member's app received the message, two in the accent colour once it was displayed; the tooltip names who read it in a group ([`7eed387`](https://github.com/dappros/ethora-chat-component/commit/7eed387), [`43a1b07`](https://github.com/dappros/ethora-chat-component/commit/43a1b07))
- **Improved:** **Quieter receipts in big rooms.** Delivery receipts are coalesced per room (a burst or a history replay collapses into one receipt), skipped in rooms with more than 20 other members, read markers skipped above 100 and rate limited, old history not acknowledged, and receipts marked not to be archived; large groups show "Read by N of M". `config.receipts` tunes or turns it off ([`2b5d327`](https://github.com/dappros/ethora-chat-component/commit/2b5d327))
- **New:** **A redesigned full-screen viewer** with a gallery of images and videos, thumbnails, zoom and keyboard navigation, paging through the opener's album, and a continuously scrolling PDF viewer with lazily rendered pages ([`bdff62e`](https://github.com/dappros/ethora-chat-component/commit/bdff62e), [`d4c7323`](https://github.com/dappros/ethora-chat-component/commit/d4c7323), [`4b84555`](https://github.com/dappros/ethora-chat-component/commit/4b84555))
- **Improved:** **Media that looks finished:** refined album tiles, solo media and file cards, an unavailable-image illustration instead of the browser's broken icon, blur-up loading, a soft shimmer, responsive larger media, SVG treated as a plain file, and file names returned in the wrong encoding repaired for display ([`78daba4`](https://github.com/dappros/ethora-chat-component/commit/78daba4), [`4b6eea4`](https://github.com/dappros/ethora-chat-component/commit/4b6eea4), [`d4490e3`](https://github.com/dappros/ethora-chat-component/commit/d4490e3), [`6f4eaea`](https://github.com/dappros/ethora-chat-component/commit/6f4eaea), [`f57b10f`](https://github.com/dappros/ethora-chat-component/commit/f57b10f), [`343029d`](https://github.com/dappros/ethora-chat-component/commit/343029d))
- **New:** **Redesigned reactions and bubbles.** Reaction chips straddle the bubble edge with a tooltip of reactors and a +N overflow; bubbles have tails, the time sits bottom right (as a glass pill over media), insets are equal on every bubble type, and bot quick-reply buttons were restyled ([`1cbd157`](https://github.com/dappros/ethora-chat-component/commit/1cbd157), [`09baac9`](https://github.com/dappros/ethora-chat-component/commit/09baac9), [`80e3e59`](https://github.com/dappros/ethora-chat-component/commit/80e3e59), [`28c098a`](https://github.com/dappros/ethora-chat-component/commit/28c098a))
- **New:** **The room list previews media:** a thumbnail or a type label as the last message, on a two-line room card ([`b638aa3`](https://github.com/dappros/ethora-chat-component/commit/b638aa3), [`adb8989`](https://github.com/dappros/ethora-chat-component/commit/adb8989))
- **New:** **Block a user from a 1:1 chat** (header menu; the room leaves the list and Unblock lives in settings), and Leave on a 1:1 chat now sticks across reloads while a new message from the other person brings it back; `config.disableUserBlock` hides it ([`4d926cc`](https://github.com/dappros/ethora-chat-component/commit/4d926cc))
- **New:** **End-to-end encrypted call media.** In an encrypted room the call's media key is delivered over OMEMO and re-sent when a participant joins, so the server never holds it ([`0fd186a`](https://github.com/dappros/ethora-chat-component/commit/0fd186a), [`0aa436d`](https://github.com/dappros/ethora-chat-component/commit/0aa436d))
- **Improved:** Avatars show initials instantly and share one URL cache; the message list re-renders one bubble per update instead of every row; the message input takes focus on a chat switch; new `config.colors.ownMessageBackground` / `otherMessageBackground` / `inputBackground` ([`c8756f5`](https://github.com/dappros/ethora-chat-component/commit/c8756f5), [`69643dd`](https://github.com/dappros/ethora-chat-component/commit/69643dd))
- **Fixed:** OS notifications show the sender's name and the text instead of raw ids; reactions persist with the cached transcript; a message that failed to send shows no tick; media falls back to a direct download when a fetch is blocked; a failed file offers Remove after a reload; the room-list unread badge no longer flickers ([`2bea0e8`](https://github.com/dappros/ethora-chat-component/commit/2bea0e8), [`fad75fc`](https://github.com/dappros/ethora-chat-component/commit/fad75fc), [`0538d27`](https://github.com/dappros/ethora-chat-component/commit/0538d27), [`6de5173`](https://github.com/dappros/ethora-chat-component/commit/6de5173))
- **Milestone:** **`@ethora/chat-component` 26.10.1 (15 Oct), 26.10.3 and 26.10.4 (16 Oct) published**, now on date-based versions with a release command, a consumer smoke test of the packed tarball on React 18 and 19, checks on every pull request, and the generated `lib` no longer tracked in git ([`26e76fa`](https://github.com/dappros/ethora-chat-component/commit/26e76fa), [`c74fd51`](https://github.com/dappros/ethora-chat-component/commit/c74fd51), [`4212a69`](https://github.com/dappros/ethora-chat-component/commit/4212a69), [`620fe2e`](https://github.com/dappros/ethora-chat-component/commit/620fe2e), [`ec15670`](https://github.com/dappros/ethora-chat-component/commit/ec15670), [`a618353`](https://github.com/dappros/ethora-chat-component/commit/a618353))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 38 commits / 26.10.2 → 26.10.7
- **New:** **Encrypted push notifications.** Each install registers an X25519 device key with its push token; the push service seals every chat push for that key and Google and Apple relay ciphertext only. On iOS a notification service extension (added by the SDK's Expo config plugin) opens the box and shows the real title and text; on Android an `expo-task-manager` task does the same, also with the app closed. A backend without the key refuses the registration rather than deliver in the clear ([`07cd350`](https://github.com/dappros/ethora-chat-component-rn/commit/07cd350))
- **New:** **Attachment previews in iOS pushes** through the same config plugin, matching Android ([`1cdff52`](https://github.com/dappros/ethora-chat-component-rn/commit/1cdff52), [`17aa005`](https://github.com/dappros/ethora-chat-component-rn/commit/17aa005))
- **New:** **Several files in one message.** The composer picks several documents or library items at once, each pick adds to the tray, files upload in parallel (fewer at a time in an encrypted room, where each is sealed first) and go out as one message in selection order with the typed text as caption; per-file progress and retry on a pending album; `config.attachments.maxFiles` and `maxSizeMB` ([`c0f0c55`](https://github.com/dappros/ethora-chat-component-rn/commit/c0f0c55), [`cf384c6`](https://github.com/dappros/ethora-chat-component-rn/commit/cf384c6), [`fd77a7a`](https://github.com/dappros/ethora-chat-component-rn/commit/fd77a7a), [`06bc0d0`](https://github.com/dappros/ethora-chat-component-rn/commit/06bc0d0))
- **New:** **Albums and captions received** the way the web SDK sends them: pictures and videos as tiles with a +N, documents and voice notes as cards, the viewer pages through the album, and the caption shows under the files, in previews, quotes and copy ([`b4e16b2`](https://github.com/dappros/ethora-chat-component-rn/commit/b4e16b2), [`aafd7ec`](https://github.com/dappros/ethora-chat-component-rn/commit/aafd7ec), [`c4e230c`](https://github.com/dappros/ethora-chat-component-rn/commit/c4e230c))
- **New:** **Delivery and read receipts**, a port of the web implementation: single, double grey and double accent ticks on your own messages, a tap opens a sheet naming who read or received the message in a group, the read position is flushed when leaving the room or the app, and `disableReadReceipts` turns both off ([`3a35a01`](https://github.com/dappros/ethora-chat-component-rn/commit/3a35a01), [`af4b5dc`](https://github.com/dappros/ethora-chat-component-rn/commit/af4b5dc), [`beb94a2`](https://github.com/dappros/ethora-chat-component-rn/commit/beb94a2), [`ffe9549`](https://github.com/dappros/ethora-chat-component-rn/commit/ffe9549))
- **Improved:** Tablet layouts are supported, and video and audio calls were fixed and updated ([`d31e66a`](https://github.com/dappros/ethora-chat-component-rn/commit/d31e66a), [`eb03120`](https://github.com/dappros/ethora-chat-component-rn/commit/eb03120), [`967f24b`](https://github.com/dappros/ethora-chat-component-rn/commit/967f24b))
- **Fixed:** Sign-out and the Leave button; unread counts ([`53b5788`](https://github.com/dappros/ethora-chat-component-rn/commit/53b5788), [`83b6185`](https://github.com/dappros/ethora-chat-component-rn/commit/83b6185))
- **Milestone:** **`@ethora/chat-component-rn` 26.10.2 through 26.10.7 published** (six releases, 12 to 16 October) ([`68d735e`](https://github.com/dappros/ethora-chat-component-rn/commit/68d735e))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 12 commits / branch 2610
- **New:** **Server settings, second round:** tabs Chats | Users | AI | Email and reports | System | API, module cards at the top of their tab with state, licence and install command (public URL with Open, or the MCP connector URL with Copy, and the uptime dashboard's sign-in shown or copied by a super admin), rate limits under Advanced, the AI agents switch on the AI card, and the App encryption switch disabled with a note when the install's encryption gate is off ([`ec93670`](https://github.com/dappros/ethora-app-reactjs/commit/ec93670), [`5efb15f`](https://github.com/dappros/ethora-app-reactjs/commit/5efb15f))
- **New:** **Web Index: sites kept up to date.** The panel lists the sites an agent's index re-crawls on a schedule, the outcome of the last refresh (changed, new, removed pages), the next run, a per-site schedule (weekly, daily, off), Refresh now, and the publish hook with its refresh key for a CMS to call ([`be0b6bf`](https://github.com/dappros/ethora-app-reactjs/commit/be0b6bf), [`b30d645`](https://github.com/dappros/ethora-app-reactjs/commit/b30d645))
- **New:** **AI usage breakdown.** Statistics > AI tokens shows what the period's tokens went on (agent replies, reply checks, scheduled messages, flows, agent API, website and document indexing, knowledge search), by agent and by model, with month to date; an agent's page shows its tokens this month ([`ccf8a0e`](https://github.com/dappros/ethora-app-reactjs/commit/ccf8a0e), [`1c0f196`](https://github.com/dappros/ethora-app-reactjs/commit/1c0f196), [`c31a937`](https://github.com/dappros/ethora-app-reactjs/commit/c31a937))
- **New:** **End-to-end encrypted calls** enabled under the install's encryption and calls gates, with the LiveKit encryption worker bundled ([`412dd02`](https://github.com/dappros/ethora-app-reactjs/commit/412dd02))
- **New:** **Blocked users** list in Settings with Unblock ([`882e81e`](https://github.com/dappros/ethora-app-reactjs/commit/882e81e))
- **Improved:** Self-hosted wording: the License and Server settings pages name `.env` or `deploy.yml` by install kind, and the base-app Chats banner tells a self-hosted operator these are their own server's chats ([`375b5b7`](https://github.com/dappros/ethora-app-reactjs/commit/375b5b7))
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 3 commits
- **New:** **Language picker, resizable panel, quick-reply buttons.** A globe in the header switches the widget's language (English, Spanish, French), the panel resizes from its corner and remembers the size, bot quick replies come as pills or a list (`data-button-style`), an animated typing indicator, `data-color-scheme`, and a smaller bundle ([`5fa7490`](https://github.com/dappros/ethora-ai-chat-widget/commit/5fa7490))
- **Fixed:** The composer grows with its text, and the history loader no longer flashes over a fresh conversation ([`6da45d0`](https://github.com/dappros/ethora-ai-chat-widget/commit/6da45d0), [`1d37cdc`](https://github.com/dappros/ethora-ai-chat-widget/commit/1d37cdc))
### WordPress Plugin (`wp-plugin`)
> [ethora-wp-plugin](https://github.com/dappros/ethora-wp-plugin) | 2 commits / 1.7.3 → 1.8.0
- **New:** **1.8.0: pages re-indexed on publish.** With a refresh key from the agent's Web Index, posts and pages that are published, updated, unpublished or trashed are sent to Ethora's refresh hook at once instead of waiting for the next scheduled refresh (old address included when a slug changes), plus a "Refresh website knowledge now" button ([`d9828b8`](https://github.com/dappros/ethora-wp-plugin/commit/d9828b8))
- **Milestone:** The plugin is published to WordPress.org from GitHub Actions ([`a339347`](https://github.com/dappros/ethora-wp-plugin/commit/a339347))
### AI Assistants & MCP (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 9 commits / 26.10.1 (npm, 16 Oct) and 26.10.2 (main)
- **New:** **Websites kept up to date from an assistant:** `ethora-source-site-watch-list` / `-watch-update` / `ethora-source-site-refresh` list the crawled sites with their last refresh, set a site's schedule, or refresh a whole site or specific pages now ([`9bd5f92`](https://github.com/dappros/ethora-mcp-server/commit/9bd5f92), [`3ae968f`](https://github.com/dappros/ethora-mcp-server/commit/3ae968f))
- **Improved:** **Every tool carries all four MCP annotation hints** as explicit booleans from one reviewed table with a reason each (`docs/TOOL_ANNOTATIONS.md` is generated from it); OAuth connections list every offered tool up front; `openWorldHint` and `destructiveHint` follow the directory scanners' definitions; the job-status tools are renamed `-get` with the old names as aliases ([`583ccd1`](https://github.com/dappros/ethora-mcp-server/commit/583ccd1), [`c14007a`](https://github.com/dappros/ethora-mcp-server/commit/c14007a), [`1049838`](https://github.com/dappros/ethora-mcp-server/commit/1049838))
- **Improved:** **First-run guidance:** an account with no app gets `NO_APP_YET` pointing at `ethora-app-create`, activating an agent before inviting it returns `AGENT_NOT_INVITED` with the next step, and `ethora-agent-model-list` returns the model ids the deployment serves ([`aaaa2b0`](https://github.com/dappros/ethora-mcp-server/commit/aaaa2b0))
- **Docs:** The ChatGPT plugin manifest embeds its review test cases (including prompts that must not trigger the plugin), release notes and a demo recording ([`02906ef`](https://github.com/dappros/ethora-mcp-server/commit/02906ef), [`4bc3059`](https://github.com/dappros/ethora-mcp-server/commit/4bc3059), [`ee6e6b7`](https://github.com/dappros/ethora-mcp-server/commit/ee6e6b7))
### Platform API & AI Service (`platform`)
> Platform API, push and AI services | 30 commits (2610, with the push changes also on 2609)
- **New:** **Push notifications reworked.** Encrypted pushes for devices that register a key (content sealed per device, ids in clear, a placeholder on iOS for the extension to replace); one notification per chat that updates in place; the unread total as the app-icon badge; an attachment thumbnail as the notification picture through a signed file link; the title and attachment text taken from the message itself; high priority on Android; no push for an empty body; and direct APNs keeps a message for a switched-off device and collapses per chat.
- **New:** **Web Index refresh on a schedule.** Every crawl start URL becomes a watched site (weekly by default, daily or off), due sites are re-crawled two at a time, unchanged pages are only marked as checked and not re-embedded, changed pages replace their old text, pages gone from the site are removed, a site pauses after three failed refreshes, and a publish hook with a refresh key lets a CMS re-index a page the moment it changes. Re-embedding replaces a page's chunks instead of adding copies.
- **New:** **AI usage ledger per App.** Every model call is recorded against its App and agent with its purpose (replies, reply checks, scheduled messages, flows, agent API, indexing, knowledge search), cached input tokens are recorded and billed at their discount, and the statistics report carries the breakdown.
- **New:** **Server settings, second round:** tabs and groups, settings for uploads (size, allowed and blocked types), translation languages, trust-and-safety and legal contacts, sign-up email checks, refresh-token lifetime, log level and log retention, error tracker; module status (installed, running, licensed, enable command); operator switches that disable AI agents or App-level encryption for the whole install; changes to uploads, contacts and the refresh lifetime take effect without a restart, and Reset restores the deployment's values at once.
- **New:** **Block a user in a 1:1 chat** and **leave a 1:1 chat without losing it:** the chat hides from your own list only, and a new message from the other person brings it back with its history; the chat server enforces a block on realtime delivery.
- **Improved:** **Fresh installs:** the base app's owner is a super admin from the first boot (and existing installs without one are repaired on their next update); the standard agent templates are seeded at init so New Agent offers them before any App exists; the install kind is reported so the admin panel names the right file; the uptime module's synthetic apps and users stay out of the licence counts; licence call-home goes to Ethora's licence service by default and reports the key in effect.
- **Improved:** An agent's model is validated against the models the AI endpoint serves (`GET /v2/agents/models`); a bare room name is normalised before an agent joins; membership caches are invalidated on leaving a group; statistics return AI token and message series with period totals in one query.
### Chat Server & Deployment (`platform`)
> Chat server, installers, images and QA deployment | 25 commits
- **New:** **End-to-end encrypted calls, documented for operators.** Call media is encrypted automatically when encryption and calls are both on and the call happens in an encrypted room; the media key is exchanged over OMEMO, with a transport-encrypted fallback for clients that cannot do it.
- **Improved:** **Messages a dead session swallowed reach offline delivery** (unacknowledged messages of a timed-out session are re-sent to offline storage and the push hook); offline pushes carry the sender, attachment preview and file fields, and send nothing for bodiless or call-signalling stanzas.
- **Improved:** **The compose bundle checks module access before starting.** With a licence key it fetches the licence's registry credential, logs in, and verifies every Enterprise module image, naming each one it cannot reach and what to do; the installers seed the standard agent templates and write the module list, module URLs, encryption gate and translation URL the Server settings page reads.
- **New:** **QA deployment from GitHub Actions** through a self-hosted runner on the QA host (nothing opened inbound, no key in secrets, the update log in the job), bumping the release line's submodules first.
- **Improved:** The web host never caches `index.html` and gives the bundles one long-cache header; the secure files host is served by the API without a rewrite; the update script survives a long stash list and rebuilds the crawler when its inputs change.
### Monitoring (`uptime`)
> [ethora-uptime](https://github.com/dappros/ethora-uptime) | 2 commits / branch 2610
- **Improved:** Journeys purge their synthetic apps instead of archiving them (and sweep leftovers of crashed runs), the chat echo runs in a synthetic app of its own, and the dashboard's section labels are proxy-neutral ([`bc17627`](https://github.com/dappros/ethora-uptime/commit/bc17627), [`d1b1812`](https://github.com/dappros/ethora-uptime/commit/d1b1812))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 1 commit (plus daily submodule bumps)
- **Docs:** Week 41 release notes ([`f597a4e`](https://github.com/dappros/ethora/commit/f597a4e))
---
## Week 41 (Oct 5 – 11, 2026) — Agents get Memory, a Try-it chat and a knowledge health check; the website AI widget keeps its look on the App and lists its visitors; the React Native SDK catches up with the web and adds opt-in encrypted rooms; a Claude Code skill adds Ethora chat to an app from one prompt; Ethora Core lands on Azure Marketplace
**Contributors:** Taras Filatov, Roman Leshchuh, Dmytro Berberov, Yurii T., Borys Bordunov, plus a community contribution (meichuanyi)
**Total commits:** 96 across SDK/app repos + 123 platform/server | **Active repos:** 15
### Theme
The first full week on the 26.10 line went into **AI agents**. An agent's long-term notes are now called Memory, its prompt is called Instructions, and both can be tested in a **Try it** chat inside Agent Settings before anything is deployed, with the knowledge excerpts and source pages it used shown under each answer. Knowledge search combines meaning with exact keywords, so product codes and names are found; each Web or Docs index reports its health and offers a rebuild; a crawl can be stopped; a new agent can start from a public template; and the agent now knows its own name, bio and today's date. The hosted MCP server learned the same tricks in the same week.
The second line was the **website AI widget**. Its appearance is now saved on the App, with a live preview, theme presets and a colour picker, and every embed picks it up without re-pasting the snippet. Anonymous visitors get their own tab under Users with the page the chat started on and the transcript, and the WordPress plugin ships the on-demand widget build.
The third line was **mobile**. The React Native SDK took the web SDK's foundation in one port (history by server cursor, names looked up on demand, real member counts, a fast start for accounts with many rooms, jump-to-message windows), then added opt-in end-to-end encrypted rooms, user language and password settings, swipe actions, mute and a new voice-message player across seven npm releases.
Alongside: a **Claude Code skill** that adds Ethora chat to a React or React Native app from one prompt, an **Ethora + Ollama** example for agents on a local model, and **Ethora Core on Azure Marketplace**, with every cloud image now running the same Docker Compose bundle and the Enterprise modules available as compose profiles.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 18 commits / 26.9.8
- **Improved:** **A fast start for users with many rooms.** The room list renders as soon as the API answers and the room joins run in the background, the open room first and then by activity; joins ask for no server history, history preload is staged (top rooms first, a small worker pool, the opened room jumps the queue), and unread counts and last messages come straight from the room list ([`aae22b7`](https://github.com/dappros/ethora-chat-component/commit/aae22b7))
- **New:** **Names for every sender.** Senders of older messages are looked up on demand, batched and cached, with a placeholder while the lookup runs instead of a raw id ([`65276c9`](https://github.com/dappros/ethora-chat-component/commit/65276c9))
- **Improved:** **Real member counts in big rooms.** The header and profile show the room's true user count, and the members list, @ mentions and the search sender filter load the full room directory on demand ([`159a769`](https://github.com/dappros/ethora-chat-component/commit/159a769))
- **New:** Profile and room changes arrive as server events and refresh the UI in place ([`3d068db`](https://github.com/dappros/ethora-chat-component/commit/3d068db))
- **Fixed:** A join in flight at a socket drop no longer blocks rooms and every history request settles; the older-history loader recovers when the cursor goes backwards; a room fills the viewport on open even when its first page is mostly read receipts; the room subtitle stays on one line on narrow screens ([`40fe72f`](https://github.com/dappros/ethora-chat-component/commit/40fe72f), [`0f11abb`](https://github.com/dappros/ethora-chat-component/commit/0f11abb), [`345bfe5`](https://github.com/dappros/ethora-chat-component/commit/345bfe5), [`85a105a`](https://github.com/dappros/ethora-chat-component/commit/85a105a))
- **Fixed:** Ordinary messages no longer carry a redundant system-message flag ([`a3bf5e7`](https://github.com/dappros/ethora-chat-component/commit/a3bf5e7))
- **Milestone:** **`@ethora/chat-component` 26.9.8 published** on 5 October ([`303425d`](https://github.com/dappros/ethora-chat-component/commit/303425d))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 24 commits / 26.8.6 → 26.10.1
- **New:** **The web SDK's foundation, ported in one go.** History follows the server's paging cursor, unknown senders are resolved on demand, rooms show their true member count, server events refresh profiles and room details, and accounts with many rooms see their list as soon as the API answers while joins run in the background. New options `historyPreload`, `userLookupRoute` and `trustedEventSenders` ([`3f8880f`](https://github.com/dappros/ethora-chat-component-rn/commit/3f8880f), [`3f17ec6`](https://github.com/dappros/ethora-chat-component-rn/commit/3f17ec6), [`57f5005`](https://github.com/dappros/ethora-chat-component-rn/commit/57f5005))
- **New:** **Search that reaches into messages.** With `enableMessageSearch` the chat-list search also lists matching messages under their chats, the field has a clear button, and the sender filter finds members of big rooms ([`a692354`](https://github.com/dappros/ethora-chat-component-rn/commit/a692354), [`a8e8990`](https://github.com/dappros/ethora-chat-component-rn/commit/a8e8990))
- **New:** **Jump to an old message without paging all history.** A search hit, push or link opens a short window of the archive around the message, with a Jump to latest button; threads load their history by the same cursor ([`a3f0dce`](https://github.com/dappros/ethora-chat-component-rn/commit/a3f0dce), [`366e778`](https://github.com/dappros/ethora-chat-component-rn/commit/366e778))
- **New:** **End-to-end encrypted rooms on mobile, opt-in.** With `config.e2ee.enabled`, rooms the app owner marks as encrypted work on iOS and Android as they do on the web: OMEMO 2 text both ways, attachments sealed on the device before upload, an "Encrypted message" action on a user's profile, and each person's devices with fingerprints and a trust mark ([`d424b38`](https://github.com/dappros/ethora-chat-component-rn/commit/d424b38), [`01b2c0a`](https://github.com/dappros/ethora-chat-component-rn/commit/01b2c0a))
- **New:** **Language and password in Settings.** Users pick the interface language and the language messages are translated into, and can change their password on its own Settings page; both cards are off by default, and every caption in menus, dialogs and toasts now follows the chosen language ([`ff8f631`](https://github.com/dappros/ethora-chat-component-rn/commit/ff8f631))
- **New:** **Swipe a room left for Report and Leave**, as in the messengers (`disableRoomSwipeActions` turns it off) ([`e5698d5`](https://github.com/dappros/ethora-chat-component-rn/commit/e5698d5))
- **New:** **Mute a chat from its profile, and a new voice-message player** with a waveform ([`7c8d28e`](https://github.com/dappros/ethora-chat-component-rn/commit/7c8d28e))
- **Improved:** **The chat says when it is not live.** The headers read "Connecting…" or "Updating…" while the connection is being set up or rooms are catching up, the connection closes when the app goes to the background so pushes keep arriving, and a lost session shows "Session expired" with a Retry ([`49823f1`](https://github.com/dappros/ethora-chat-component-rn/commit/49823f1), [`169078a`](https://github.com/dappros/ethora-chat-component-rn/commit/169078a), [`22679f5`](https://github.com/dappros/ethora-chat-component-rn/commit/22679f5))
- **Improved:** In-app toasts follow the web client's rules (another chat, someone else, app on screen); Manage Data, Visibility, Blocked users and the shares screens were reworked and scroll ([`71980d7`](https://github.com/dappros/ethora-chat-component-rn/commit/71980d7), [`0f244cc`](https://github.com/dappros/ethora-chat-component-rn/commit/0f244cc))
- **Fixed:** iOS videos play from the secure files host, falling back to a cached download when streaming is refused; a pending sender is no longer shown as a profile name ([`359e12f`](https://github.com/dappros/ethora-chat-component-rn/commit/359e12f), [`7598533`](https://github.com/dappros/ethora-chat-component-rn/commit/7598533))
- **Milestone:** **`@ethora/chat-component-rn` 26.8.7 through 26.10.1 published** (seven releases, 6 to 9 October; 26.10.0 aligns the SDK with the 26.10 line) ([`184ef4a`](https://github.com/dappros/ethora-chat-component-rn/commit/184ef4a), [`425f083`](https://github.com/dappros/ethora-chat-component-rn/commit/425f083))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 21 commits / branch 2610
- **New:** **Agent Settings: Memory, Instructions and a Try it chat.** Test an agent's instructions, memory and knowledge without deploying it, with the number of knowledge excerpts and their pages under each answer; Web Index and Docs Index show a knowledge health line and offer a rebuild when stored content is not searchable; a new agent can start from a blank agent or a public template ([`193dcae`](https://github.com/dappros/ethora-app-reactjs/commit/193dcae), [`ee6c192`](https://github.com/dappros/ethora-app-reactjs/commit/ee6c192))
- **New:** **Agents list:** category filter and tags, a clone dialog with "include knowledge", a confirmation before an agent goes public, and Stop on a running crawl ([`100471b`](https://github.com/dappros/ethora-app-reactjs/commit/100471b), [`14affb8`](https://github.com/dappros/ethora-app-reactjs/commit/14affb8))
- **New:** **AI Widget appearance saved on the App, with a live preview.** Theme presets including the app's brand colour, a colour picker with hex input, size cards, sliders, launcher icon upload, and the agent's avatar in the preview; pinning values in the snippet is now optional ([`3022cf9`](https://github.com/dappros/ethora-app-reactjs/commit/3022cf9), [`3f7d1b2`](https://github.com/dappros/ethora-app-reactjs/commit/3f7d1b2), [`0bb1fd1`](https://github.com/dappros/ethora-app-reactjs/commit/0bb1fd1), [`8507742`](https://github.com/dappros/ethora-app-reactjs/commit/8507742))
- **Improved:** **A simpler AI Widget tab.** Test widget on top, one agent card (picker, avatar, bio, on/off, knowledge size, conversations), the code first with appearance on its own tab, a copy that copies the snippet as written, and a drag-and-drop zone for documents ([`44ebb96`](https://github.com/dappros/ethora-app-reactjs/commit/44ebb96), [`dfbc609`](https://github.com/dappros/ethora-app-reactjs/commit/dfbc609))
- **New:** **Users | Admins | Visitors.** Website visitors from the AI widget get their own tab: country, device, the page the chat started on, first and last seen, the transcript, and Delete ([`44eb22b`](https://github.com/dappros/ethora-app-reactjs/commit/44eb22b))
- **New:** **Agent Flows editor checks the script while you type,** with line numbers and the error line highlighted ([`4952470`](https://github.com/dappros/ethora-app-reactjs/commit/4952470), [`dba5eba`](https://github.com/dappros/ethora-app-reactjs/commit/dba5eba))
- **New:** **Account > Security: change email** ([`fc83ec9`](https://github.com/dappros/ethora-app-reactjs/commit/fc83ec9))
- **New:** **Server settings page for super admins:** email delivery, feedback retention, default rooms, analytics reports, rate limits and the AI provider, each showing where its value comes from, with Reset and a note when a change waits for a restart ([`42ed201`](https://github.com/dappros/ethora-app-reactjs/commit/42ed201))
- **New:** The License page shows the registry credential for the Enterprise module images ([`fdea78e`](https://github.com/dappros/ethora-app-reactjs/commit/fdea78e))
- **Improved:** Short names and an empty last name are accepted in the admin forms; Profile's About, Documents, Preferences and Logout sections tidied ([`5a7fb30`](https://github.com/dappros/ethora-app-reactjs/commit/5a7fb30), [`314d936`](https://github.com/dappros/ethora-app-reactjs/commit/314d936))
- **Fixed:** Agent Settings tabs show the saved value after a tab switch; the read-only notice no longer takes a third of the page ([`0e6019b`](https://github.com/dappros/ethora-app-reactjs/commit/0e6019b), [`808b14c`](https://github.com/dappros/ethora-app-reactjs/commit/808b14c))
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 4 commits
- **New:** **The widget applies the appearance saved in the admin.** It reads the App's stored look before drawing the launcher (1.5 s timeout); a value on the snippet or in the URL still wins, so existing embeds behave as before ([`5fca704`](https://github.com/dappros/ethora-ai-chat-widget/commit/5fca704))
- **New:** The session records the page the widget runs on (origin and path only) so operators can see where a chat started ([`d180d2a`](https://github.com/dappros/ethora-ai-chat-widget/commit/d180d2a))
- **Fixed:** The bundle is built as ASCII so it renders on pages that are not UTF-8, and the PDF viewer is located relative to the script's own directory ([`e6c97ff`](https://github.com/dappros/ethora-ai-chat-widget/commit/e6c97ff), [`0cd00fd`](https://github.com/dappros/ethora-ai-chat-widget/commit/0cd00fd))
### WordPress Plugin (`wp-plugin`)
> [ethora-wp-plugin](https://github.com/dappros/ethora-wp-plugin) | 2 commits / 1.7.2 → 1.7.3
- **Milestone:** **1.7.3:** the bundled widget is the current 26.10 build, which creates a visitor session the first time the launcher is hovered or opened (not on page load), resumes it for a returning visitor, and records the page the chat started on ([`0d93b29`](https://github.com/dappros/ethora-wp-plugin/commit/0d93b29), [`927708e`](https://github.com/dappros/ethora-wp-plugin/commit/927708e))
### AI Assistants & MCP (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 3 commits (on main, next npm release)
- **New:** **Agent and widget tools:** `ethora-agent-try`, `ethora-agent-knowledge-get` / `-rebuild`, `ethora-source-site-crawl-cancel`, and a new widget group with `ethora-widget-appearance-get` / `-set` for the look saved on the App; `includeKnowledge` on clone, visibility and category filters on the agent list, and crawls and uploads can target a named agent ([`e3453a5`](https://github.com/dappros/ethora-mcp-server/commit/e3453a5))
- **Improved:** In user sign-in, `ethora-agent-list` lists the account's agents unless an `appId` is passed ([`1a1f0fc`](https://github.com/dappros/ethora-mcp-server/commit/1a1f0fc))
### Claude Code Skill (`chat-ethora-skill`) — new repository
> [chat-ethora-skill](https://github.com/dappros/chat-ethora-skill) | 11 commits / MIT
- **New:** **Add Ethora chat to an app from one prompt.** A Claude Code skill that detects a web (Vite, Next) or React Native project, installs the chat SDK, wraps the app, creates the chat page or screen, signs in to the Ethora admin from the terminal to create or pick an app, writes the env files, sets up users signed in automatically through the app's own backend (asking before it touches the backend), and verifies the result; works with Ethora Cloud or a self-hosted server ([`c70fd42`](https://github.com/dappros/chat-ethora-skill/commit/c70fd42), [`5a5122f`](https://github.com/dappros/chat-ethora-skill/commit/5a5122f))
- **New:** Installs as a Claude Code plugin from its own marketplace, by cloning into `.claude/skills`, or with `npx skills` for Cursor, Codex and other agents; MIT licensed ([`0dc43b4`](https://github.com/dappros/chat-ethora-skill/commit/0dc43b4), [`4f399f6`](https://github.com/dappros/chat-ethora-skill/commit/4f399f6), [`e991839`](https://github.com/dappros/chat-ethora-skill/commit/e991839))
- **Improved:** Directory readiness: icon and display name, documentation and privacy links, the admin password and MFA code typed only at a hidden prompt, token routes written in the backend's own language (Python, PHP, Ruby, Go, Java/Kotlin, .NET), and a 3-minute demo video ([`6b6f6de`](https://github.com/dappros/chat-ethora-skill/commit/6b6f6de), [`3a87533`](https://github.com/dappros/chat-ethora-skill/commit/3a87533), [`6688d89`](https://github.com/dappros/chat-ethora-skill/commit/6688d89), [`3cbf092`](https://github.com/dappros/chat-ethora-skill/commit/3cbf092))
### Ethora + Ollama (`ollama-example`) — new repository
> [ethora-ollama-example](https://github.com/dappros/ethora-ollama-example) | 1 commit
- **New:** **Run an Ethora AI agent on a model that never leaves your machine.** A compose file that runs Ollama and pulls a CPU-friendly chat model and an embeddings model, the four environment variables that point Ethora's AI service at it, a pgvector database for knowledge, and scripts that verify the calls and test a chat ([`49f28a0`](https://github.com/dappros/ethora-ollama-example/commit/49f28a0))
### Platform API & AI Service (`platform`)
> Platform API and AI service | 54 commits (2610, with push changes also on 2609)
- **New:** **Agent Memory and a sharper knowledge search.** Knowledge search combines meaning with keyword matching so exact names and product codes are found, drops near-duplicate excerpts and caps excerpts per page, and hands them to the model as reference material; a Try it endpoint answers from a test conversation and returns the sources it used; a knowledge health endpoint compares stored and searchable content, with one rebuild per agent at a time and embedding in batches.
- **New:** **Agents know who they are.** The model is told its display name, bio and today's date; web excerpts carry their source URL so answers can cite it; a running crawl can be stopped and keeps the pages delivered so far.
- **New:** **Agent templates, categories and clones.** A shared template stays shared until an App changes something, then the App gets its own copy (its bot is repointed, nothing else changes); agents have categories, clone with or without their knowledge, can be deleted by the App that homes them, and take their knowledge with them when deleted.
- **New:** **The website widget's appearance is stored on the App** with a public, cached widget config endpoint; widget conversations record the page they started on, and visitors are kept out of the Users list.
- **New:** **Change your own email** with the same proof as a password change (current password, a fresh provider sign-in or an MFA code); other sessions are ended.
- **New:** **Server settings a super admin can change after install** (email delivery, feedback retention, default-room trimming, analytics reports, rate limits, AI provider), stored by the platform and taking precedence over the deployment values, with a note of which saved change still waits for a restart.
- **New:** **Push notifications with the server's own keys for every app.** Keys uploaded to the base app serve every app on the install, an app with its own keys uses them, there is no daily cap, and each app has a single off switch.
- **New:** The licence service delivers each customer's pull credential for the Enterprise module images with every heartbeat, and the License page shows it to super admins.
- **Improved:** **One name rule everywhere:** a first name of 1 to 60 characters and an optional last name on every sign-up, create and profile route, so short and single names are accepted.
- **Improved:** Statistics count each archived message once, with a backfill for past days; room member pages are stable and the room-list preview shows the most recently active members first; social sign-up works on apps without blockchain and social logins re-join default rooms; a refused request body answers 4xx; `GET /v1/users/my` is served.
- **New:** Optional error reporting from the API, push and AI services to a Sentry-compatible tracker (off unless configured); log lines name their source file and line, with per-request traces moved to debug.
- **Docs:** Agents API, widget config and crawl cancel in the API reference.
### Chat Server & Deployment (`platform`)
> Server installation, images and licence service | 69 commits
- **Milestone:** **Ethora Core is live on Azure Marketplace** (8 October), joining AWS Marketplace.
- **Improved:** **Every cloud image runs the same compose bundle.** The AWS, Azure, DigitalOcean, Vultr and Akamai images share one provisioning script and pre-pull the bundle's images; the Azure and DigitalOcean images were re-baked and verified on build 2610.16.
- **New:** **Enterprise modules as compose profiles.** The AI service (with its pgvector database and the website chat widget), push, playground, MCP and uptime modules run from the same bundle behind `--modules`, and their images are published to private registry repositories reached with the customer's licence credential.
- **Improved:** **Chat attachments work out of the box on every Core install:** the secure files host is now derived like the other hosts by the installer, the cloud images, the compose bundle and the Helm chart.
- **Improved:** Release builds: build numbers from git tags, an image-export workflow for hosts without a registry token, a registry cleanup workflow, and an image build after every submodule bump.
- **New:** Monitoring alerts for process restart loops and log levels for more log formats.
- **Docs:** "Other ways to install" (marketplaces, Helm, platforms, Cloudron, Docker Hub) in the installer README, the chat server's Ethora modules described, Server settings in the operator notes, and team instructions for testing the full version from Docker Hub.
### Monitoring (`uptime`)
> [ethora-uptime](https://github.com/dappros/ethora-uptime) | 3 commits / branch 2610
- **Improved:** Journey checks delete the agents they create before deleting their synthetic App, and the runtime image was slimmed ([`97275c7`](https://github.com/dappros/ethora-uptime/commit/97275c7), [`7ce4262`](https://github.com/dappros/ethora-uptime/commit/7ce4262))
### Bots (`bots`)
> [ethora-bots](https://github.com/dappros/ethora-bots) | 1 commit
- **Docs:** The 2021-2023 bot documentation preserved in the repository ahead of the old wiki's retirement ([`538c3cc`](https://github.com/dappros/ethora-bots/commit/538c3cc))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 8 commits (plus daily submodule bumps)
- **Docs:** **A chat protocol reference** for client authors (server events are `<ethora-event>`), the push notifications page rewritten, and hosting options pointing at [ethora.com/get](https://ethora.com/get/) ([`33c98d8`](https://github.com/dappros/ethora/commit/33c98d8), [`7bed929`](https://github.com/dappros/ethora/commit/7bed929), [`e448975`](https://github.com/dappros/ethora/commit/e448975), [`e6c6f59`](https://github.com/dappros/ethora/commit/e6c6f59))
- **Docs:** README "Run your own server" with distribution badges; the 2021 engine feature list archived; Week 40 release notes; a typo fix in the contributing guide from a community contributor ([`dcd6d68`](https://github.com/dappros/ethora/commit/dcd6d68), [`192cb49`](https://github.com/dappros/ethora/commit/192cb49), [`977a964`](https://github.com/dappros/ethora/commit/977a964), [`2f2a16e`](https://github.com/dappros/ethora/commit/2f2a16e))
---
## Week 40 (Sep 28 – Oct 4, 2026) — Release 26.10 ships; Ethora Core is packaged for a dozen one-click platforms; the web chat SDK learns to search messages and discover public chats; a speed pass across widget, API and admin console
**Contributors:** Taras Filatov, Roman Leshchuh, Dmytro Berberov, Yurii T., Borys Bordunov
**Total commits:** 87 across SDK/app repos + 127 platform/server | **Active repos:** 10
### Theme
**Release 26.10 shipped on 1 October** and became the production line the next day; the 2610 iteration is now frozen as the stable branch. The week's first line of work was **distribution**: the self-hosted edition, Ethora Core, which became installable from public images last week, gained a packaged form for nearly every place an operator might look for it. There is an AWS Marketplace AMI baked from the public installer, a DigitalOcean 1-Click image, an Azure image, a Vultr image and a Linode StackScript, a Helm chart published to Docker Hub's OCI registry and Artifact Hub, a single-file Docker Compose bundle, and store packages for Cloudron, Umbrel and CasaOS, plus guides for Coolify, Dokploy and Portainer. All of them install the same free tier with the same caps.
The second line was **finding things in a conversation**. The web chat SDK gained message search, in one chat or across every chat, with sender and date filters, Ctrl/Cmd+F, and a jump that pages history back to the hit; and a "Discover chats" directory so a user can find and join an app's public chats without being sent a link. The React Native SDK caught up on conversation basics with reactions, reply threads, an appearance and push switch in Settings, and a faster startup.
The third line was **speed**. The embeddable AI widget stopped creating a visitor session on every page view (it now waits until someone actually reaches for the chat), its script dropped from 3.5 MB to well under a megabyte by loading the PDF viewer only when a PDF appears, login and sign-up stopped waiting on side effects (login p50 373 ms to about 160 ms), the room list loads in three queries instead of one per room, and agents in widget rooms answer without a second model call first.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 40 commits / 26.9.1 → 26.9.6
- **New:** **Message search, in one chat or everywhere.** A search button in the chat header opens a side panel (the conversation narrows instead of being covered) that searches this chat or all chats the user can see, debounced and paged, with sender, date and a highlighted snippet per hit. Tapping a hit switches room if needed and scrolls to the message. Filters by sender and date range, Ctrl/Cmd+F, an entry from the chat profile, and the chat-list search box now searches inside messages too. `config.disableMessageSearch` hides it ([`d4f9720`](https://github.com/dappros/ethora-chat-component/commit/d4f9720), [`344485a`](https://github.com/dappros/ethora-chat-component/commit/344485a), [`c8bcab5`](https://github.com/dappros/ethora-chat-component/commit/c8bcab5))
- **Improved:** **Jumping to an old message actually gets there.** History is loaded back to the found message by archive cursor; when the history cannot reach it the message is shown on its own; toast, push and `?messageId=` links all use the same jump; and a hit names its sender instead of "Someone" ([`4e9cca1`](https://github.com/dappros/ethora-chat-component/commit/4e9cca1), [`a05c0ae`](https://github.com/dappros/ethora-chat-component/commit/a05c0ae), [`57ae1f8`](https://github.com/dappros/ethora-chat-component/commit/57ae1f8), [`1138c6b`](https://github.com/dappros/ethora-chat-component/commit/1138c6b), [`f34ea2f`](https://github.com/dappros/ethora-chat-component/commit/f34ea2f))
- **New:** **Discover chats.** A "Discover chats" entry in the room-list menu lists the app's public chats with avatar, title and description, and offers Join or Open depending on whether the user is already in. It gets its own button and icon when the host hides the menu; `config.disablePublicChatsDirectory` hides it ([`8e143b5`](https://github.com/dappros/ethora-chat-component/commit/8e143b5), [`fb56e7f`](https://github.com/dappros/ethora-chat-component/commit/fb56e7f), [`fa2df94`](https://github.com/dappros/ethora-chat-component/commit/fa2df94))
- **Improved:** **Scrolling history feels continuous.** Older pages are prefetched ahead of the reader and the spinner appears only if the reader reaches the top first; the reader's place is kept when a page lands mid-scroll; a short conversation sits at the bottom of the pane; a room stays pinned to the bottom while it fills in ([`c8bcab5`](https://github.com/dappros/ethora-chat-component/commit/c8bcab5), [`351d8fb`](https://github.com/dappros/ethora-chat-component/commit/351d8fb), [`c55c517`](https://github.com/dappros/ethora-chat-component/commit/c55c517), [`832dc94`](https://github.com/dappros/ethora-chat-component/commit/832dc94))
- **Improved:** **Reconnects fetch a fresh chat credential** from `/v1/users/xmpp-token` instead of retrying the one that just expired; the stream opens to the configured XMPP domain and the configured conference domain is kept, so installs that serve the API, web app and WebSocket from one origin connect cleanly; a message typed while connecting is no longer sent twice ([`d51941f`](https://github.com/dappros/ethora-chat-component/commit/d51941f), [`254c013`](https://github.com/dappros/ethora-chat-component/commit/254c013), [`4f00a2d`](https://github.com/dappros/ethora-chat-component/commit/4f00a2d), [`9aa013a`](https://github.com/dappros/ethora-chat-component/commit/9aa013a))
- **New:** `config.pdfPreview.libUrl` loads the PDF viewer from a URL at runtime, so a host shipping the component as one self-contained script no longer carries 1.7 MB of pdf.js for every visitor ([`71eb06a`](https://github.com/dappros/ethora-chat-component/commit/71eb06a))
- **Fixed:** **Dark-mode and layout polish after 26.9.0.** Room tiles share one height, the header no longer jumps while history loads and follows the pane's rounding, the composer separator no longer glows or curves in dark mode, the room list waits for the panel's exit animation, the inner root takes its theme from the host config, a joining loader replaces "chat isn't available" while a join is in flight, and a web push shows its icon ([`c70b7d6`](https://github.com/dappros/ethora-chat-component/commit/c70b7d6), [`c926290`](https://github.com/dappros/ethora-chat-component/commit/c926290), [`1474c2f`](https://github.com/dappros/ethora-chat-component/commit/1474c2f), [`a17e559`](https://github.com/dappros/ethora-chat-component/commit/a17e559), [`a2e7c56`](https://github.com/dappros/ethora-chat-component/commit/a2e7c56), [`975ae1c`](https://github.com/dappros/ethora-chat-component/commit/975ae1c), [`0a95edb`](https://github.com/dappros/ethora-chat-component/commit/0a95edb), [`5d2e95f`](https://github.com/dappros/ethora-chat-component/commit/5d2e95f), [`0b84b6f`](https://github.com/dappros/ethora-chat-component/commit/0b84b6f))
- **Fixed:** The local chat cache is no longer wiped while the host's config is still loading, which had read as a tenant switch on every cold start ([`9e10f30`](https://github.com/dappros/ethora-chat-component/commit/9e10f30))
- **Milestone:** **`@ethora/chat-component` 26.9.1 through 26.9.6 published** (dark-mode polish 26.9.1-26.9.4 on 29 Sep; message search, Discover chats and the scroll fixes 26.9.5-26.9.6 on 1 Oct) ([`107890b`](https://github.com/dappros/ethora-chat-component/commit/107890b), [`352c525`](https://github.com/dappros/ethora-chat-component/commit/352c525), [`91b0b1c`](https://github.com/dappros/ethora-chat-component/commit/91b0b1c))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 10 commits / 26.8.2 → 26.8.6
- **New:** **Reactions** with an emoji picker sheet on any message ([`4f46d27`](https://github.com/dappros/ethora-chat-component-rn/commit/4f46d27))
- **New:** **Replies and threads** on messages, with a test suite for the reply flow ([`701405f`](https://github.com/dappros/ethora-chat-component-rn/commit/701405f))
- **New:** **Appearance and push in Settings.** Light / Dark / System is persisted per device and reported to the host through `onThemeChange`; a push switch releases and re-registers the device's push tokens on the backend, and the host can hand the SDK an Expo, FCM or APNs token with `registerPushToken` instead of wiring registration itself ([`ac63b71`](https://github.com/dappros/ethora-chat-component-rn/commit/ac63b71), [`404b890`](https://github.com/dappros/ethora-chat-component-rn/commit/404b890))
- **Improved:** **Faster startup and smoother long rooms.** History is fetched in batched pages, each room's messages persist locally in MMKV, and message rendering is memoized ([`1513aab`](https://github.com/dappros/ethora-chat-component-rn/commit/1513aab))
- **Improved:** Keyboard and input-dock layout, header and room-list polish ([`6ed4e81`](https://github.com/dappros/ethora-chat-component-rn/commit/6ed4e81), [`5e6dd6e`](https://github.com/dappros/ethora-chat-component-rn/commit/5e6dd6e))
- **Milestone:** **`@ethora/chat-component-rn` 26.8.3 through 26.8.6 published** ([`9191d23`](https://github.com/dappros/ethora-chat-component-rn/commit/9191d23), [`2a1aa77`](https://github.com/dappros/ethora-chat-component-rn/commit/2a1aa77), [`9e004b5`](https://github.com/dappros/ethora-chat-component-rn/commit/9e004b5))
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 2 commits
- **Improved:** **A visitor session is created when someone reaches for the chat, not on every page view.** The session call (visitor account, room, agent invite) now runs when the launcher is hovered, focused or opened; a page view that never touches the launcher costs nothing. A returning visitor gets the same account and conversation back ([`1e11705`](https://github.com/dappros/ethora-ai-chat-widget/commit/1e11705))
- **Improved:** **`assistant.js` is a fraction of its former size.** The PDF viewer, half of the old 3.5 MB script, is now loaded from the widget host only when a PDF is shown ([`b7d1f59`](https://github.com/dappros/ethora-ai-chat-widget/commit/b7d1f59))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 19 commits / branches 2609 and 2610
- **New:** **Messages and AI tokens tabs in Statistics,** next to Chats and API calls, now that the platform counts chat messages and LLM tokens per app ([`7843baf`](https://github.com/dappros/ethora-app-reactjs/commit/7843baf))
- **Improved:** **A lighter first load.** The statistics page and its charting stack, the wallet sign-on stack and product analytics moved out of the main bundle, and the one-second wait before the app config is published is gone ([`c7ec566`](https://github.com/dappros/ethora-app-reactjs/commit/c7ec566), [`c7fcdd1`](https://github.com/dappros/ethora-app-reactjs/commit/c7fcdd1))
- **Fixed:** **Sign-in edge cases.** A temporary password now leads to the set-password step again, and social sign-up logs in on every host rather than only on allowed domains, ending the provisional session first ([`ce03acd`](https://github.com/dappros/ethora-app-reactjs/commit/ce03acd), [`efbb3aa`](https://github.com/dappros/ethora-app-reactjs/commit/efbb3aa), [`f7ad8f1`](https://github.com/dappros/ethora-app-reactjs/commit/f7ad8f1), [`465366d`](https://github.com/dappros/ethora-app-reactjs/commit/465366d))
- **Testing:** A diagnostics probe for the widget's on-demand session and resume path, which traces outgoing stanzas and detects the agent's reply by sender ([`4773909`](https://github.com/dappros/ethora-app-reactjs/commit/4773909), [`6ff3cb2`](https://github.com/dappros/ethora-app-reactjs/commit/6ff3cb2), [`289f51c`](https://github.com/dappros/ethora-app-reactjs/commit/289f51c))
- **Docs:** Licence links point at the published legal pages on ethora.com ([`7fae3c4`](https://github.com/dappros/ethora-app-reactjs/commit/7fae3c4))
- **Infrastructure:** Chat component pinned through 26.9.4 to the latest 26.9.x ([`850de95`](https://github.com/dappros/ethora-app-reactjs/commit/850de95), [`ca236e2`](https://github.com/dappros/ethora-app-reactjs/commit/ca236e2), [`e4a944f`](https://github.com/dappros/ethora-app-reactjs/commit/e4a944f))
### AI Assistants & MCP (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 12 commits / 26.9.5 → 26.10.0
- **New:** **Account memory on the hosted server.** The selected app and agent and the enabled tool groups are kept per signed-in account for 24 hours and restored into every new session, so clients that open a new session per tool call (ChatGPT does) keep their context; a newly created app becomes the current app, and an account with one app has it selected automatically ([`9c78321`](https://github.com/dappros/ethora-mcp-server/commit/9c78321))
- **New:** **A ChatGPT plugin package** for the OpenAI directory, with a checked build, the current Ethora mark and review materials; the Claude plugin bundle's version now follows the package ([`a386889`](https://github.com/dappros/ethora-mcp-server/commit/a386889), [`10d4dd4`](https://github.com/dappros/ethora-mcp-server/commit/10d4dd4), [`dbdc48d`](https://github.com/dappros/ethora-mcp-server/commit/dbdc48d), [`8820c05`](https://github.com/dappros/ethora-mcp-server/commit/8820c05))
- **Improved:** **Tool hints that match what tools do.** Tools that overwrite say so and carry the destructive hint, session-only tools are marked read-only, and the `admin` scope is required by irreversible operations by name, so a read+write grant can still edit agents and apps ([`56ab88a`](https://github.com/dappros/ethora-mcp-server/commit/56ab88a))
- **Improved:** **100/100 on the HOL plugin scanner,** the scan the Awesome AI Plugins catalog runs, now part of CI; credential placeholders in recipes and errors are built at runtime ([`2f123a3`](https://github.com/dappros/ethora-mcp-server/commit/2f123a3), [`490ec8a`](https://github.com/dappros/ethora-mcp-server/commit/490ec8a), [`1b38c06`](https://github.com/dappros/ethora-mcp-server/commit/1b38c06), [`1b22807`](https://github.com/dappros/ethora-mcp-server/commit/1b22807))
- **Milestone:** **`@ethora/mcp-server` 26.10.0 published** on release day, the first version of the 26.10 line ([`5e0599c`](https://github.com/dappros/ethora-mcp-server/commit/5e0599c), [`51209db`](https://github.com/dappros/ethora-mcp-server/commit/51209db))
### Platform API & AI Service (`platform`)
> Platform API and AI service | 39 commits (2609 and 2610)
- **Improved:** **Login, sign-up and app creation stop waiting on side effects.** The response waits only for the lookup, the password check and the token; session rows, counters and chat-server registration run in the background (login p50 373 ms to about 160 ms on a production install). Web3 steps run only when blockchain is enabled.
- **Improved:** **A cheaper request path.** The OpenAPI spec is built once and served with an ETag, audit writes are deferred to one per request, apps are cached, and the logs collection is indexed; the room list loads chats, memberships and members in three queries instead of one round trip per room, and carries member counts.
- **Improved:** **Faster agent replies in widget rooms and DMs.** An agent in smart mode no longer asks the model whether a message is meant for it when it is the only possible addressee, removing a model round trip before every reply; widget rooms are no longer persisted for replay, restart replay is bounded, and duplicate stanzas are ignored.
- **New:** **Widget visitors resume their own room,** and anonymous widget visitors are counted separately from sign-ups in the stats emails, which now open with an activity summary (who was active, how much was said, what the AI agents did, which apps drove it).
- **New:** **Chat messages and LLM tokens are counted per app** and returned by the statistics endpoint.
- **Improved:** Startup fails fast with a readiness probe, SIGTERM shuts down gracefully, and the push and AI services log JSON lines in the same shape as the API. The public ping summary includes the licence tier and caps.
- **Fixed:** Revoking sessions counts only unexpired ones; OAuth loopback redirect URIs match regardless of port (RFC 8252 §7.3); the seed owner account is bootstrap only.
- **New:** A room reconcile script recreates chat rooms from the platform's record on an existing install (see Chat Server below).
### Chat Server & Deployment (`platform`)
> ejabberd image and deployment tooling | 88 commits
- **Milestone:** **Release 26.10 shipped 1 October** and became the production line on 2 October; the Helm chart and store packages carry 26.10.0.
- **New:** **Ethora Core packaged for a dozen one-click platforms.** An AWS Marketplace AMI baked from the public installer and Docker Hub images (with an optional Elastic IP for unattended launch); a DigitalOcean 1-Click image with its image check; an Azure Marketplace image; a Vultr image and a Linode StackScript for the Akamai Marketplace; a Helm chart published to Docker Hub's OCI registry and Artifact Hub; a single-file Docker Compose project; and Cloudron, Umbrel and CasaOS store packages, plus Coolify, Dokploy and Portainer guides. Marketplace listing texts point at the published legal pages.
- **Improved:** **A one-line public installer.** `get.sh` bootstraps from a terminal or a pipe, the installer README is written for outsiders, re-running setup reconfigures an existing install instead of regenerating its secrets, and image-mode updates need no component sources on the host.
- **Improved:** **Chat rooms keep their full names in the database.** The chat-server schema indexes room names to 191 characters, and the update step widens existing databases and reconciles any rooms missing from the chat server against the platform's record.
- **Improved:** Static assets are compressed at the web tier, the widget host serves the PDF viewer, default-room membership can follow activity, and the monitoring stack's log scraping and dashboards were fixed.
- **Docs:** The final Ethora server legal set (licence, feature schedule, support policy, privacy and telemetry, enterprise EULA, third-party notices), effective 29 September, ships with the installer and the images; operator notes on the on-demand widget visitor and the agent replay cap.
### Monitoring (`uptime`)
> [ethora-uptime](https://github.com/dappros/ethora-uptime) | 2 commits
- **Improved:** Journey checks hard-delete their synthetic app on teardown instead of archiving it ([`05cce22`](https://github.com/dappros/ethora-uptime/commit/05cce22))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 2 commits (plus daily submodule bumps)
- **Docs:** Week 39 release notes; the README's SDK platform description refreshed ([`7e72e7e`](https://github.com/dappros/ethora/commit/7e72e7e), [`0f2cf1b`](https://github.com/dappros/ethora/commit/0f2cf1b))
---
## Week 39 (Sep 21 – 27, 2026) — Accounts get a second factor and admins get a Users page that shows who can do what; dark mode across web, mobile and the admin console; encrypted rooms become a per-app choice with sealed attachments; Ethora Core defines the free self-hosted tier
**Contributors:** Taras Filatov, Roman Leshchuh, Borys Bordunov, Dmytro Berberov
**Total commits:** 82 across SDK/app repos + 116 platform/server | **Active repos:** 10
### Theme
Three lines converged this week, and all three answer a question a regulated buyer asks before signing. **Account security**: every account can now turn on TOTP two-step verification with backup codes, change or set its own password (including accounts that only ever signed in with Google or a wallet), and the second factor is enforced whichever first factor was used. On the admin side, the Users page grew Role and MFA columns, an admin-access filter, tag filters, sortable columns, an Edit user form, and a permissions dialog that speaks in seven plain capabilities instead of a 25-cell grid. Installs without outbound email are no longer stuck: temporary passwords are shown once to the admin, and a host-side recovery script restores a locked-out superadmin.
**Dark mode arrived everywhere at once.** The web chat SDK gained a `light` / `dark` / `system` colour scheme and shipped it as 26.9.0 a day after the request; the React Native SDK gained `config.dark` with a full dark palette; the admin console gained an Appearance tab with the same three choices and now themes the embedded chat to match.
**Encryption became an app owner's decision rather than an operator's switch.** End-to-end encrypted rooms are opted into per app in App Settings, an encrypted 1:1 chat is a separate room next to the plaintext one, and attachments in those rooms are sealed in the browser before upload so the server stores only opaque bytes. The scope is stated plainly in the code and should be stated plainly to customers: the message text and file contents are protected; sender, room, reply and mention metadata stay readable so push notifications and room administration keep working. Alongside this, the self-hosted line defined **Ethora Core**, a free tier with no licence key and no expiry, and the deployment tooling learned to install from prebuilt images alone.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 36 commits / 26.8.1 → 26.9.0
- **New:** **Dark and system colour scheme.** `config.colorScheme: 'light' | 'dark' | 'system'`; the default renders exactly as before, `system` follows the OS preference and updates live. The theme builder swaps surfaces, text, borders and the chat background for a dark palette, publishes new tokens for brand-as-text, overlays and icon chips, and applies the scheme to every element the chat themes including the language modal and in-app notifications. A review pass then stopped a host's light `secondary` colour bleeding into dark chips and made the outer and inner roots agree on the scheme when a host drives the chat through the store ([`dd4dbe5`](https://github.com/dappros/ethora-chat-component/commit/dd4dbe5), [`02cb778`](https://github.com/dappros/ethora-chat-component/commit/02cb778))
- **New:** **Encrypted 1:1 chats, started from the profile drawer.** An "Encrypted message" action opens (or creates) the pair's encrypted room, which is a room of its own so the plaintext history stays where it was written. The action renders only when `config.e2ee.enabled` is on ([`5d0a7e9`](https://github.com/dappros/ethora-chat-component/commit/5d0a7e9))
- **New:** **Sealed attachments in encrypted rooms.** Files are encrypted in the browser with a fresh key per file, uploaded as opaque bytes under a random name with the `clientEncrypted` flag, and the real name and type travel inside the seal. On the receiving side a sealed file renders as a lock card with its size; nothing is fetched until it is clicked, the file is decrypted and handed to the browser under its real name, and the object URL is revoked immediately so plaintext is not retained. The room list no longer calls every sealed file "audio", and a file that will not open says which step failed ([`6e5536a`](https://github.com/dappros/ethora-chat-component/commit/6e5536a), [`a6aa3b9`](https://github.com/dappros/ethora-chat-component/commit/a6aa3b9), [`639de20`](https://github.com/dappros/ethora-chat-component/commit/639de20), [`f7b90b2`](https://github.com/dappros/ethora-chat-component/commit/f7b90b2), [`c2e1281`](https://github.com/dappros/ethora-chat-component/commit/c2e1281), [`90b0fb5`](https://github.com/dappros/ethora-chat-component/commit/90b0fb5))
- **Improved:** **The encryption envelope covers the message body only, and says so.** `<data>` (sender name, avatar, room name, reply and mention references) is appended in the clear so the server can still build push notifications; the commit records the trade-off in full. A companion fix closed the send path used when translation is enabled, which had bypassed the encryption seam entirely ([`4cfecf3`](https://github.com/dappros/ethora-chat-component/commit/4cfecf3), [`a36865f`](https://github.com/dappros/ethora-chat-component/commit/a36865f))
- **Fixed:** **Cold-start and recovery banners.** The "Connection lost" banner no longer flashes for two seconds on every first connect (the client now knows the difference between never-yet-online and dropped), and token-expiry recovery no longer stalls on a spinner ([`55d0692`](https://github.com/dappros/ethora-chat-component/commit/55d0692), [`ba17b87`](https://github.com/dappros/ethora-chat-component/commit/ba17b87))
- **Fixed:** **Display names.** A failed profile lookup was cached forever, so a brand-new user's messages showed a raw XMPP id until a reload; failures are now held briefly and retried, a nameless entry is no longer mistaken for a name, and an opaque id never sticks as a display name ([`42941e6`](https://github.com/dappros/ethora-chat-component/commit/42941e6), [`dbd7182`](https://github.com/dappros/ethora-chat-component/commit/dbd7182), [`4ebb3d0`](https://github.com/dappros/ethora-chat-component/commit/4ebb3d0), [`91dd4e9`](https://github.com/dappros/ethora-chat-component/commit/91dd4e9))
- **Fixed:** A newly created private room now appears live in the invitee's list instead of after a reload: the placeholder is no longer pruned as corrupt, and the rooms cache is invalidated before the corrective fetch ([`281dff3`](https://github.com/dappros/ethora-chat-component/commit/281dff3), [`250b850`](https://github.com/dappros/ethora-chat-component/commit/250b850))
- **Fixed:** **Files tab.** Deleting a file now tombstones the chat message that carried it instead of leaving a broken image, the retraction waits until the file is really gone, and the list layout and raw room id are corrected; the right-click context menu stays inside the viewport ([`d18db41`](https://github.com/dappros/ethora-chat-component/commit/d18db41), [`7840c7c`](https://github.com/dappros/ethora-chat-component/commit/7840c7c), [`0c7946f`](https://github.com/dappros/ethora-chat-component/commit/0c7946f), [`a13a55c`](https://github.com/dappros/ethora-chat-component/commit/a13a55c))
- **Fixed:** **Media bubbles.** The voice-note bubble now draws a waveform built from per-bucket RMS scaled to the 95th percentile (so two loud clicks no longer flatten the rest) and shows the true duration; a sent attachment no longer keeps reading its optimistic placeholder after the upload finished ([`7119b83`](https://github.com/dappros/ethora-chat-component/commit/7119b83), [`5a88c78`](https://github.com/dappros/ethora-chat-component/commit/5a88c78))
- **Refactored:** In-place playback of sealed voice notes was tried and reverted the next morning; sealed voice notes render as the download chip like every other sealed file ([`9e8806d`](https://github.com/dappros/ethora-chat-component/commit/9e8806d), [`08d018b`](https://github.com/dappros/ethora-chat-component/commit/08d018b))
- **Testing:** The dev harness takes a second account from the environment so two-user scenarios can be driven locally ([`d66b912`](https://github.com/dappros/ethora-chat-component/commit/d66b912), [`a3451a6`](https://github.com/dappros/ethora-chat-component/commit/a3451a6))
- **Milestone:** **`@ethora/chat-component` 26.8.2** (the combined QA fix batch) **and 26.9.0** (dark scheme and encrypted uploads) **published** ([`861a97d`](https://github.com/dappros/ethora-chat-component/commit/861a97d), [`2ee3e6a`](https://github.com/dappros/ethora-chat-component/commit/2ee3e6a), [`6d997ba`](https://github.com/dappros/ethora-chat-component/commit/6d997ba), [`ed0e8e1`](https://github.com/dappros/ethora-chat-component/commit/ed0e8e1))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 5 commits / 26.8.1 → 26.8.2 (release branch) + dark theme on `main`
- **New:** **Dark theme.** `config.dark` switches the whole component (room list, headers, conversation, bubbles, composer, attach sheet, context menus, modals) to a dark palette, and `config.darkColors` overrides any of it; covered by a theme test suite ([`ab90fbe`](https://github.com/dappros/ethora-chat-component-rn/commit/ab90fbe))
- **Fixed:** The room-list title is localised and hero action labels no longer wrap; re-running bootstrap with the same key no longer flips a ready provider to failed ([`fd671de`](https://github.com/dappros/ethora-chat-component-rn/commit/fd671de), [`82210ec`](https://github.com/dappros/ethora-chat-component-rn/commit/82210ec))
- **Milestone:** **`@ethora/chat-component-rn` 26.8.2 published** — the translation fixes rebased onto the 26.7.10 line ([`eb2908f`](https://github.com/dappros/ethora-chat-component-rn/commit/eb2908f), [`8462bc1`](https://github.com/dappros/ethora-chat-component-rn/commit/8462bc1))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 27 commits / branches 2609 and 2610
- **New:** **Account > Security.** Change your password (other devices are signed out, the current session stays); enrol in two-step verification with a QR code or manual key, confirm with the first code, receive ten backup codes shown once, regenerate them, or turn it off with password plus code. Sign-in gains a second step (six-digit or backup code, five-minute countdown) when the account has MFA, and an app policy can send administrators to enrol before they continue ([`68508a9`](https://github.com/dappros/ethora-app-reactjs/commit/68508a9))
- **New:** **Password for social accounts, and MFA on every first factor.** Accounts that only ever signed in with Google, Facebook, Apple or a wallet can set a password after a fresh proof of identity, either "Confirm with Google" or an authenticator code; a reset link appears when the install can send mail; and the Google and wallet buttons hand off to the same MFA step as the password form ([`f01d31e`](https://github.com/dappros/ethora-app-reactjs/commit/f01d31e), [`7534aad`](https://github.com/dappros/ethora-app-reactjs/commit/7534aad))
- **New:** **Users page rebuilt for administrators.** Role (Superadmin / Owner / Admin / Member) and MFA columns; an "Admin access" filter for auditing who can manage the app; bulk "Remove admin access" with a confirm step that keeps the account and its chats; sortable compact columns including Tags and Role; a tag filter; Manage Tags as add/remove; an Edit user form; and auth-method titles ([`ca906d7`](https://github.com/dappros/ethora-app-reactjs/commit/ca906d7), [`dd2700d`](https://github.com/dappros/ethora-app-reactjs/commit/dd2700d), [`c9fb61e`](https://github.com/dappros/ethora-app-reactjs/commit/c9fb61e), [`39ae129`](https://github.com/dappros/ethora-app-reactjs/commit/39ae129), [`226c35a`](https://github.com/dappros/ethora-app-reactjs/commit/226c35a))
- **New:** **Permissions in plain words.** The five-by-five ACL grid is replaced by seven named capabilities (see this app, change settings, view users, manage users, remove users, manage permissions of others, send push, view statistics) with role presets on top, and a separate platform-access dialog for superadmins covers superadmin, AI-agent creation and network statistics per user. "View users" stands on its own so an Analyst can read the list without managing it. Strings in en, fr and es ([`64a9185`](https://github.com/dappros/ethora-app-reactjs/commit/64a9185), [`a20de8c`](https://github.com/dappros/ethora-app-reactjs/commit/a20de8c), [`4826530`](https://github.com/dappros/ethora-app-reactjs/commit/4826530))
- **New:** On installs without outbound email, "Reset password" shows the temporary passwords once, with a copy button, instead of silently dropping the email ([`a9e92f5`](https://github.com/dappros/ethora-app-reactjs/commit/a9e92f5))
- **New:** **MCP onboarding that asks where the key will be used.** The AI Assistants tab shows exact steps for Claude.ai, ChatGPT, Claude Desktop, Cursor, VS Code or Claude Code, one-click installers for Cursor and VS Code, a note where a free plan has nowhere to paste a connector, a live "Connected" status per key once it has been used, and a Regenerate action; the onboarding modal, the Help card and the admin footer all lead to it ([`7f30e3c`](https://github.com/dappros/ethora-app-reactjs/commit/7f30e3c), [`70e59f4`](https://github.com/dappros/ethora-app-reactjs/commit/70e59f4))
- **New:** **Appearance tab and dark theme.** Light / dark / system for the console, neutral colours moved to CSS variables, and the Account tabs regrouped into Appearance, Security, AI Assistants, Privacy & Data and Documents (old tab links still land in the right place). The embedded chat component follows the console's theme ([`1acc23c`](https://github.com/dappros/ethora-app-reactjs/commit/1acc23c), [`2b6a0f2`](https://github.com/dappros/ethora-app-reactjs/commit/2b6a0f2), [`c3e8baa`](https://github.com/dappros/ethora-app-reactjs/commit/c3e8baa), [`05ddf7c`](https://github.com/dappros/ethora-app-reactjs/commit/05ddf7c), [`e9bdd46`](https://github.com/dappros/ethora-app-reactjs/commit/e9bdd46))
- **New:** **License page for the Core tiers.** Shows the edition (Core unregistered, Core, Enterprise, Enterprise trial), apps and accounts used against the caps, the packages the key includes and the support channel; an unregistered install can register for the free Core key from the page. The footer shows the edition and backend build, the console is no longer locked in any licence state, and the banner appears only during a grace period; the frontend image carries the licence texts ([`986c7e3`](https://github.com/dappros/ethora-app-reactjs/commit/986c7e3), [`c279970`](https://github.com/dappros/ethora-app-reactjs/commit/c279970), [`d9e2515`](https://github.com/dappros/ethora-app-reactjs/commit/d9e2515))
- **New:** **Per-app toggle for end-to-end encrypted chats** under App Settings > Chats, shown only where the install supports it, ANDed with the install-level flag so both gates have to be open; the help text says what an encrypted room gives up (moderation, search, export, recovery) ([`5a0897f`](https://github.com/dappros/ethora-app-reactjs/commit/5a0897f), [`1aa6b61`](https://github.com/dappros/ethora-app-reactjs/commit/1aa6b61))
- **Infrastructure:** Chat component pinned to 26.8.2; the nginx runtime stage upgrades its packages at build ([`22beeed`](https://github.com/dappros/ethora-app-reactjs/commit/22beeed), [`27b7230`](https://github.com/dappros/ethora-app-reactjs/commit/27b7230), [`8af9778`](https://github.com/dappros/ethora-app-reactjs/commit/8af9778))
### AI Assistants & MCP (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 9 commits / 26.9.3 → 26.9.5
- **Improved:** **A core profile by default.** A session lists 24 core tools (one variant per operation) instead of all ~90; the other groups stay registered and are enabled per session with `ethora-tools-enable`, or automatically when a hidden tool is called by name, so nothing is ever refused. The tool list drops from ~120 KB to ~40 KB ([`b9bc38a`](https://github.com/dappros/ethora-mcp-server/commit/b9bc38a))
- **Improved:** **One naming rule for every tool**: `ethora-<resource>-<verb>[-<qualifier>]`, singular resource, verb last, no `-v2` suffixes; three auth switches became one `ethora-auth-mode-set`. Every earlier name keeps working as an unlisted alias rewritten to the canonical tool, so no client has to change anything ([`d75acce`](https://github.com/dappros/ethora-mcp-server/commit/d75acce))
- **New:** **Newcomer journeys.** Help goals for `new-app`, `in-app-chat` and `multi-agent-room` with the calls in order; uniform `created` / `next` envelopes on app, chat and agent creation; named senders on message and history rows; a search intent layer that maps beginner phrasings to the right document; and a `doc:not-available` guide that says what is not exposed over MCP and where to do it instead ([`27ce53f`](https://github.com/dappros/ethora-mcp-server/commit/27ce53f))
- **New:** A browser opening `/` or `/mcp` gets a human landing page (what this is, how to connect, per-client steps), light and dark; MCP clients and the discovery document are unchanged. Outbound API calls carry the assistant behind the session so the platform can show which client last used a key ([`6ae31d4`](https://github.com/dappros/ethora-mcp-server/commit/6ae31d4), [`83b4f4b`](https://github.com/dappros/ethora-mcp-server/commit/83b4f4b))
- **Milestone:** **Calendar versioning enforced.** 26.9.4, then 27.0.0 and 27.1.0, then 26.9.5 in one night: the two 27.x numbers broke the `YY.M.patch` scheme and would have sorted above every future release, so 26.9.5 republished the same code and the 27.x versions are deprecated on npm and in the registry. The version-sync step now refuses any number outside the current month, and a deprecate workflow marks versions on both registries ([`878f98b`](https://github.com/dappros/ethora-mcp-server/commit/878f98b), [`f6524ed`](https://github.com/dappros/ethora-mcp-server/commit/f6524ed))
- **Infrastructure:** The container builds and runs on Node 24; workflow actions are pinned to commit SHAs with Dependabot keeping them current ([`f6fe83c`](https://github.com/dappros/ethora-mcp-server/commit/f6fe83c), [`3dac9e1`](https://github.com/dappros/ethora-mcp-server/commit/3dac9e1))
### Platform API & Identity (`platform`)
> Platform API and AI service | 65 commits
- **New:** **Self-service password change and TOTP multi-factor authentication.** Changing a password ends every other interactive session while keeping API keys and OAuth grants; MFA enrolment parks the secret as pending until the first code confirms it, issues ten one-shot backup codes, and requires the current password on top of the session for enrol and disable, so a hijacked session cannot take over the second factor. Login stops after the password check for MFA accounts and completes through a short-lived pending token.
- **New:** **MFA on social and wallet logins, and a first password for password-less accounts.** Google, Facebook, Apple and wallet sign-ins stop after the first factor for MFA-enabled accounts, and the completed login records which first factor was used. An account that never had a password sets one after a fresh proof of identity: a provider re-authentication verified server-side against the account email, or an MFA code.
- **New:** **A users list built for auditing.** Each row carries a derived role (superadmin, owner, admin, member) and MFA state; an admin-access filter narrows to users who hold a management grant; sorting by auth method, MFA and tags with stable paging; a tag filter; and a tags endpoint listing the tags in use with counts. The CSV export gains the same columns.
- **New:** **Capabilities and platform access.** Superadmin grant and revoke from the panel with audit events; a per-user platform-access endpoint for the base app covering superadmin, AI-agent creation and network statistics; a standalone "view users" grant that the users list, tags, CSV export and message search check; and settings read included in every ACL grant.
- **New:** **Recovery without outbound email.** A host-side admin-reset script restores a locked-out superadmin, and the two reset flows now say what actually happened: an install that cannot send mail returns the temporary passwords to the administrator instead of reporting success.
- **New:** **Last-used tracking for API keys and OAuth grants.** Each authenticated request stamps the key or grant with when and by which client it was last used, throttled to one write a minute and off the request path, so a never-used key can be shown as such.
- **New:** **Encrypted rooms as an app-level choice.** `e2eeEnabled` on the app (off by default, carried to clients in the app config); encrypted pair chats as their own room alongside the plaintext one, idempotent per variant; a `clientEncrypted` upload flag that stores the payload verbatim with no preview, probe or mimetype branch; and server-side creation of a private chat between two app users by an integration backend or app admin, plaintext or encrypted.
- **New:** **Ethora Core tiers.** No valid key now means Core (unregistered): five apps and 500 accounts per server, Core features, no countdown and nothing locked. Free registration raises the caps to ten apps and 5,000 accounts. Enterprise and trial keys keep their features; an expired key keeps its entitlements for the 14-day grace and then falls back to Core instead of restricting the install. Caps are enforced on creation and counted fresh on every request. The licence endpoint reports tier, limits and usage, and the API image carries the licence texts.
- **Improved:** Signing out other devices now counts token families rather than rotated rows, so "N other sessions were signed out" is the real number. Rejected requests log their error message and code, and request logging moved to structured JSON lines with per-request ids and durations.
- **Refactored:** **A strict TypeScript gate, grown one file at a time.** A check-only strict config over a hand-kept allowlist runs in CI beside the existing typecheck; utilities, MFA helpers, the User, App, chat, room and log models and the first controllers moved onto it, and TypeScript went to 5.9. Ten unused legacy routes and modules were removed along with the unused passport strategies.
- **Docs:** Four Swagger blocks that failed to parse were repaired; the users list parameters and the tags endpoint are documented.
### Licensing Service (`platform`)
> Standalone licence service | 2 commits
- **New:** **Free Core registration.** A registration page and endpoint issue one perpetual Core key per domain (the same email re-issues, another is refused); the root now leads to registration, with the enterprise trial form kept alongside.
- **New:** A self-service trial page shows the issued key with its deployment snippet and emails it to the requester; every issued key is announced to the team's chat and an ops mailbox.
### Chat Server & Deployment (`platform`)
> ejabberd image and deployment tooling | 51 commits
- **Improved:** The pubsub and connection shaper settings that predate encryption were adjusted so OMEMO 2 key exchange fits within them, on every config the installer actually mounts.
- **New:** **A chat-server image that ships compiled modules only.** Every custom module is compiled at build time, debug information is stripped so the beams cannot be decompiled, no Erlang sources ship in the image, and the deploy-side files are carried under a distribution directory so a host without the checkout can extract them.
- **New:** **Image-mode installs without component sources on the host.** The API image carries its one-off scripts and runs them from inside the container; the AI module, push worker, SDK playground and MCP server all have images behind compose profiles; the chat server has an image mode; and a fresh-host install from the public installer repository and the published images was completed end to end, which surfaced and fixed the remaining source-tree assumptions.
- **New:** **Ethora Core edition in the installer.** `setup.sh --edition core` enables the API, admin panel and chat server with every optional module off and points the image references at a public registry; the release workflow numbers each run `<line>.<n>` from git tags, tags every image with it, and can push the Core images when the publishing secrets are present. The Core licence texts are staged into the API, frontend and chat-server images and the installer prints the acceptance line. A separate public install repository now receives the deployment files and operator docs per release line, with no component source.
- **New:** The AWS image template validates and can build the API and frontend on the builder host when no registry token is available, with a scoped IAM policy for a dedicated builder user.
- **Docs:** The deploy README was split into runbooks (backup and restore, snapshot migration, offline tarball, troubleshooting), plus a one-page operator quick start, per-release operator release notes for 2607 to 2610, a first-login security practice for the superadmin account, the Core tiers reference, the calendar-version rule for published packages, and the encryption install gate with what an operator gives up in an encrypted room.
- **Fixed:** MinIO is pulled from a pinned copy the team controls, since the public tags disappeared from both Docker Hub and Quay in the same week; the push image runs the worker command; the deploy script self-heals git-over-SSH under sudo and renders the JWT key before compose.
### Monitoring & SDK Playground
> [ethora-uptime](https://github.com/dappros/ethora-uptime) 1 commit | [ethora-sdk-playground](https://github.com/dappros/ethora-sdk-playground) 2 commits
- **Fixed:** The group-chat echo check no longer fails on every other run: the probe waited for the destroyed room's process to unregister before recreating it ([`86556cf`](https://github.com/dappros/ethora-uptime/commit/86556cf))
- **Improved:** The SDK playground moved to Next 15.5 and React 19 ([`e5a7257`](https://github.com/dappros/ethora-sdk-playground/commit/e5a7257), [`6a21fe1`](https://github.com/dappros/ethora-sdk-playground/commit/6a21fe1))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 1 commit (plus daily submodule bumps)
- **Docs:** Week 38 release notes ([`64118582`](https://github.com/dappros/ethora/commit/64118582))
---
## Week 38 (Sep 14 – 20, 2026) — The hosted MCP server goes live behind OAuth; self-hosting gains licence keys and a container image; the web chat SDK ships its cold-start and accessibility round
**Contributors:** Roman Leshchuh, Taras Filatov, Yurii T.
**Total commits:** 130 across SDK/app repos + 31 platform/server | **Active repos:** 7
### Theme
The week's centre of gravity was **making Ethora something an AI assistant can drive**. The MCP server stopped being a command-line tool you install and became a hosted service you connect to: Streamable HTTP transport, per-session isolation, a personal connector URL, and a full OAuth 2.1 authorization server built into the platform so a user signs in on an Ethora consent page instead of pasting a secret into someone else's product. Four releases went out in five days, the agent **Flows** capability that shipped last week was exposed through MCP with an authoring reference, and a docs corpus was added so an assistant can look things up instead of guessing.
Two other lines ran in parallel. **Self-hosting grew a commercial spine**: offline-verifiable licence keys with grace and restricted states, a licence page in the admin console, a container image for the API with an optional bytecode stage, runtime configuration for the frontend so one prebuilt image serves any install, and a new licence service to issue and renew keys. And the **web chat SDK** had its biggest single week of the year: the profile panels became a real third column instead of an overlay, the room list learned to seed itself from the API so it is never blank, the cold-start empty states stopped lying, and a contrast sweep took the default palette to WCAG AA.
### AI Assistants & MCP (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 46 commits / 26.9.0 → 26.9.3
- **New:** **Hosted mode over Streamable HTTP.** The server can now run as a shared, long-lived service alongside the platform instead of only as a local command-line process. Session state is kept per connection, so one client's sign-in never reaches another, and idle sessions are evicted on a four-hour timer. The endpoint accepts a bearer credential and binds the session to whatever kind it is — a user token, an API key, an app token or a server token — so the same surface serves a person in Claude and a machine in CI ([`3a3e855`](https://github.com/dappros/ethora-mcp-server/commit/3a3e855), [`9e16c09`](https://github.com/dappros/ethora-mcp-server/commit/9e16c09))
- **New:** **Two ways to connect without a login step.** A personal connector URL carries the API key in the path, which is what URL-only clients such as Claude.ai and ChatGPT custom connectors need; and an OAuth-protected entry point returns a proper challenge, publishes its resource metadata, validates the token against the platform once per session and enforces the granted scope per tool, hiding identity tools from a grant that did not ask for them. Request URLs are never logged, since the personal URL is itself a credential ([`dce199f`](https://github.com/dappros/ethora-mcp-server/commit/dce199f), [`73c53df`](https://github.com/dappros/ethora-mcp-server/commit/73c53df))
- **New:** **Agent flows are reachable from an assistant.** The scripted-conversation YAML that shipped last week is now accepted on agent create and update through MCP, with an authoring reference in the docs corpus so a model writes a valid script rather than inventing a syntax. Opening menus, appointment requests and intake questionnaires can now be built end to end from Claude, ChatGPT or Cursor ([`e131cfb`](https://github.com/dappros/ethora-mcp-server/commit/e131cfb))
- **New:** **`search` and `fetch` over a built-in docs corpus.** Auth map, quickstarts, recipes, a hosted getting-started guide, an API-keys guide and one reference entry per tool with its inputs and annotations. The `initialize` response now also returns instructions tailored to how the client connected, so an assistant knows the status, sign-in and app-selection ordering before its first call ([`9e16c09`](https://github.com/dappros/ethora-mcp-server/commit/9e16c09), [`6695ccc`](https://github.com/dappros/ethora-mcp-server/commit/6695ccc))
- **New:** **A widget embed tool.** `ethora-widget-embed-snippet` emits the ready-to-paste script tag for the website chat widget with its prerequisites spelled out, and agent activation now works from an ordinary user session, so "give my site an AI assistant" is a single conversation rather than a trip through the admin panel ([`ef8e616`](https://github.com/dappros/ethora-mcp-server/commit/ef8e616))
- **New:** **Report a problem from inside the session.** `ethora-feedback-submit` sends a report with the last few tool failures attached automatically, so it joins to the server-side log instead of arriving as a paraphrase. It works anonymously and is exempt from scope checks, because the person most worth hearing from is the one whose sign-up is what broke. Outbound calls now also carry client and tool attribution headers, so assistant traffic can be counted separately from the web app ([`05233f5`](https://github.com/dappros/ethora-mcp-server/commit/05233f5))
- **New:** **A Claude Code plugin.** A second distribution channel alongside the connector directory: it declares the hosted server over HTTP and ships a marketplace manifest and setup notes, so a developer installs it with one command and signs in through the consent page rather than pasting a credential ([`6a1e75e`](https://github.com/dappros/ethora-mcp-server/commit/6a1e75e), [`957f518`](https://github.com/dappros/ethora-mcp-server/commit/957f518))
- **Improved:** **Every tool now carries a human title and explicit behaviour hints** (read-only, destructive, open-world), the discovery document publishes its auth modes, vendor and contact as structured data, and the hosted surface deliberately excludes the wallet tools, which stay available to the local command-line process only ([`1e96863`](https://github.com/dappros/ethora-mcp-server/commit/1e96863), [`9b10827`](https://github.com/dappros/ethora-mcp-server/commit/9b10827), [`78e8840`](https://github.com/dappros/ethora-mcp-server/commit/78e8840))
- **Improved:** **Credentials are redacted from every tool result.** App secrets, tenant secrets, app tokens and passwords are replaced at any depth, with an exception only for the handful of tools whose job is to hand a credential over once. A separate tool reveals an app token deliberately, under admin scope, and the App Secret is never returned over MCP at all. Bare token-shaped key names are covered too ([`0c37fab`](https://github.com/dappros/ethora-mcp-server/commit/0c37fab), [`42d04c0`](https://github.com/dappros/ethora-mcp-server/commit/42d04c0))
- **Improved:** **Errors say what to do next.** A sweep of all tools replaced masked failures with the API's own message, gave every class of validation, precondition and authorisation problem a real code instead of a generic internal error, and made the app-selection messaging uniform so a model that picked the wrong app is told so plainly. The agent-import bundle is typed, so a malformed bundle is rejected before it reaches the network ([`8bd86ff`](https://github.com/dappros/ethora-mcp-server/commit/8bd86ff), [`9b10827`](https://github.com/dappros/ethora-mcp-server/commit/9b10827), [`88d66f6`](https://github.com/dappros/ethora-mcp-server/commit/88d66f6), [`4938df1`](https://github.com/dappros/ethora-mcp-server/commit/4938df1))
- **Fixed:** Agents, rooms and message tools work in ordinary user mode, and several message and history routes that pointed at retired endpoints were rewired. A sweep closed an app-update field mismatch, crawl polling, a legacy widget 404, agent id aliases and a header auth override ([`2d45e3d`](https://github.com/dappros/ethora-mcp-server/commit/2d45e3d), [`e260232`](https://github.com/dappros/ethora-mcp-server/commit/e260232))
- **Docs:** README rewritten for the hosted server (entry points, auth modes, the agent journey, environment, troubleshooting), one-click install buttons that point at the hosted server over HTTPS redirectors, LM Studio added to the supported clients, and a security policy and container notes added ([`8dd81eb`](https://github.com/dappros/ethora-mcp-server/commit/8dd81eb), [`3e7e23a`](https://github.com/dappros/ethora-mcp-server/commit/3e7e23a), [`a0f8e65`](https://github.com/dappros/ethora-mcp-server/commit/a0f8e65), [`425b4b8`](https://github.com/dappros/ethora-mcp-server/commit/425b4b8), [`1b22812`](https://github.com/dappros/ethora-mcp-server/commit/1b22812))
- **Infrastructure:** Publishing to npm and the registry now runs from CI with loud failure on a bad token and a retry on registry verification, a Dockerfile was added, and the security scan moved to the open-source scanner CLI ([`08fc838`](https://github.com/dappros/ethora-mcp-server/commit/08fc838), [`62c4953`](https://github.com/dappros/ethora-mcp-server/commit/62c4953), [`e16c0f2`](https://github.com/dappros/ethora-mcp-server/commit/e16c0f2), [`b13339b`](https://github.com/dappros/ethora-mcp-server/commit/b13339b), [`afb4c36`](https://github.com/dappros/ethora-mcp-server/commit/afb4c36))
- **Milestone:** **`@ethora/mcp-server` 26.9.0, 26.9.1, 26.9.2 and 26.9.3 published** — 26.9.0 fixed a version scheme that could not be published at all, 26.9.1 carried hosted mode, API keys, the OAuth entry point and the widget tool, and 26.9.2 and 26.9.3 carried the compliance, redaction and feedback rounds ([`5e5058e`](https://github.com/dappros/ethora-mcp-server/commit/5e5058e), [`f9e5da8`](https://github.com/dappros/ethora-mcp-server/commit/f9e5da8), [`6f86077`](https://github.com/dappros/ethora-mcp-server/commit/6f86077), [`a90d7e9`](https://github.com/dappros/ethora-mcp-server/commit/a90d7e9))
- **Milestone:** The registry entry gained a website URL and the listing metadata needed for third-party MCP directories, including a quality-score card ([`6209269`](https://github.com/dappros/ethora-mcp-server/commit/6209269), [`3964e4d`](https://github.com/dappros/ethora-mcp-server/commit/3964e4d), [`c93509d`](https://github.com/dappros/ethora-mcp-server/commit/c93509d), [`4efcbc3`](https://github.com/dappros/ethora-mcp-server/commit/4efcbc3))
### Platform API & Identity (`platform`)
> Platform API and AI service | 29 commits
- **New:** **An OAuth 2.1 authorization server, built on the existing token factory.** Standards-compliant metadata, dynamic client registration, authorization code with PKCE, rotating refresh tokens and revocation, plus a self-contained sign-in, create-account and consent page that reuses the ordinary web login against the base app. Access tokens are the platform's normal user tokens anchored to a revocable row, so revoking a connection takes effect immediately and no API route had to change. A "connected AI apps" list lets a user see and revoke their grants.
- **New:** **Sign in with Google (and optionally Facebook) on the consent page**, so connecting an assistant does not force a password on an account that has never had one. The app's closed-registration setting is honoured on the consent page's sign-up paths.
- **New:** **Long-lived, revocable user API keys.** Automation clients — the hosted MCP server, agents, CI — need a credential that outlives the one-hour session token but can still be killed instantly. An API key is an ordinary user token bound to a revocable row with a chosen lifetime of up to a year, so every existing authenticated route accepts it with no middleware change, deleting the row revokes it, and it can never be used to mint a session refresh.
- **New:** **Revocable B2B server tokens minted by the app owner.** Integrators previously had to hand-sign a server token from the app secret, which meant the only way to revoke one was to rotate the secret and break everything else. An owner can now create a server token from the API, see it once, list the active ones and revoke any of them individually; a revoked or expired token is refused at the point of use, and legacy hand-signed tokens keep working.
- **New:** **A minimal identity surface for connector review.** A userinfo endpoint returns the subject, email and verification state for the bearer of an OAuth access token, checked against the grant so a revoked connection stops returning claims, and two identity scopes are advertised and described in plain words on the consent screen. Identity scopes grant claims only, never platform access, and the user can decline and continue. Deliberately not built: ID tokens, asymmetric signing and a full provider surface, none of which the review asks for.
- **New:** **Optional email verification.** Mandatory confirmation was removed on purpose because the friction cost signups, so verification stays optional everywhere: sign-up, sign-in and the admin panel behave exactly as before for an unconfirmed account. The one exception is an assistant connector asking for identity scopes, since some of them refuse an unverified address. A user can start verification themselves and confirm from the email client.
- **New:** **Product feedback, accepted from anywhere.** A feedback endpoint takes a message with an optional category, address, source and free-form context and delivers it by email and chat. It works authenticated or anonymous — a signed-in caller is attributed from the token only, never from the body — and the free-form context is what makes an assistant-submitted report useful, because it carries the tool, error code and request id that join straight to the server-side log.
- **New:** **Offline-verifiable licence keys for self-hosted installs.** A signed key encodes the licensed parent domain, edition and expiry and is verified locally against public keys compiled into the platform, so an install never has to phone home to start. A state machine moves an install between licensed, a fourteen-day grace period and a restricted state, a key supplied at deploy time takes precedence over one uploaded in the admin panel, and local and test hosts always pass. A daily job calls home for renewal and operator notices, and reports the current key expiry so the issuing service can refresh a key only when it is genuinely due.
- **New:** **A licence service.** A small standalone service issues and renews the signed keys, records installs, enforces the instance limit on a licence, issues one fourteen-day trial per domain and per address, and exposes an administration surface for creating, inspecting, renewing and suspending licences and for minting an offline key.
- **New:** **A container image for the API**, one image that runs the API, the jobs runner or the blockchain worker depending on its argument, with an optional stage that compiles first-party code to bytecode and ships no sources. Test files, source maps and development dependencies are never included.
- **Improved:** **Multi-agent rooms can no longer talk to each other forever.** Four gaps in the autonomy cap are closed: a bot answers another bot only while a human has spoken within a configurable window, a bot mentioning another bot no longer bypasses that rule, and a proactive heartbeat post opens a short round rather than handing out a fresh full budget.
- **Improved:** An app provisioned through the B2B route is now attributed to the person who provisioned it rather than to the tenant identity, so it appears in their own app list and can be deleted by them.
- **Fixed:** Agent reactions are sent in the identifier format clients actually expect, so they render under the right bubble.
- **Fixed:** The app-scoped document and site-source routes accept their own URL. Their parameter schemas omitted the app id that the route path itself declares, so every assistant-driven call to tag or delete a source was rejected as malformed.
- **Fixed:** The broadcast endpoint answers a missing room list with a sentence that names the three valid options, instead of the validation library's raw internal text.
- **Fixed:** **The metrics endpoint.** It returned a server error the moment it was switched on, because the handler wrote a promise to the response; and once fixed, every distinct URL an internet scanner probed became a permanent label, pushing a single host past eight thousand series. Requests are now labelled with the route pattern that handled them, unmatched requests fold into one value, and the number of distinct paths is capped.
- **Fixed:** A client registered without a scope may request any supported scope, rather than being locked out of everything.
- **Fixed:** Three consent-page defects found in social sign-in: the popup could not reach the consent page under a cross-origin isolation policy, a failure did not name its cause, and the form could not be submitted at all.
- **Docs:** A data-handling reference for the assistant integration, plus a policy template a self-hosting operator can adapt, and notes on licence enforcement and the container image.
- **Infrastructure:** The repository's secret scan moved to the open-source scanner CLI.
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 60 commits / 26.7.5 → 26.8.1
- **New:** **The profile family is now a chat column, not an overlay.** Chat profile, user profile, settings, Manage Data and Visibility used to render on the modal layer parked against the right edge, which meant opening a profile hid the conversation you were reading. They now sit in the layout as a third column and the chat simply gets narrower, the way a desktop messenger behaves. The routing that decides which panel is open has one source of truth shared by both hosts, so centred dialogs and side panels cannot drift apart ([`419dff6`](https://github.com/dappros/ethora-chat-component/commit/419dff6), [`d60284c`](https://github.com/dappros/ethora-chat-component/commit/d60284c))
- **New:** **The room list seeds its previews from the API.** The rooms endpoint returns a last message per room, so a room whose history has not loaded yet now shows that message as its preview and sorts by its timestamp, instead of a blank line and a creation-date ordering. Live history still wins the moment it arrives, and a response that omits the field never erases one already seeded ([`9daf70d`](https://github.com/dappros/ethora-chat-component/commit/9daf70d), [`c0e5ff2`](https://github.com/dappros/ethora-chat-component/commit/c0e5ff2), [`41bc8fc`](https://github.com/dappros/ethora-chat-component/commit/41bc8fc))
- **New:** **The chat QR code is a panel rather than a full-screen takeover**, stacking over the profile column with the room list and conversation left in place, and recomposed as one balanced centred block. Escape peels it off and leaves the profile open underneath ([`7da947d`](https://github.com/dappros/ethora-chat-component/commit/7da947d), [`707a435`](https://github.com/dappros/ethora-chat-component/commit/707a435))
- **New:** **Motion throughout.** Side drawers, file previews, the thread pane, and the delete-confirm, report-chat and new-chat dialogs animate in and out; switching rooms settles in with a fade rather than snapping. Exit animations need the element to stay mounted, which two small hooks now handle, and everything no-ops under a reduced-motion preference ([`2794fdd`](https://github.com/dappros/ethora-chat-component/commit/2794fdd), [`f4bfa2b`](https://github.com/dappros/ethora-chat-component/commit/f4bfa2b), [`c81ce4b`](https://github.com/dappros/ethora-chat-component/commit/c81ce4b), [`0a80f01`](https://github.com/dappros/ethora-chat-component/commit/0a80f01), [`27bcf95`](https://github.com/dappros/ethora-chat-component/commit/27bcf95), [`8792c61`](https://github.com/dappros/ethora-chat-component/commit/8792c61), [`c41129e`](https://github.com/dappros/ethora-chat-component/commit/c41129e))
- **Improved:** **The default palette meets WCAG AA.** A contrast sweep found online and success text at 2.62:1 and message timestamps at 3.36:1 against a 4.5:1 requirement, and the destructive colour short of the bar on the hover surface where it actually renders. All three tokens were darkened to the minimum needed to clear 4.5:1 on every surface they appear on, keeping their hue. A host's own configured colours are passed through untouched, and a new test computes the ratios from the theme builder's real output so a future edit fails loudly instead of shipping a regression ([`08ec238`](https://github.com/dappros/ethora-chat-component/commit/08ec238))
- **Improved:** **The profile drawers were redesigned.** Description reads as prose instead of a disabled-looking form field, chat type is a small icon pill, member rows are taller with hover feedback and a secondary line, and empty states read as deliberate blanks rather than failures. A published type scale gives the profile hero a real focal point, and Manage Data's controls read as controls ([`179f8f6`](https://github.com/dappros/ethora-chat-component/commit/179f8f6), [`b997fb0`](https://github.com/dappros/ethora-chat-component/commit/b997fb0))
- **Fixed:** **The cold-start empty states stopped lying.** Three separate defects made a fresh login show "no chats yet" or "choose a chat" while the room list was still loading — a request that takes tens of seconds on a cold cache, not a frame. The no-rooms prompt was guarded only by the absence of loading, the idle placeholder returned before any of those guards were reached, and a failed rooms request was indistinguishable from an account with no rooms because the transport error was swallowed and handed back as an empty list. All three empty-list outcomes now live in one guard: a clean resolve with zero rooms gets the prompt, a failure gets a retry message and a timed retry, and anything else gets a loader ([`cb29b84`](https://github.com/dappros/ethora-chat-component/commit/cb29b84), [`951c4b9`](https://github.com/dappros/ethora-chat-component/commit/951c4b9), [`09d378e`](https://github.com/dappros/ethora-chat-component/commit/09d378e), [`47404f3`](https://github.com/dappros/ethora-chat-component/commit/47404f3))
- **Fixed:** A slow or failing rooms request no longer paints "connection lost" over a healthy socket ([`47404f3`](https://github.com/dappros/ethora-chat-component/commit/47404f3))
- **Fixed:** **Opening a room no longer flickers.** The loading state was derived from four independent async flags, so a loader and an empty-chat placeholder traded places several times before any history landed. One forward-only phase per room now absorbs the gaps between them, and while a room is opening its seeded last message is shown in a normal bubble with a loader above it for the rest of the conversation. A room whose archive is genuinely empty keeps that message and stops spinning ([`00877ea`](https://github.com/dappros/ethora-chat-component/commit/00877ea), [`4b06080`](https://github.com/dappros/ethora-chat-component/commit/4b06080))
- **Fixed:** **Joining a public room by link works without a reload.** The join was sent without waiting and the room list immediately refetched from a cache, so the new room never appeared and the user got an empty pane until they reloaded by hand. The join is now awaited, the refetch invalidates the cache, and it retries in the background because membership registers a few seconds later ([`50f1f69`](https://github.com/dappros/ethora-chat-component/commit/50f1f69))
- **Fixed:** **Deep links can no longer address a room that cannot exist.** A missing conference host used to produce a malformed room address, which selected nothing and left the pane blank; a missing host now means do nothing rather than guess, full addresses are accepted as given, and any malformed entries already persisted in a browser are pruned on load. A parked link destination also survives the first-run cache reset that a shared link tends to trigger ([`7ca8743`](https://github.com/dappros/ethora-chat-component/commit/7ca8743), [`b06f76a`](https://github.com/dappros/ethora-chat-component/commit/b06f76a), [`8b2eb38`](https://github.com/dappros/ethora-chat-component/commit/8b2eb38), [`e8aa4b1`](https://github.com/dappros/ethora-chat-component/commit/e8aa4b1), [`0dd3a83`](https://github.com/dappros/ethora-chat-component/commit/0dd3a83), [`abe1ba8`](https://github.com/dappros/ethora-chat-component/commit/abe1ba8))
- **Fixed:** **Manual translation works again, and shows what automatic mode shows.** The two modes had separate lookups and separate visibility rules, so a reader could watch automatic mode render a translation while clicking Translate on the same message dead-ended. Both now call one shared resolver, a translation is fetched on demand when the host provides no translator of its own, and both the older and newer shapes of the translation service are supported so a deployment change cannot silently break it again ([`dc7b74f`](https://github.com/dappros/ethora-chat-component/commit/dc7b74f), [`5919319`](https://github.com/dappros/ethora-chat-component/commit/5919319), [`ed5c8e9`](https://github.com/dappros/ethora-chat-component/commit/ed5c8e9))
- **Fixed:** **Line breaks a user typed are kept.** Markdown treats a single newline as a space, so a multi-line message collapsed into one line; a small plugin restores real breaks, including in the plain-text paths that render a quoted original alongside a translation ([`f3f613b`](https://github.com/dappros/ethora-chat-component/commit/f3f613b))
- **Fixed:** **An edit appears the moment it is sent.** Editing only put the change on the wire, so the bubble kept its old text until the server echo arrived and on a slow link the edit looked like it had done nothing. It is now applied locally as soon as the client confirms it can actually send, and not at all if it cannot ([`b68b1a3`](https://github.com/dappros/ethora-chat-component/commit/b68b1a3))
- **Fixed:** **Scrollbars.** Setting a scrollbar colour makes current Chrome abandon the platform's slim overlay bar for a classic always-visible widget, which arrived painted in the host's brand colour, ran the height of the room list and clipped the date column. The themed bar is back but muted and translucent, firming up on hover, and the room list reserves real clearance for it on every platform rather than relying on a property that only applies to space-taking scrollbars ([`03a44c5`](https://github.com/dappros/ethora-chat-component/commit/03a44c5), [`df78dda`](https://github.com/dappros/ethora-chat-component/commit/df78dda), [`e88b419`](https://github.com/dappros/ethora-chat-component/commit/e88b419))
- **Fixed:** **A broken avatar image falls back to initials.** Social profile photos hotlinked with a referrer, or simply expired, rendered as a broken-image glyph with clipped alternative text in member lists. The referrer is now withheld, which fixes most of them outright, the rest fall back to the same initials used when no picture is set, images in a long member list load lazily, and the alternative text is the person's name in their own language ([`6297a9f`](https://github.com/dappros/ethora-chat-component/commit/6297a9f))
- **Fixed:** Clicking a room no longer leaves a focus ring on the row, while keyboard activation keeps one; a chat-type pill no longer stretches and the scroll button no longer covers the panel; and a room that cannot be opened now says so instead of showing nothing ([`c426ab2`](https://github.com/dappros/ethora-chat-component/commit/c426ab2), [`b8a8ed2`](https://github.com/dappros/ethora-chat-component/commit/b8a8ed2), [`a1b793d`](https://github.com/dappros/ethora-chat-component/commit/a1b793d), [`5f4cffc`](https://github.com/dappros/ethora-chat-component/commit/5f4cffc))
- **Milestone:** `@ethora/chat-component` 26.7.6, 26.7.7, 26.7.9 and **26.8.1** published ([`b7c2353`](https://github.com/dappros/ethora-chat-component/commit/b7c2353), [`6b1effe`](https://github.com/dappros/ethora-chat-component/commit/6b1effe), [`fad8715`](https://github.com/dappros/ethora-chat-component/commit/fad8715), [`ebb3b0b`](https://github.com/dappros/ethora-chat-component/commit/ebb3b0b))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 6 commits / 26.7.10 → 26.8.1
- **Fixed:** **The read marker is the message you actually reached.** Every path that leaves a room — unmounting, backgrounding, losing visibility or focus, logging out — wrote the newest message the server had acknowledged rather than the last one the reader had scrolled to, so leaving a room marked unread messages as read. It now writes the reader's own scroll boundary, and the "new messages" divider compares timestamps at full precision, so it sits directly below the last read message and matches the unread count ([`3147653`](https://github.com/dappros/ethora-chat-component-rn/commit/3147653))
- **Fixed:** **Every screen rendered blank on React Native 0.81.** A style helper the framework removed in that version was being spread into ten different style objects, which is a silent no-op rather than a crash, so positioning simply vanished from media overlays, the interactions overlay, the file-preview backdrop and the testbed's own panes. Swapped for the equivalent that remains, which is a drop-in ([`206059b`](https://github.com/dappros/ethora-chat-component-rn/commit/206059b))
- **Fixed:** **Three localisation defects from a French and Spanish QA pass.** The attach sheet, the chat profile screen and the new-message divider carried hardcoded English that no locale could reach and now resolve through the string table in all six supported languages; translations were dropped on every cold start because the field was excluded from what gets persisted; and "Show original" now collapses ([`c09de5a`](https://github.com/dappros/ethora-chat-component-rn/commit/c09de5a), [`206059b`](https://github.com/dappros/ethora-chat-component-rn/commit/206059b))
- **New:** `config.inputDockPaddingBottom` overrides the composer's bottom padding, including to zero, for a host that already sits above its own tab bar ([`3147653`](https://github.com/dappros/ethora-chat-component-rn/commit/3147653))
- **Improved:** The version constant is now regenerated from the package version as part of the release itself, with a test covering the other direction, so the two cannot drift again ([`eac2801`](https://github.com/dappros/ethora-chat-component-rn/commit/eac2801))
- **Milestone:** `@ethora/chat-component-rn` 26.7.10 and **26.8.1** published; the minimum supported iOS version stays where it was ([`4b3b4fa`](https://github.com/dappros/ethora-chat-component-rn/commit/4b3b4fa), [`d48033f`](https://github.com/dappros/ethora-chat-component-rn/commit/d48033f))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 16 commits / branches 2609 and 2610
- **New:** **An AI Assistants tab in the account.** Create, list and revoke personal API keys, and on creating one, see it once alongside ready-to-paste connection details for the hosted assistant server: a personal connector URL for Claude.ai and ChatGPT custom connectors, a one-line command for Claude Code, and a JSON block with a bearer header for Cursor and other clients. A "Connected AI apps" section lists the grants a user has given and lets them revoke one, and hides itself on installs where that endpoint is not deployed ([`741358f`](https://github.com/dappros/ethora-app-reactjs/commit/741358f))
- **New:** **Server tokens in the API tab.** An app owner can mint a B2B server token, see it once behind the existing secret control with a copy-ready request example, list the active ones and revoke any of them. The credential table now says what each credential is and which one to use. The whole section hides itself on deployments that predate the feature ([`a9db57b`](https://github.com/dappros/ethora-app-reactjs/commit/a9db57b), [`25aed51`](https://github.com/dappros/ethora-app-reactjs/commit/25aed51), [`b9b6a73`](https://github.com/dappros/ethora-app-reactjs/commit/b9b6a73), [`870ba27`](https://github.com/dappros/ethora-app-reactjs/commit/870ba27), [`91e5013`](https://github.com/dappros/ethora-app-reactjs/commit/91e5013))
- **New:** **A Licence page in the admin console**, with a status card and key upload for super administrators, a banner shown to administrators while an install is in grace or restricted, and a redirect that keeps the console on that page when the platform reports the admin panel as restricted. The status is read once and shared, and a failed read never blocks the interface ([`3f7eef7`](https://github.com/dappros/ethora-app-reactjs/commit/3f7eef7))
- **New:** **Runtime configuration and a prebuilt frontend image.** Every setting the app reads now prefers a runtime configuration file loaded before the bundle, falling back to the build-time value, so one image can serve any install instead of each install needing its own build. The container renders that file and the content-security origins from its environment at start, and can either serve the bundle itself or render it into a directory for a host that serves it with its own web server. Source-mode installs are unchanged ([`5db92ef`](https://github.com/dappros/ethora-app-reactjs/commit/5db92ef), [`7a0a318`](https://github.com/dappros/ethora-app-reactjs/commit/7a0a318))
- **New:** **An optional email-verification affordance**, placed on the AI Assistants tab beside the connector setup it affects rather than anywhere a general user would meet it, because verification stays optional and the only reason to surface it is that some connectors will not accept an unverified address. It shows the address with its state, offers to send a link, and renders nothing at all unless the platform reports a verification state ([`90af287`](https://github.com/dappros/ethora-app-reactjs/commit/90af287), [`ed32e4e`](https://github.com/dappros/ethora-app-reactjs/commit/ed32e4e))
- **New:** A customisation interface for the embeddable widget, and a clearer loading state on sign-in ([`ecce9f0`](https://github.com/dappros/ethora-app-reactjs/commit/ecce9f0))
- **Improved:** The bundled chat component was moved forward to the week's releases ([`ec6838a`](https://github.com/dappros/ethora-app-reactjs/commit/ec6838a), [`f789410`](https://github.com/dappros/ethora-app-reactjs/commit/f789410))
- **Refactored:** The quick lint findings were cleared, from 201 down to 138 ([`5cffc22`](https://github.com/dappros/ethora-app-reactjs/commit/5cffc22))
- **Docs:** The diagnostics catalogue gained the agent room probe with its button-tap and scripted modes, and a note that the widget lives in a shadow root ([`70c6151`](https://github.com/dappros/ethora-app-reactjs/commit/70c6151))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 2 commits (plus daily submodule bumps)
- **Docs:** Week 37 release notes published, and the MCP section of the README now leads with the hosted server rather than the command-line install ([`3440e79f`](https://github.com/dappros/ethora/commit/3440e79f), [`afb914fd`](https://github.com/dappros/ethora/commit/afb914fd))
---
## Week 37 (Sep 7 – 13, 2026) — Agents learn to run a script: operator-authored flows, tappable answers, and a mobile push overhaul
**Contributors:** Borys Bordunov, Dmytro Berberov, Roman Leshchuh, Taras Filatov, Yurii T.
**Total commits:** 29 across SDK/app repos + 16 platform/server | **Active repos:** 8
### Theme
Three lines converged this week. **Flows** gives an operator a way to script an agent's conversation in YAML — an opening menu, an intake questionnaire, an appointment request — validated by the API and authored from a new tab in the agent settings. **Quick replies** gives that script somewhere to land: the web chat component now renders a bot's buttons under the bubble and posts the tapped answer back as an ordinary message, and the AI service can choose to answer with buttons or a reaction. And the React Native SDK got a **push-delivery overhaul** that closes the gap where a signed-in user held a device token and still received nothing.
### AI Agents & Platform API (`platform`)
> Platform API and AI service | 14 commits
- **New:** **Scripted agent flows.** An operator can now describe an agent's conversation as a YAML script on the agent itself: `say` steps (with optional buttons that jump to another flow or end the conversation), `ask` steps that collect one typed slot (text, number, date, phone, email, or a list of options rendered as buttons), `goto` and `end`, with `{slot}` interpolation and `when: slot == value` branching. The API compiles and validates the script on save and refuses to store one that does not compile, returning line-numbered errors. A flow named `start` becomes the agent's **opening menu**, offered automatically at the beginning of a session; any other flow is invoked when the model decides it is needed, and flows can chain into one another. A dedicated validate endpoint dry-runs the compiler without saving, and the widget session response carries the opening step so a client can render it immediately. The answers a flow collects are readable through the API. Pre-built templates ship for an opening menu, appointment request, lead capture, intake questionnaire and feedback survey.
- **New:** **Agents can answer with buttons and reactions.** Both are exposed to the model as tools alongside the existing persona tool. `reply_with_buttons` sends the reply text with tappable options attached (labels and values validated and capped, duplicates dropped, so a confused model degrades to fewer buttons rather than a broken bubble); `react_to_message` puts an emoji reaction on the message being answered, built to match the chat component's own reaction format so it renders under the right bubble. Reactions are offered only on room turns, where there is a message to react to.
- **New:** **Mute and unmute a chat, per member.** A member can silence a room for themselves through new mute and unmute endpoints; the flag is per member, so it never affects anyone else, and the room list and single-room reads return it. Idempotent, and scoped to rooms the caller belongs to.
- **New:** **Optional password on single-user provisioning.** The provisioning route now accepts a password chosen by the caller and stores it as a permanent credential, so an operator provisioning an account for someone who cannot receive the invite email (a shared inbox, onboarding done in person, an address not yet live) can hand over a credential that works straight away. Minimum length matches the sign-in floor, so anything accepted at creation is accepted at login.
- **New:** **App and chat language are now two separate preferences.** The profile used to carry one language that meant two things: what the interface renders in, and what incoming messages are translated into. These are now `appLanguage` and `chatLanguage`, both validated against the install's configured list, both clearable. Chat language falls back to the app language when unset, so a reader who never chose one keeps the behaviour they had. A migration moves existing rows.
- **New:** **The install's translation targets are published to clients.** The translation server is deployed separately from the API, so which languages it can translate into is an operational fact no client could infer. A new install-wide `translateLanguages` list, configured at deploy time and synchronised on every install and update, is served in the unauthenticated bootstrap config alongside the chat host. The key is always present and empty when no translation server is configured, so a client can tell "none configured" from "old API". Language writes are validated against the same list clients receive, so a picker cannot offer a code the write would then reject.
- **Improved:** One list now describes the available languages instead of two that could disagree. The older `languages` block has been removed from the session bootstrap responses in favour of the config list.
- **Improved:** **Message translations are persisted in the archive**, so a translated conversation reads the same on reload as it did live, and the chat server forwards translations to the push service.
- **Improved:** **Push notifications carry more of the message.** The sender's name becomes the notification title, the body is rendered in the receiver's own language, a member's chat mute is honoured, and the sender's avatar is forwarded to the device (as the notification image on Android, and with mutable content on iOS so a notification service extension can attach it).
- **Improved:** **Faster app reads and token refresh.** The app payload no longer embeds the full crawled markdown of every indexed site source — the dashboard only ever used the URL and size, and the markdown is fetched per source — which removes seconds and hundreds of megabytes of heap from a single read on an app with a large web index. Indexes were declared behind refresh-token, app-ACL and room-membership lookups that had been full collection scans on every request.
- **Fixed:** An edited message's translations now sync correctly out of the archive.
### Chat Server & Infrastructure (`platform`)
> Chat server | 2 commits
- **Improved:** The offline-message hook forwards message translations to the push service and passes the sender's avatar through as the notification image.
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 4 commits / 26.7.5 → 26.7.9
- **New:** **Mute a chat from its profile.** A bell button joins Search, Leave and Report in the chat-profile hero, reading "Unmuted" or "Muted" and toggling the caller's own membership flag through the new platform endpoints, with the initial state read from the room list. The flip is optimistic and rolls back with a toast if the request fails ([`6d8a289`](https://github.com/dappros/ethora-chat-component-rn/commit/6d8a289))
- **New:** **`handlePushPayload(data)` and `openRoomFromPush(jid)` are exported from the package root.** The host keeps ownership of the native push side (token, permission, tap listeners) and hands the tapped notification's data to the SDK: a call push rings, a message push opens its room — immediately if the room list is loaded, otherwise as soon as it is. The pending room is persisted with a five-minute expiry, so a tap handled by a JS context that is replaced right after (the cold-start race) still opens the room on the next mount ([`8bef8e6`](https://github.com/dappros/ethora-chat-component-rn/commit/8bef8e6))
- **New:** **`config.headerLayout.safeAreaTop`** lets the room-list and chat header cards pad their own top inset and run under the status bar as one surface, instead of the host wrapping the component in a top-edge safe area that painted its own white band above the card. Off by default, so existing hosts are unchanged ([`dd9136d`](https://github.com/dappros/ethora-chat-component-rn/commit/dd9136d))
- **Fixed:** **Push notifications now arrive for users who only ever signed in through the SDK.** The bootstrap re-joined rooms with presence but never sent the room-subscription that the chat server uses to decide whom to push for — only the legacy path did — so such a user had a registered device token and received nothing. Both the bootstrap and the reconnect handler now subscribe every room in the store after the presence pass ([`dd9136d`](https://github.com/dappros/ethora-chat-component-rn/commit/dd9136d))
- **Fixed:** **Push subscription no longer takes minutes on a busy account.** The subscription pass was strictly sequential with a pause and a timeout per room, so a user with a few dozen rooms outlived the socket and finished mostly unsubscribed; it now runs in parallel batches with unique request ids (shared ids had made every request resolve on the first reply). A refused subscription logs the server's reason instead of failing silently ([`8bef8e6`](https://github.com/dappros/ethora-chat-component-rn/commit/8bef8e6))
- **Fixed:** **The chat stream is now closed when the app goes to the background** and reopened on foreground. Android keeps a backgrounded socket alive for minutes, and while it lived the server still saw the user as online and routed new messages into the socket instead of sending a push — so only the first push after a cold start ever arrived. Opt out with `xmppSettings.keepAliveInBackground: true` ([`8bef8e6`](https://github.com/dappros/ethora-chat-component-rn/commit/8bef8e6))
- **Fixed:** A successful room join is no longer reported as a bootstrap failure — the presence timeout raced the reply and won ([`dd9136d`](https://github.com/dappros/ethora-chat-component-rn/commit/dd9136d))
- **Milestone:** `@ethora/chat-component-rn` 26.7.6, 26.7.7, 26.7.8 and 26.7.9 published ([`dd9136d`](https://github.com/dappros/ethora-chat-component-rn/commit/dd9136d), [`8bef8e6`](https://github.com/dappros/ethora-chat-component-rn/commit/8bef8e6), [`c443cf9`](https://github.com/dappros/ethora-chat-component-rn/commit/c443cf9))
### Web Chat SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 3 commits / 26.7.4 → 26.7.5
- **New:** **Bot quick-reply buttons render under the bubble and answer as messages.** A message carrying `quickReplies` now draws its options as tappable chips; tapping one sends its value into the room as an ordinary message, so the bot reads the answer through exactly the same path as typed input and the transcript stays readable. The chips lock after a tap, so a double tap cannot post two answers to one question. The wire format is the one Ethora bots already emit, so nothing on the bot side has to change to light this up; an optional question id is carried for flows that need to tie an answer to its question. Options survive a repaint from cache instead of disappearing until the message is re-delivered ([`c8e2781`](https://github.com/dappros/ethora-chat-component/commit/c8e2781), [`ebfb2fd`](https://github.com/dappros/ethora-chat-component/commit/ebfb2fd))
- **New:** `config.eventHandlers.onQuickReply` fires after the answer is sent, for hosts driving their own scripted flow (a quiz, an intake form) on top of the same buttons. It is a notification rather than an interception point, so a throwing handler cannot cost the user their answer ([`c8e2781`](https://github.com/dappros/ethora-chat-component/commit/c8e2781))
- **Milestone:** `@ethora/chat-component` 26.7.5 published ([`890f901`](https://github.com/dappros/ethora-chat-component/commit/890f901))
### Web App & Admin (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 11 commits / branch 2609
- **New:** **Flows tab in the agent settings.** This is where an operator writes the YAML script: a plain editor in the Behaviour section with starter templates (opening menu, appointment request, lead capture, intake questionnaire, feedback survey), a Validate button that dry-runs the API's compiler without saving, and Save. Compiler errors come back with line numbers and are listed under the editor, and a script that does not compile is refused by the API, so the panel can never show a saved-but-broken state. Copy in English, French and Spanish ([`472468e`](https://github.com/dappros/ethora-app-reactjs/commit/472468e))
- **New:** **Self-serve Apple push credentials and a per-app push switch.** The mobile app settings screen takes an APNs auth key upload with its key id, team id, bundle id and sandbox or production environment, shows whether a key is in place and allows removing it, and adds a switch that turns platform push on or off per app with today's count against the daily quota shown next to it. Validation problems from the API are surfaced verbatim ([`7df9f05`](https://github.com/dappros/ethora-app-reactjs/commit/7df9f05))
- **New:** **Generate a password in Add New User and download the credentials as CSV.** Creating a user from the admin modal used to produce an account whose credential the operator never saw. The modal now seeds a fresh password on every open (drawn from the platform's cryptographic random with rejection sampling so the character distribution is even, one character of each class guaranteed, and the characters that get misread off a screen left out), the field is editable with a regenerate link, and the credentials are downloaded as CSV the moment the account exists — before the user-list refresh, since the server stores the password hashed and no endpoint reads it back ([`ee42ab9`](https://github.com/dappros/ethora-app-reactjs/commit/ee42ab9))
- **New:** **Two language pickers in the profile.** App language and chat language are now separate choices, each written on its own. The app picker offers the locales the bundle ships dictionaries for (an unbundled one would render in English); the chat picker offers the translation server's own list, whole, because translating *into* a language does not require the interface to render in it. When no translation server is configured the chat row is hidden entirely, and a chat language that was never chosen shows the app language and says it is following it ([`53e9747`](https://github.com/dappros/ethora-app-reactjs/commit/53e9747), [`315f761`](https://github.com/dappros/ethora-app-reactjs/commit/315f761), [`7742daf`](https://github.com/dappros/ethora-app-reactjs/commit/7742daf))
- **Fixed:** **The chat language choice now actually translates messages.** The chat surface took a single language input derived from the app language and used it for both its own captions and its message-translation target, so the profile's chat-language row was stored and echoed back but read by nothing. The two inputs are now separate, and the app-wide chat provider follows the user's picks instead of raw browser detection; changing a language re-applies the config without reconnecting ([`14f8dbd`](https://github.com/dappros/ethora-app-reactjs/commit/14f8dbd))
- **Fixed:** **The translation controls no longer appear on installs that cannot translate.** The gate read a capability list whose fallback was the entire bundled catalogue, which turned "no translation server" into three offered languages, a globe picker and an auto-translate mode that could never produce anything. It now reads the install's real list ([`14f8dbd`](https://github.com/dappros/ethora-app-reactjs/commit/14f8dbd))
- **Fixed:** The admin apps list's cheap count call for the other tab's total now uses the API's minimum page size instead of one, which the API rejects ([`f324271`](https://github.com/dappros/ethora-app-reactjs/commit/f324271))
- **Testing:** The multi-agent room probe transcribes agent buttons and reactions, not just message bodies, tagging message ids so a reaction can be matched to its target; `TAP_BUTTON` answers the first message offering buttons the way a person tapping a chip would, and `SCRIPT` plays a whole scripted conversation from the command line, so one run covers the full round trip of an agent offering choices, a user picking, and the agent seeing the answer through the normal inbound path ([`6c3f668`](https://github.com/dappros/ethora-app-reactjs/commit/6c3f668), [`472468e`](https://github.com/dappros/ethora-app-reactjs/commit/472468e))
- **Improved:** The chat bootstrap passes the app id through to the component, and the admin app is marked as not for indexing ([`20a616e`](https://github.com/dappros/ethora-app-reactjs/commit/20a616e), [`4a92bc2`](https://github.com/dappros/ethora-app-reactjs/commit/4a92bc2))
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 2 commits / 26.7.2
- **Fixed:** **The call-to-action teaser could stay permanently invisible.** Its fade-in animation started from fully transparent, and a CSS animation's clock only advances once the browser produces render frames for the document — so in a backgrounded tab, a non-visible preview iframe or on a low-power device the animation stayed pinned at its first keyframe: correctly positioned, sized and dismissible, but invisible, which is indistinguishable from never having rendered ([`43f7464`](https://github.com/dappros/ethora-ai-chat-widget/commit/43f7464))
- **Milestone:** `@ethora/ai-chat-widget` 26.7.2 published, rebuilt against chat component 26.7.4 ([`6ebd9d4`](https://github.com/dappros/ethora-ai-chat-widget/commit/6ebd9d4))
### Playground (`sdk-playground`)
> [ethora-sdk-playground](https://github.com/dappros/ethora-sdk-playground) | 8 commits
- **New:** **AI Assistant configurator with live preview.** A full configurator for the embeddable widget — appearance, colours, fonts, position, launcher, call-to-action — that generates the production embed snippet as you change it. The preview loads the real built widget bundle in an iframe rather than a hand-simulated approximation, so what you see is what the snippet produces ([`8f711ef`](https://github.com/dappros/ethora-sdk-playground/commit/8f711ef), [`346be46`](https://github.com/dappros/ethora-sdk-playground/commit/346be46))
- **New:** **React Native tab with an in-browser Expo Snack.** The React Native chat component now runs in the browser with no account and no install, using the sample app; the local iOS Simulator and Android Emulator route is documented alongside it for a real native run ([`b14c921`](https://github.com/dappros/ethora-sdk-playground/commit/b14c921))
- **New:** Both tabs are wired into the top-level navigation next to Chat, SDK, Auto and HTTP, and a "Book a call" action sits beside "Launch live demo chat" on the Quickstart tab ([`0de10b7`](https://github.com/dappros/ethora-sdk-playground/commit/0de10b7))
- **New:** The server-to-server token endpoint takes an optional TTL, so a QA script can mint a longer-lived token without changing the one-hour default used everywhere else ([`e0f6b8c`](https://github.com/dappros/ethora-sdk-playground/commit/e0f6b8c))
- **Milestone:** The public "try without signup" sandbox and production defaults landed on the main branch ([`03c7148`](https://github.com/dappros/ethora-sdk-playground/commit/03c7148), [`4374a8d`](https://github.com/dappros/ethora-sdk-playground/commit/4374a8d))
### Backend Integration Sample (`sdk-backend-integration`)
> [ethora-sdk-backend-integration](https://github.com/dappros/ethora-sdk-backend-integration) | 1 commit
- **Milestone:** Version bumped to 26.08.01 ([`8cc7d47`](https://github.com/dappros/ethora-sdk-backend-integration/commit/8cc7d47))
---
## Week 36 (Aug 31 – Sep 6, 2026) — Version 26.09 ships; the RN SDK gets a full UI redesign; AI agents learn to share a room and to speak first
**Contributors:** Dmytro Berberov, Roman Leshchuh, Yurii T., Borys Bordunov, Taras Filatov
**Total commits:** ~16 across SDK/app repos + ~10 platform/server | **Active repos:** 5
### Milestones
- **Milestone:** **Version 26.09 released** — the 2608 iteration (August development) is tagged `v26.09` on the monorepo and npm packages roll to 26.09 (`@ethora/mcp-server` [`0966301`](https://github.com/dappros/ethora-mcp-server/commit/0966301)); production platform updated to the 2608 line during the week. September development continues on the `2609` iteration branches (version 26.10).
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 12 commits / v26.7.2 → 26.7.4
- **New:** Chat profile screen rebuilt around the chat photo — a full-bleed hero with name, member count and round action buttons that collapses into a frosted compact bar as you scroll (parallax and collapse run on the UI thread); rooms without a picture get a flat avatar colour with initials. Below it: description and chat-type cards, an **Add Members** row for moderators, the member list with roles and a per-row remove action, **Leave** / **Report** actions (report categories post to the platform), a "…" menu with Edit / Remove photo / Delete and Leave gated on what the signed-in user may do, and a member **search** that folds into the menu when the header is collapsed ([`d8b08a9`](https://github.com/dappros/ethora-chat-component-rn/commit/d8b08a9))
- **New:** User profile screen rebuilt on the same collapsing header — your own profile gets Account, Share, Edit, Log out and a Leave button that runs the SDK's full sign-out teardown; someone else's gets Message and Share. New **About** section and, on your own profile, **Language / Media / Documents** tabs (files come from the platform's v2 files endpoint, split by type) ([`1981077`](https://github.com/dappros/ethora-chat-component-rn/commit/1981077))
- **New:** "Create new chat" redesigned as a full-screen modal — round picture picker, chat name, optional description, side-by-side Cancel/Create, every accent on the configured primary colour ([`1981077`](https://github.com/dappros/ethora-chat-component-rn/commit/1981077))
- **New:** Attach sheet reworked into a Slack-style media picker — a "Photos & Videos" strip with a camera tile and the 12 most recent photos (via the optional `expo-media-library` peer), one-tap attach, "View Library" for the full gallery and "Upload a File" for documents; the grab handle now drags to dismiss ([`921cb80`](https://github.com/dappros/ethora-chat-component-rn/commit/921cb80))
- **New:** Room-list header menu is now a bottom sheet (New Chat / Profile / Settings / Sign out) that pulls down to dismiss; `config.headerMenu: true` shows the SDK's own menu without a host callback; Settings restyled into separate cards; shared full-screen modal headers get the same card treatment ([`70b117a`](https://github.com/dappros/ethora-chat-component-rn/commit/70b117a))
- **Improved:** Room list, headers and composer restyled — light grey list ground, floating search strip, white card headers with rounded bottom corners and soft shadow, the composer mirroring it; tapping a room's avatar now opens the chat; profile header buttons realigned with the collapsed avatar ([`c85add7`](https://github.com/dappros/ethora-chat-component-rn/commit/c85add7), [`ea20c90`](https://github.com/dappros/ethora-chat-component-rn/commit/ea20c90))
- **Improved:** Room-list search overlay reworked (v2) with expanded regression tests, alongside session-refresh handling tweaks ([`dd87da1`](https://github.com/dappros/ethora-chat-component-rn/commit/dd87da1), [`ddcd845`](https://github.com/dappros/ethora-chat-component-rn/commit/ddcd845))
- **Fixed:** Unread counts are no longer silently capped at one history page — when the first page is entirely unread the SDK pages further back (bounded) to find the true boundary, and flags the count as a floor when it cannot; the "typing…" indicator is cleared when the app is backgrounded or the device locks; send-message and last-viewed bookkeeping tightened ([`6386e37`](https://github.com/dappros/ethora-chat-component-rn/commit/6386e37))
- **Fixed:** The signed-in user's description survives login (the About section can show your bio); avatars for names starting with a digit render initials; "Save to gallery" works again on Expo SDK 54+ via the media-library legacy runtime ([`1981077`](https://github.com/dappros/ethora-chat-component-rn/commit/1981077), [`921cb80`](https://github.com/dappros/ethora-chat-component-rn/commit/921cb80))
- **Milestone:** `@ethora/chat-component-rn` 26.7.3 and 26.7.4 published ([`8273b7f`](https://github.com/dappros/ethora-chat-component-rn/commit/8273b7f), [`16e8069`](https://github.com/dappros/ethora-chat-component-rn/commit/16e8069))
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 3 commits (branches `2608`/`2609`)
- **New:** Per-agent **LLM model** override in the agent Persona panel (free text with suggestions; empty keeps the platform default), and the SOUL.MD / Heartbeat panels now describe what is live — the agent self-updates its SOUL.MD and the heartbeat scheduler runs — with the schedule grammar (`every 30m`, `idle 15m`, `daily 09:00`, cron) documented inline in en/fr/es. A new diagnostics probe posts into a room with AI agents and transcribes their replies ([`c93f26d`](https://github.com/dappros/ethora-app-reactjs/commit/c93f26d))
- **Improved:** Admin/app-management tabs now show only on the base app host — tenant app hosts present a clean end-user navigation ([`4f6b085`](https://github.com/dappros/ethora-app-reactjs/commit/4f6b085))
- **Fixed:** Product analytics reports image uploads as images (the MIME type is read from the chat component's `metadata.fileType`) ([`3b41f42`](https://github.com/dappros/ethora-app-reactjs/commit/3b41f42))
### Platform API & AI Service
- **New:** **Multi-agent rooms that keep talking.** Rooms with several AI agents no longer fall silent after one exchange — response-gate counters are tracked once per message instead of once per agent, and human-pause, cooldown and spacing rules now *defer* a reply instead of dropping it (newest message wins, one pending reply per agent per room). A configurable cap bounds agent-only turns per human message, and system join/leave notices are never answered.
- **New:** **Real room history for agents.** A per-room transcript log (30-day retention, deduplicated across agents) now feeds each agent's context window: its own turns as assistant messages, everyone else — humans and other agents — as name-attributed turns. Knowledge (RAG) excerpts are injected into the same prompt, so a persona agent stays in character while citing your sources instead of dropping into a stateless FAQ mode.
- **New:** **Heartbeat scheduler.** Agents can now speak first: interval, idle, daily and cron schedules post a proactive turn into every room of an enabled agent, or stay quiet when the model decides there is nothing worth saying. Configured per agent in the admin panel.
- **New:** **Per-agent models.** The agent's LLM model setting is honoured in the chat path, and the model layer handles reasoning-model parameters separately from classic ones, so different model families can be mixed across agents in one install.
- **New:** **One-shot agent reply endpoint** — a server-to-server API call asks an agent a question and gets a single answer back over HTTP, for integrations that need an agent's judgement outside a chat room.
- **Improved:** Operator edits to a running agent (prompt, response mode, cooldown, model, SOUL.MD) hot-apply without a restart; agent tool callbacks resolve against the install's own platform address so self-hosted installs work out of the box; the AI service README is rewritten around Agents, bot instances and multi-agent rooms.
- **New:** **Push notification overhaul for calls and universal builds** — VoIP push notifications and subscriptions (incoming calls ring on iOS through the VoIP channel); a central push gateway delivers to devices running the universal/platform build, with delivery keys routed by build origin (platform vs tenant), owner opt-in and a daily quota for platform-key delivery; the app's public config exposes whether platform push is enabled.
- **Improved:** Apple push delivery now goes direct to APNs over a reused connection (no third-party relay required for iOS).
- **Improved:** Platform usage reports (daily/weekly/monthly) now exclude the platform's own synthetic monitoring traffic — synthetic apps and sessions are flagged at creation and filtered on read, with an opt-in to include them — and the emailed HTML body is capped to stay within mail-provider limits (full data continues in the CSV attachments).
---
## Week 35 (Aug 24 – 30, 2026) — Encrypted-at-rest storage lands in the RN SDK; React 19 support; installs can go invite-only
**Contributors:** Roman Leshchuh, Dmytro Berberov, Borys, Taras Filatov
**Total commits:** ~25 across SDK/app repos + ~6 platform/server | **Active repos:** 5
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 4 commits / v26.6.13 → 26.7.2
- **New:** Secure on-device storage across the SDK — session credentials (REST access and refresh tokens, chat password, secure-media file token) now live in the platform Keychain (iOS) / Keystore-backed encrypted preferences (Android) via the optional `expo-secure-store` peer, and the persisted message-history/room-list cache is AES-256 envelope-encrypted at rest with its key held in the same secure store. Hosts without the peer fall back gracefully (one logged warning), so nothing breaks for existing consumers; verified on device, 18 new unit tests (760 total green) ([`47a9511`](https://github.com/dappros/ethora-chat-component-rn/commit/47a9511))
- **New:** `config.logout` — a built-in "Sign out" item in the room-list header menu with native confirm and host `onBeforeLogout`/`onAfterLogout` hooks, backed by a full teardown (XMPP, state, persisted caches); `useLogout` is now exported so hosts can build their own button on the same awaitable teardown ([`6b312db`](https://github.com/dappros/ethora-chat-component-rn/commit/6b312db))
- **Fixed:** iOS attach sheet — the Take photo / Photo or video / Document rows now reliably open their pickers (a modal-dismiss race left them dead and jammed the document picker), and the picker opens noticeably sooner after the tap ([`6b312db`](https://github.com/dappros/ethora-chat-component-rn/commit/6b312db))
- **Fixed:** Avatar handling — profile and new-chat avatar picking and placeholder rendering corrected ([`56cc6aa`](https://github.com/dappros/ethora-chat-component-rn/commit/56cc6aa))
- **Milestone:** `@ethora/chat-component-rn` 26.7.1 and 26.7.2 published ([`7d3becf`](https://github.com/dappros/ethora-chat-component-rn/commit/7d3becf), [`6b312db`](https://github.com/dappros/ethora-chat-component-rn/commit/6b312db))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 7 commits / v26.7.1 → 26.7.4
- **New:** React 19 support — the package stops bundling react-dom's React 18 reconciler, so hosts on React 19 can adopt the chat component without dependency conflicts ([`eaa46bf`](https://github.com/dappros/ethora-chat-component/commit/eaa46bf))
- **Fixed:** Media loading polish — the loading skeleton now holds while the secure-media file token is absent or rotating, and media is preloaded before the skeleton swaps out, so images no longer flash a blank gap or a broken first paint ([`27fb3fb`](https://github.com/dappros/ethora-chat-component/commit/27fb3fb), [`9cc9a48`](https://github.com/dappros/ethora-chat-component/commit/9cc9a48), [`80ee118`](https://github.com/dappros/ethora-chat-component/commit/80ee118))
- **Milestone:** `@ethora/chat-component` 26.7.1 → 26.7.4 published ([`9848122`](https://github.com/dappros/ethora-chat-component/commit/9848122), [`99be692`](https://github.com/dappros/ethora-chat-component/commit/99be692), [`bb132b4`](https://github.com/dappros/ethora-chat-component/commit/bb132b4), [`eaa46bf`](https://github.com/dappros/ethora-chat-component/commit/eaa46bf))
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | ~14 commits (branches `2607`/`2608`/`2609`)
- **New:** PostHog product analytics wired into the web app, giving the team behavioural insight into the live admin/chat experience ([`937d1d1`](https://github.com/dappros/ethora-app-reactjs/commit/937d1d1))
- **New (next release line):** UI language becomes a real per-profile setting — the picker lists the languages the install offers, persists the choice to the user's profile, and on single-language installs the picker and message translation hide entirely ([`65c9c01`](https://github.com/dappros/ethora-app-reactjs/commit/65c9c01), [`c80eed5`](https://github.com/dappros/ethora-app-reactjs/commit/c80eed5))
- **New (next release line):** The login/registration flow honours the app's new self-service registration switch, so invite-only installs present the right door ([`f52298f`](https://github.com/dappros/ethora-app-reactjs/commit/f52298f))
- **Fixed:** Secure-files media — the file token is forwarded to the chat component so membership-gated media renders ([`65af9a1`](https://github.com/dappros/ethora-app-reactjs/commit/65af9a1)); the web app's own token refresh no longer deadlocks on its own lock ([`f07c280`](https://github.com/dappros/ethora-app-reactjs/commit/f07c280))
- **Improved:** Chat component dependency rolled forward across iteration branches; the frontend build now tolerates a stubbed AI widget so deploys don't fail on optional components ([`cf6f2bc`](https://github.com/dappros/ethora-app-reactjs/commit/cf6f2bc), [`d8a9a73`](https://github.com/dappros/ethora-app-reactjs/commit/d8a9a73))
- **Milestone:** Iteration branch `2609` opened — the next release line (version 26.09, shipping with September) starts taking features
### Platform API & AI Service
- **New:** Per-app switch to close self-service registration — operators can now run an install invite-only, with the guard enforced at the API level, not just hidden in the UI
- **New:** User-profile UI language — the platform stores each user's language choice, with the offered language set fixed at install time; an empty set marks a single-language install so clients can skip the picker and translation machinery
- **Improved:** Stricter install-time configuration validation on self-hosted deployments — the platform now verifies its chat-server settings at startup instead of running with incomplete configuration
### Chat Server & Infrastructure
- **Improved:** Tighter default configuration for self-hosted chat-server installs — deployments now supply their own secrets rather than inheriting sample values
---
## Week 34 (Aug 17 – 23, 2026) — Knowledge goes per-agent; the AI widget ships inside the app
**Contributors:** Borys, Roman Leshchuh, Dmytro Berberov, Yurii T.
**Total commits:** ~29 across SDK/app repos + ~27 platform/server | **Active repos:** 6
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 11 commits (branch `2607`)
- **New:** The Knowledge panel is now scoped per agent — each AI agent sees and manages its own indexed sources, instead of one shared per-app list ([`48594ee`](https://github.com/dappros/ethora-app-reactjs/commit/48594ee))
- **Improved:** The embeddable AI widget is now served by the web app itself and pinned as a versioned dependency instead of a committed bundle — installs no longer depend on an external widget host, and the admin preview drives the widget through its public control API ([`4f8b52c`](https://github.com/dappros/ethora-app-reactjs/commit/4f8b52c), [`fb927fe`](https://github.com/dappros/ethora-app-reactjs/commit/fb927fe), [`ea30d6c`](https://github.com/dappros/ethora-app-reactjs/commit/ea30d6c), [`67d1c8c`](https://github.com/dappros/ethora-app-reactjs/commit/67d1c8c))
- **Fixed:** Widget bundles load as classic scripts so built embeds run everywhere ([`7cc171d`](https://github.com/dappros/ethora-app-reactjs/commit/7cc171d)); the shipped widget bundle wins over stale env configuration ([`5ad01f7`](https://github.com/dappros/ethora-app-reactjs/commit/5ad01f7)); the preview can load the widget from its dev server during development ([`6c6d2e1`](https://github.com/dappros/ethora-app-reactjs/commit/6c6d2e1))
- **Improved:** Chat component dependency updated, session-refresh handling improved, assorted bug fixes ([`8e7e46a`](https://github.com/dappros/ethora-app-reactjs/commit/8e7e46a), [`75bd871`](https://github.com/dappros/ethora-app-reactjs/commit/75bd871), [`e8f6e77`](https://github.com/dappros/ethora-app-reactjs/commit/e8f6e77))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 7 commits / v26.6.11 → 26.6.13
- **Fixed:** Secure media rendered blank in hosts that pass a login snapshot — three holes closed: the session resolver now adopts the fresher persisted session (so the file token needed by membership-gated media is present), bootstrap rotates the session *before* the first chat connect (so short-lived chat passwords are live at boot instead of dead-ending on a connection error), and the testbed folds the top-level file token into the resolved user ([`08dde9b`](https://github.com/dappros/ethora-chat-component-rn/commit/08dde9b), [`788b692`](https://github.com/dappros/ethora-chat-component-rn/commit/788b692), [`2295ca2`](https://github.com/dappros/ethora-chat-component-rn/commit/2295ca2))
- **New:** Secure-upload fallback — when the platform doesn't serve the secure files endpoint yet, uploads retry on the legacy endpoint and remember that for the session, so the SDK works against older self-hosted platforms ([`08dde9b`](https://github.com/dappros/ethora-chat-component-rn/commit/08dde9b))
- **Improved:** Session-refresh and file-handling logic reworked across the SDK ([`dcded7d`](https://github.com/dappros/ethora-chat-component-rn/commit/dcded7d), [`30f148a`](https://github.com/dappros/ethora-chat-component-rn/commit/30f148a), [`cf3c654`](https://github.com/dappros/ethora-chat-component-rn/commit/cf3c654))
- **Milestone:** `@ethora/chat-component-rn` 26.6.13 published ([`6d30de4`](https://github.com/dappros/ethora-chat-component-rn/commit/6d30de4))
### Embeddable AI Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 10 commits / v26.7.1
- **New:** Public control API + embed attribute manifest — host pages can now drive the widget programmatically, and every supported embed attribute is documented in a machine-readable manifest ([`e54872b`](https://github.com/dappros/ethora-ai-chat-widget/commit/e54872b))
- **New:** Configurable starter message greets visitors by default; roomier desktop default size; media features off by default for leaner embeds ([`8571b0c`](https://github.com/dappros/ethora-ai-chat-widget/commit/8571b0c), [`1904529`](https://github.com/dappros/ethora-ai-chat-widget/commit/1904529))
- **Fixed:** Greeting reliability — the welcome message now survives history loads, hidden room-join notices and message ordering, and resumed visitor sessions no longer get stuck ([`cb007c1`](https://github.com/dappros/ethora-ai-chat-widget/commit/cb007c1), [`11906fb`](https://github.com/dappros/ethora-ai-chat-widget/commit/11906fb), [`28f9e73`](https://github.com/dappros/ethora-ai-chat-widget/commit/28f9e73), [`b47145e`](https://github.com/dappros/ethora-ai-chat-widget/commit/b47145e))
- **Milestone:** Widget version 26.7.1 cut, shipped with a prebuilt embed bundle and pinned by the web app; npm package refreshed ([`9832b28`](https://github.com/dappros/ethora-ai-chat-widget/commit/9832b28), [`020391b`](https://github.com/dappros/ethora-ai-chat-widget/commit/020391b), [`4a6d4b9`](https://github.com/dappros/ethora-ai-chat-widget/commit/4a6d4b9))
### Monorepo (`ethora`)
> [ethora](https://github.com/dappros/ethora) | 1 commit
- **Docs:** README links repaired — retired docs-portal links replaced, MCP server repo rename reflected, product page links refreshed ([`dad32884`](https://github.com/dappros/ethora/commit/dad32884))
### Platform API & AI Service
- **New:** Agent-scoped knowledge sources — indexed website sources are now tracked per AI agent instead of per app, with a migration that backfills existing installs; retrieval falls back to the app-level index when an agent has no scoped sources yet, so answers keep working through the transition
- **New:** The chat list now returns each room's last message for the signed-in user, so clients can render conversation previews without extra requests
- **New:** The platform's public config now exposes the install's chat-server host, so clients on self-hosted deployments auto-discover the right endpoint
- **Improved:** Website crawling for agent knowledge hardened for large sites — deep crawls are bounded and processed in prioritized batches, browser concurrency is capped, and the crawl engine was upgraded, so indexing a big site no longer risks exhausting server memory
- **Improved:** Chat-session token lifetimes are now configurable per install — interactive sessions default to short-lived tokens while embedded-widget visitors get long-lived ones, balancing security and visitor convenience
- **New:** API session security strengthened with refresh-token rotation and reuse detection on the release line
- **Docs:** Push service architecture and API documented
### Chat Server & Infrastructure
- **New:** Deploy tooling now runs data migrations automatically as part of install and update — schema and data changes ship with the release instead of requiring manual steps, and already-migrated hosts are detected and re-run safely when a migration is revised
- **Improved:** Chat-token lifetime knobs wired through the deploy environment configuration
- **Fixed:** Crawler service healthcheck corrected; installer treats an empty component directory as missing sources instead of failing part-way
---
## Week 33 (Aug 10 – 16, 2026) — Web Index overhaul for AI agents; push credentials go self-serve
**Contributors:** Borys, Yurii T., Dmytro Berberov
**Total commits:** ~19 across SDK/app repos + ~23 platform/server | **Active repos:** 5
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 12 commits (branch `2607`)
- **New:** Web Index management for AI agents got a full workover in the admin panel — the operator now sees a crawl *start* and watches the index fill live as pages arrive (event-driven, no manual refetch) ([`9c1c606`](https://github.com/dappros/ethora-app-reactjs/commit/9c1c606), [`92b37b5`](https://github.com/dappros/ethora-app-reactjs/commit/92b37b5), [`9705ff2`](https://github.com/dappros/ethora-app-reactjs/commit/9705ff2)); you can view the stored markdown of any indexed URL ([`2f2dfb9`](https://github.com/dappros/ethora-app-reactjs/commit/2f2dfb9)), bulk-remove URLs ([`d1f1ed0`](https://github.com/dappros/ethora-app-reactjs/commit/d1f1ed0)), page through large indexes ([`cd2b4f9`](https://github.com/dappros/ethora-app-reactjs/commit/cd2b4f9)), and get a re-crawl offer when a URL is already indexed ([`34bd94e`](https://github.com/dappros/ethora-app-reactjs/commit/34bd94e))
- **New:** Mobile push credentials are now managed from the app settings screen — upload, status check and removal for both APNs auth keys and Firebase service accounts, no support ticket needed ([`e75b14c`](https://github.com/dappros/ethora-app-reactjs/commit/e75b14c))
- **Improved:** Chat component dependency updated with adaptive-layout fixes ([`0134420`](https://github.com/dappros/ethora-app-reactjs/commit/0134420)); login/register page fixes and general UI polish ([`71ab109`](https://github.com/dappros/ethora-app-reactjs/commit/71ab109), [`e3fbe70`](https://github.com/dappros/ethora-app-reactjs/commit/e3fbe70))
- **Refactored:** Legacy v1 site-crawl UI removed from the admin frontend ([`dab3b78`](https://github.com/dappros/ethora-app-reactjs/commit/dab3b78))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 5 commits / v26.6.3 → 26.6.6
- **New:** File handling moved to the platform's v2 files endpoint with a configurable base URL — media previews, file/photo modals, chat-list thumbnails and unsupported-type fallbacks all updated ([`cda02e6`](https://github.com/dappros/ethora-chat-component/commit/cda02e6))
- **Improved:** Upload fallback logic so hosts on older platform versions keep working against the previous file endpoint, backed by a new regression test suite ([`6cdbb7d`](https://github.com/dappros/ethora-chat-component/commit/6cdbb7d), [`59b6e42`](https://github.com/dappros/ethora-chat-component/commit/59b6e42))
- **Milestone:** `@ethora/chat-component` 26.6.5 and 26.6.6 published ([`7a8b2ec`](https://github.com/dappros/ethora-chat-component/commit/7a8b2ec), [`0a469db`](https://github.com/dappros/ethora-chat-component/commit/0a469db))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 2 commits / v26.6.11
- **Fixed:** Media and video message rendering hardened (video player sizing/controls) and auth/API request handling reworked, with expanded test coverage for API requests and customer-feedback fixes ([`1b3e50f`](https://github.com/dappros/ethora-chat-component-rn/commit/1b3e50f))
- **Milestone:** `@ethora/chat-component-rn` 26.6.11 published ([`1c2516c`](https://github.com/dappros/ethora-chat-component-rn/commit/1c2516c))
### Platform API & AI Service
- **New:** Website crawling for agent knowledge is now fully asynchronous — the crawl endpoint answers immediately and every crawl runs on a queue as a tracked job. Crawled pages are delivered to the platform in incremental batches with progress events to the requesting operator, and crawl failures are reported instead of silently dropped.
- **New:** Web Index API round-out — fetch a single indexed URL with its stored markdown, opt-in pagination for the sources list, duplicate-crawl detection with an explicit re-crawl path, and reindexing queued as a tracked job. The base app's assistant can crawl beyond the standard per-tenant page ceilings.
- **New:** Push credential management API — upload, status and delete endpoints for APNs auth keys and Firebase service accounts, and Push endpoints are now documented in the public API reference.
- **Improved:** Chat-session authentication modernized — the platform now issues short-lived signed chat tokens (JWT) for XMPP sessions, automatically re-issued when the API session refreshes, replacing static per-user chat credentials.
- **Improved:** Background job consumers now self-heal after transient Redis connection blips, so queued work (crawls, exports, notifications) resumes without a restart.
- **Fixed:** Chat-widget sessions now provision correctly for apps whose only bot is a modern bot instance (no legacy bot user required).
- **Refactored:** Legacy v1 site-crawl routes and dead crawl-result handling removed.
### Chat Server & Infrastructure
- **New:** The chat server now accepts JWT-based (SASL) authentication with a signing secret provisioned automatically by the deploy tooling — the server-side half of the short-lived chat-token flow.
- **Docs:** Deploy documentation covers the chunked crawl-callback flow and its batch-size tuning knobs.
---
## Week 32 (Aug 3 – 9, 2026) — Unread counts land in the chat list; audit trail extends to room membership
**Contributors:** Borys, Yurii T., Roman Leshchuh
**Total commits:** ~2 across SDK/app repos + ~20 platform/server | **Active repos:** 4
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 2 commits / v26.6.10
- **Milestone:** `@ethora/chat-component-rn` package version realigned to 26.6.10 for npm publishing ([`f71aae1`](https://github.com/dappros/ethora-chat-component-rn/commit/f71aae1))
- **Improved:** Message-translation UI polish (translation bubble + language selector) and hardened "new messages" divider ordering, backed by new Jest regression suites for manual-translation mirroring and divider order; testbed app updated to exercise the flows ([`f71aae1`](https://github.com/dappros/ethora-chat-component-rn/commit/f71aae1), [`0e60e82`](https://github.com/dappros/ethora-chat-component-rn/commit/0e60e82))
### Platform API & AI Service
- **New:** Per-room unread message counts in the chat list — the signed-in user's room list now returns an unread count per room (computed fresh on each request, with a safety cap), building on the server-side unread-counts API shipped earlier. Chat UIs get accurate badge counts without client-side bookkeeping.
- **New:** Compliance audit trail now covers room membership — room join and leave events, plus message creation, are persisted into the platform audit logs alongside the existing edit/delete and history-access events, completing the who-did-what picture for regulated deployments.
- **Improved:** The website-crawler (RAG ingestion) result callback into the platform is now authenticated with a shared secret, matching the convention already used between platform services; previously silent callback failures are now surfaced in logs.
- **Fixed:** Secure chat attachments now render correctly when embedded by the chat app across origins (resource-policy header adjusted on the token-gated file endpoint).
- **Fixed:** The AI widget's chat binding now saves correctly for apps without a legacy bot user, so the admin panel selection no longer reverts to "None" after reload.
- **Refactored:** Legacy built-in API monitoring retired in favour of the platform's external monitoring stack.
### Chat Server & Infrastructure
- **Improved:** Local development installs now enable the message- and membership-tracking modules out of the box, matching production audit-trail behaviour.
- **Improved:** Installer and deploy hardening continues — chat-server admin commands no longer hang on interactive input, the AI database's readiness is verified with a real query before schema setup, chat-server config rendering is portable to macOS/BSD tooling, and the crawler callback secret is provisioned automatically at install time.
- **Fixed:** Local deployment templates corrected (valid owner-email domain, correct crawler callback URL wiring).
---
## Week 31 (Jul 27 – Aug 2, 2026) — Version 26.08 cut; secure attachments & a full compliance audit trail
**Contributors:** Yurii T., Borys, Dmytro Berberov
**Total commits:** ~7 across SDK/app repos + ~25 platform/server | **Active repos:** 8
- **Milestone:** **Version 26.08 cut.** The July development cycle was tagged `v26.08` on July 31 and npm package versions rolled over on August 1 (`@ethora/setup` 26.08 ([`0ebf165`](https://github.com/dappros/ethora-setup/commit/0ebf165)), `@ethora/mcp-server` 26.08 ([`4623e93`](https://github.com/dappros/ethora-mcp-server/commit/4623e93))). Development continues on the next monthly iteration.
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 3 commits (branch `2607`)
- **Improved:** Login and registration pages refreshed as part of the sitewide design pass ([`c33b5d1`](https://github.com/dappros/ethora-app-reactjs/commit/c33b5d1), [`a65adda`](https://github.com/dappros/ethora-app-reactjs/commit/a65adda))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 1 commit
- **Refactored:** Deploy-script build stamps kept out of version control across the SDK ecosystem ([`c9d41f6`](https://github.com/dappros/ethora-chat-component/commit/c9d41f6))
### Platform API & AI Service
- **New:** Secure chat attachments — file uploads to a chat can now be membership-gated: attachments are stored in a private bucket and streamed back only to authenticated room members via short-lived file tokens. Documented in the public API reference.
- **New:** Compliance audit trail expanded — message edit and delete events, authentication outcomes, and archived-history reads are all persisted into the platform's audit logs, giving regulated deployments a verifiable record of what happened and who accessed what.
- **New:** Immutable audit-log export — a scheduled job ships audit logs to a write-once (immutable) S3 bucket, a building block for HIPAA-style retention and tamper-evidence requirements.
- **Improved:** App-wide broadcast messaging is now restricted to admin and B2B roles, following a customer feedback round.
- **Fixed:** Image and video attachment previews no longer fail on freshly provisioned servers, and upload errors are surfaced in server logs for faster diagnosis.
- **Refactored:** Legacy analytics count/graph routes retired.
### Chat Server & Infrastructure
- **New:** The chat server now reports message edit and delete events, and archived-history access, to the platform audit trail — configurable per deployment, wired automatically by the installer.
- **Improved:** Deployment wiring for the secure-attachments flow (dedicated vhost + environment) and for per-install audit callback endpoints.
- **Fixed:** Installer robustness on localhost and clean-machine installs — chat-server config rendering, callback URL derivation, and stateful data directories all handled safely.
---
## Week 30 (Jul 20 – 26, 2026) — Translation goes regional; compliance audit logging on the chat server
**Contributors:** Roman Leshchuh, Yurii T., Borys
**Total commits:** ~5 across SDK/app repos + ~14 platform/server | **Active repos:** 5
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 4 commits / v26.6.3
- **Improved:** The language picker now works with regional language ids (`en-CA`, `es-US`, `fr-CA`), so readers in regional locales get the right translation variant ([`6677988`](https://github.com/dappros/ethora-chat-component/commit/6677988))
- **Fixed:** Sender avatars now resolve through the live user set instead of the message's own stale copy, so photo updates show everywhere ([`08eb345`](https://github.com/dappros/ethora-chat-component/commit/08eb345))
- **Fixed:** A translation that comes back identical to the original is no longer shown as a "translation" ([`5406622`](https://github.com/dappros/ethora-chat-component/commit/5406622))
- **Milestone:** `@ethora/chat-component` 26.6.3 published ([`9845df9`](https://github.com/dappros/ethora-chat-component/commit/9845df9))
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 1 commit (branch `2607`)
- **Improved:** Chat component updated to 26.6.3 with the regional language-code alignment ([`e9d116e`](https://github.com/dappros/ethora-app-reactjs/commit/e9d116e))
### Chat Server & Infrastructure
- **New:** Compliance-grade audit logging for message-history access — reads of archived chat history are now tracked on the server with request/response outcome and delivered to a configurable audit endpoint. A building block for regulated deployments (healthcare, finance) that need a verifiable trail of who accessed which conversation history.
- **Improved:** Edited messages are re-translated automatically, so readers in other languages always see the translation of the latest text, not the original version.
- **Improved:** Self-hosted deployments can now configure the chat server's translation endpoint directly from the deployment config.
- **Fixed:** Installer robustness — deployment data-sentinel files are written safely alongside data directories, removing an upgrade crash path.
---
## Week 29 (Jul 13 – 19, 2026) — AI message translation lands end-to-end
**Contributors:** Roman Leshchuh, Yurii T.
**Total commits:** ~41 across SDK/app repos + ~4 platform API | **Active repos:** 4
The headline feature of the 26.08 iteration arrived this week: **real-time AI message translation**. Every participant can read the room in their own language while senders keep typing in theirs. Translations travel inside the message itself, so there is no extra round-trip on read.
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 35 commits / v26.6.0 → 26.6.1
- **New:** Sender-side pre-translation — outgoing messages carry their translations inside the message stanza, and each reader resolves the right one by their full locale (e.g. `fr-CA`) with base-language fallback ([`9776215`](https://github.com/dappros/ethora-chat-component/commit/9776215), [`29d69b9`](https://github.com/dappros/ethora-chat-component/commit/29d69b9))
- **New:** Reader controls — switch between automatic and on-demand translation from the language modal; hosts can pin the mode via `forceType`, toggle the language picker, or drive it externally ([`6f7b0d2`](https://github.com/dappros/ethora-chat-component/commit/6f7b0d2), [`00d3c7b`](https://github.com/dappros/ethora-chat-component/commit/00d3c7b), [`dc2d057`](https://github.com/dappros/ethora-chat-component/commit/dc2d057))
- **New:** Translated messages get a real UI — quoted original with the translation emphasized ([`e26077b`](https://github.com/dappros/ethora-chat-component/commit/e26077b), [`5c69cab`](https://github.com/dappros/ethora-chat-component/commit/5c69cab))
- **New:** Static UI localization completed — new-chat, user-selection, room-menu, profile, settings and auth surfaces all follow the language picker ([`26b869b`](https://github.com/dappros/ethora-chat-component/commit/26b869b), [`dbe1489`](https://github.com/dappros/ethora-chat-component/commit/dbe1489))
- **New:** Edited messages are marked as edited, and the flag survives a cache restore ([`996b85f`](https://github.com/dappros/ethora-chat-component/commit/996b85f))
- **Improved:** Send-path performance — translation taken off the send path, the per-send history-fetch storm eliminated, and persist transforms repaired so sends are fast again ([`7eb7daf`](https://github.com/dappros/ethora-chat-component/commit/7eb7daf), [`02cd49f`](https://github.com/dappros/ethora-chat-component/commit/02cd49f))
- **Fixed:** Local cache stability — storage quota budget corrected, member rosters no longer evict the message cache, and live-only state is kept out of persistence ([`5e5baf0`](https://github.com/dappros/ethora-chat-component/commit/5e5baf0), [`34da5f9`](https://github.com/dappros/ethora-chat-component/commit/34da5f9), [`1e519f2`](https://github.com/dappros/ethora-chat-component/commit/1e519f2))
- **Fixed:** Refresh no longer flashes the login form — the stored session is restored seamlessly ([`4a6a2ef`](https://github.com/dappros/ethora-chat-component/commit/4a6a2ef), [`06765ae`](https://github.com/dappros/ethora-chat-component/commit/06765ae))
- **Fixed:** An incoming call no longer double-rings when the tab is open but backgrounded ([`75a2542`](https://github.com/dappros/ethora-chat-component/commit/75a2542))
- **Fixed:** Reconnect polish — no more "Deleted User" names or raw room addresses in notifications right after reconnect ([`7ad8a6f`](https://github.com/dappros/ethora-chat-component/commit/7ad8a6f))
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 6 commits (branch `2607`)
- **New:** AI message translation wired into the hosted web app ([`2185e0f`](https://github.com/dappros/ethora-app-reactjs/commit/2185e0f), [`ae68728`](https://github.com/dappros/ethora-app-reactjs/commit/ae68728))
- **Fixed:** App bootstrap repaired after the chat-component upgrade ([`324fd32`](https://github.com/dappros/ethora-app-reactjs/commit/324fd32))
### Platform API & AI Service
- **Fixed:** Call push notifications now reliably reach devices — the push matcher uses the full user address, so incoming-call alerts line up with stored subscriptions.
- **Improved:** Push-subscription hygiene — device tokens that the push provider reports as dead are pruned automatically, keeping delivery lists clean.
---
## Week 28 (Jul 6 – 12, 2026) — Calls & performance polish; load-testing and monitoring for self-hosted
**Contributors:** Roman Leshchuh, Yurii T., Taras Filatov, Borys
**Total commits:** ~50 across SDK/app repos + ~20 platform/server | **Active repos:** 8
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 33 commits
- **New:** Groundwork for multilingual chat — built-in UI string tables (en/fr/es) with a `useT` hook and `config.i18n`, plus an on-demand Translate button with a pluggable `onTranslate` callback so hosts can bring their own translation endpoint ([`97fd6b0`](https://github.com/dappros/ethora-chat-component/commit/97fd6b0), [`8ee22ab`](https://github.com/dappros/ethora-chat-component/commit/8ee22ab))
- **New:** Online-members popover on group rooms — see who is online straight from the room list or chat header ([`1818621`](https://github.com/dappros/ethora-chat-component/commit/1818621), [`f199238`](https://github.com/dappros/ethora-chat-component/commit/f199238))
- **Improved:** Audio calls get their own compact call card with redesigned spacing, no clipped controls, and correct sizing on mobile toolbars ([`264e636`](https://github.com/dappros/ethora-chat-component/commit/264e636), [`a85da38`](https://github.com/dappros/ethora-chat-component/commit/a85da38), [`258db67`](https://github.com/dappros/ethora-chat-component/commit/258db67))
- **Improved:** Calls ring on any app page, with an OS-level notification when the tab is not visible ([`1bc873a`](https://github.com/dappros/ethora-chat-component/commit/1bc873a))
- **Fixed:** Call history is reliable — the server call state is the canonical log entry, with a local "call ended" fallback so no call disappears from history ([`3495a05`](https://github.com/dappros/ethora-chat-component/commit/3495a05), [`cb89d37`](https://github.com/dappros/ethora-chat-component/commit/cb89d37))
- **Improved:** Chat-loading performance on heavy accounts — a loading stall and duplicate presence sweeps were eliminated, with regression tests added ([`f5e23cd`](https://github.com/dappros/ethora-chat-component/commit/f5e23cd), [`6f43437`](https://github.com/dappros/ethora-chat-component/commit/6f43437), [`c4938e3`](https://github.com/dappros/ethora-chat-component/commit/c4938e3))
- **Fixed:** Unread polish — the New Messages delimiter survives realtime sync, and per-room badges no longer flicker on refresh ([`c8dab3d`](https://github.com/dappros/ethora-chat-component/commit/c8dab3d), [`3aa9270`](https://github.com/dappros/ethora-chat-component/commit/3aa9270))
- **Fixed:** Mobile layout pass — room list adapts to narrow widths without horizontal scroll, long 1:1 titles no longer widen rows, and in-app toasts show across the whole app ([`efbf290`](https://github.com/dappros/ethora-chat-component/commit/efbf290), [`6717857`](https://github.com/dappros/ethora-chat-component/commit/6717857), [`d39d212`](https://github.com/dappros/ethora-chat-component/commit/d39d212))
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 14 commits (branches `2607`/`2606`)
- **Improved:** Theming correctness — attach/mic/send icon chips and system messages no longer render as black squares under dark secondary colours, and per-name avatar colours are preserved ([`189b73e`](https://github.com/dappros/ethora-app-reactjs/commit/189b73e), [`ab328a8`](https://github.com/dappros/ethora-app-reactjs/commit/ab328a8))
- **Fixed:** Mobile UX — flicker removed, menu-bar grey strip closed, room-list padding made responsive ([`2094de7`](https://github.com/dappros/ethora-app-reactjs/commit/2094de7), [`e0079f4`](https://github.com/dappros/ethora-app-reactjs/commit/e0079f4))
- **Testing:** WordPress-embed network probe added to the diagnostics suite ([`d915387`](https://github.com/dappros/ethora-app-reactjs/commit/d915387))
### Embeddable AI Widget (`ethora-ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget) | 1 commit
- **Improved:** The embed script accepts `data-api-url` as an alias for `data-api-base`, matching the documented attribute ([`c2e7f8d`](https://github.com/dappros/ethora-ai-chat-widget/commit/c2e7f8d))
### Developer tooling (`mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | 1 commit (branch `feat/ai-agents`)
- **New:** AI-agents branch brought to 26.07 API parity, with the B2B AI bootstrap fixed for freshly created apps ([`364ffc2`](https://github.com/dappros/ethora-mcp-server/commit/364ffc2))
### Uptime & Self-hosted Ops (`ethora-uptime`)
> [ethora-uptime](https://github.com/dappros/ethora-uptime) | 6 commits
- **New:** Built-in load-testing tool with scenarios, a metrics endpoint, and Grafana/Prometheus links in the load-testing UI ([`57c4885`](https://github.com/dappros/ethora-uptime/commit/57c4885), [`8dd8f98`](https://github.com/dappros/ethora-uptime/commit/8dd8f98))
- **New:** TLS certificate-expiry checks — self-hosted operators get warned before certificates lapse ([`668e2a8`](https://github.com/dappros/ethora-uptime/commit/668e2a8))
- **New:** Opt-in AI journey for synthetic monitoring, kept out of the standard B2B journey by default ([`ee2e3a7`](https://github.com/dappros/ethora-uptime/commit/ee2e3a7))
### Chat Server & Infrastructure
- **New:** Self-hosted monitoring stack — Grafana and Prometheus dashboards ship with the deployment, served behind authenticated access and auto-started on update.
- **New:** Load-testing tooling wired into the server deployment, so operators can benchmark their own instance before go-live.
- **Docs:** AWS backup and restore runbook plus a customer-facing guide for self-hosted deployments.
- **Fixed:** Profile images are returned for chat members via the API.
---
## Week 27 (Jun 29 – Jul 5, 2026) — Version 26.07 ships; web chat polish & message search
**Contributors:** Roman Leshchuh, Yurii T.
**Total commits:** ~17 across SDK/app repos + platform API & chat-server work | **Active repos:** 6
- **Milestone:** **Version 26.07 rolled out.** The June development cycle shipped at the start of July — package versions bumped across the ecosystem on July 1 (`@ethora/setup` 26.07, `@ethora/mcp-server` 26.07), and platform/server work advanced onto the 26.07 iteration. Development now continues on the next monthly iteration.
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 14 commits
A concentrated stability-and-polish pass on the web chat component, tightening host-configuration handling and squashing several interaction bugs:
- **Fixed:** In-app notifications no longer fire for your own messages, nor for the room you are actively viewing ([`04b0044`](https://github.com/dappros/ethora-chat-component/commit/04b0044), [`8810e9b`](https://github.com/dappros/ethora-chat-component/commit/8810e9b))
- **Fixed:** `config.disableNewChatButton` and `config.disableProfilesInteractions` are now honored — the new-chat button and the duplicate Settings / Manage Data room-menu options hide as intended (they were previously dead flags) ([`144e71b`](https://github.com/dappros/ethora-chat-component/commit/144e71b), [`774b102`](https://github.com/dappros/ethora-chat-component/commit/774b102))
- **Fixed:** QR-join reliability — the QR code now encodes the room localpart and builds its link from `config.qrUrl` or the current origin instead of a hardcoded default, so QR joins work outside production and no longer produce a malformed JID ([`aff1dc1`](https://github.com/dappros/ethora-chat-component/commit/aff1dc1), [`d7dd9d1`](https://github.com/dappros/ethora-chat-component/commit/d7dd9d1))
- **Fixed:** Deleting a room now leaves the MUC and clears the active room, so a public room no longer auto-rejoins ([`5d52595`](https://github.com/dappros/ethora-chat-component/commit/5d52595))
- **Fixed:** Guarded config-colour access in the Manage Data modal and room-state destructuring when leaving a room — removes two crash paths ([`fc1487c`](https://github.com/dappros/ethora-chat-component/commit/fc1487c), [`c3c63e5`](https://github.com/dappros/ethora-chat-component/commit/c3c63e5))
- **Improved:** Interaction and visual polish — the whole user row toggles selection (the checkbox was double-toggling), the room list is pinned to a fixed width with a reserved scrollbar gutter so it stops jumping on select, the date-separator pill uses a light chip, and the non-functional Unban placeholder is removed ([`2ab4c8b`](https://github.com/dappros/ethora-chat-component/commit/2ab4c8b), [`6612f8a`](https://github.com/dappros/ethora-chat-component/commit/6612f8a), [`31453df`](https://github.com/dappros/ethora-chat-component/commit/31453df), [`9bed4f2`](https://github.com/dappros/ethora-chat-component/commit/9bed4f2))
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 1 commit
- **Improved:** Mobile styling refinements ([`988d005`](https://github.com/dappros/ethora-app-reactjs/commit/988d005))
### Developer tooling (`setup`, `mcp-server`)
- **Milestone:** `@ethora/setup` and `@ethora/mcp-server` bumped to 26.07 ([`81da293`](https://github.com/dappros/ethora-setup/commit/81da293), [`d287159`](https://github.com/dappros/ethora-mcp-server/commit/d287159))
### Platform API & AI Service
- **New:** Message search for end users — an app's own users can now search their message history through the API, with sortable, direction-aware results.
### Chat Server & Infrastructure
- **New:** Server-side message-tracking archive hook is now compiled into the chat-server image and wired through deployment, so message activity is durably recorded on the server.
---
## Week 26 (Jun 22–28, 2026) — Audio calls & durable reactions
**Contributors:** Roman Leshchuh
**Total commits:** 5 across SDK repos | **Active repos:** 1
A focused week on the React.js chat SDK: voice calling arrives as an opt-in alongside the existing video calls, and message reactions now survive a page reload by being rebuilt from chat history.
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 5 commits / 26.5.7 → 26.5.10
- **New:** Opt-in audio-only calls, rendered next to the video-call button and gated behind a new `config.videoCalls.enableAudioCalls` flag (off by default). Reuses the existing call signalling, so no server change is required ([`686530b`](https://github.com/dappros/ethora-chat-component/commit/686530b), [`1b6591d`](https://github.com/dappros/ethora-chat-component/commit/1b6591d))
- **Fixed:** Message reactions now persist across a refresh. They are archived as standalone history stanzas, so on reload they are extracted and reapplied to their target messages instead of being dropped; added test coverage for in-page merge, multi-reactor and clearing ([`33e127f`](https://github.com/dappros/ethora-chat-component/commit/33e127f))
- **Milestone:** Published 26.5.8 → 26.5.10 ([`8ead128`](https://github.com/dappros/ethora-chat-component/commit/8ead128), [`4421639`](https://github.com/dappros/ethora-chat-component/commit/4421639))
---
## Week 24–25 (Jun 11–21, 2026) — Theming, fonts & broadcasts
**Contributors:** Taras Filatov, Roman Leshchuh, Dmytro Berberov
**Total commits:** 39 across SDK/app repos + platform hardening | **Active repos:** 4
Customization week across the SDKs: host apps gained deep control over colours, fonts and typography on both web and React Native, the Android SDK learned to render system broadcasts cleanly, and the admin panel added archive/restore plus full app/agent export-import.
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 5 commits
Admin lifecycle & data portability (Phase 5b):
- **New:** Archive & restore for users, with a dedicated Archived users tab — admins can take accounts out of active rotation without deleting them ([`0817aa3`](https://github.com/dappros/ethora-app-reactjs/commit/0817aa3))
- **New:** Archive/restore plus JSON/ZIP export-import for Apps and Agents — back up or move an app or agent's full configuration ([`b521cf5`](https://github.com/dappros/ethora-app-reactjs/commit/b521cf5))
- **Improved:** UX polish across the lifecycle / archive / import controls ([`0c74af8`](https://github.com/dappros/ethora-app-reactjs/commit/0c74af8))
- **Improved:** New apps now opt in to a default "Main" chat on creation; tab counts shown comma-separated; chat rooms surfaced in the purge confirmation ([`b8b4b6d`](https://github.com/dappros/ethora-app-reactjs/commit/b8b4b6d), [`d39b6fc`](https://github.com/dappros/ethora-app-reactjs/commit/d39b6fc))
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 18 commits / → 26.5.21
Theming, fonts & platform stability:
- **New:** Colour configuration from the config file — icon colours, sender-name and avatar colours, and message-date colour are all drivable from config, with a worked colour-config example ([`babcfa2`](https://github.com/dappros/ethora-chat-component-rn/commit/babcfa2), [`c0b641f`](https://github.com/dappros/ethora-chat-component-rn/commit/c0b641f), [`a1acac9`](https://github.com/dappros/ethora-chat-component-rn/commit/a1acac9), [`5df2309`](https://github.com/dappros/ethora-chat-component-rn/commit/5df2309), [`d11d862`](https://github.com/dappros/ethora-chat-component-rn/commit/d11d862))
- **New:** Typography and input-layout configuration, configurable header height, and custom fonts on the Chat Profile title and attach-sheet hint ([`7856834`](https://github.com/dappros/ethora-chat-component-rn/commit/7856834), [`32eee85`](https://github.com/dappros/ethora-chat-component-rn/commit/32eee85), [`9c235db`](https://github.com/dappros/ethora-chat-component-rn/commit/9c235db), [`e8aad0c`](https://github.com/dappros/ethora-chat-component-rn/commit/e8aad0c))
- **Fixed:** XMPP reconnect handling ([`322c119`](https://github.com/dappros/ethora-chat-component-rn/commit/322c119)); iOS document picker; iOS fonts & UI polish ([`1ec1175`](https://github.com/dappros/ethora-chat-component-rn/commit/1ec1175), [`ef7f49f`](https://github.com/dappros/ethora-chat-component-rn/commit/ef7f49f), [`bbcdeb0`](https://github.com/dappros/ethora-chat-component-rn/commit/bbcdeb0))
- **Improved:** Pending-message watchdog timing tuned for slower networks ([`0742029`](https://github.com/dappros/ethora-chat-component-rn/commit/0742029))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component) | 11 commits / → 26.5.7
Mirrors the RN theming work for web:
- **New:** Background colours for own/other message bubbles and the input bar (`config.colors.ownMessageBackground` / `otherMessageBackground` / `inputBackground`), plus additional host customizations and web placeholders ([`8448ea3`](https://github.com/dappros/ethora-chat-component/commit/8448ea3), [`7769c14`](https://github.com/dappros/ethora-chat-component/commit/7769c14), [`598ff69`](https://github.com/dappros/ethora-chat-component/commit/598ff69))
- **Improved:** `config.colors.icons` now drives the active send button, the new-chat button and other accent icon-buttons (not just chrome icons), and icon colours are locked against host CSS bleed ([`5b0f936`](https://github.com/dappros/ethora-chat-component/commit/5b0f936), [`15b12b5`](https://github.com/dappros/ethora-chat-component/commit/15b12b5))
- **Improved:** Custom avatar colours ([`d7ca8a9`](https://github.com/dappros/ethora-chat-component/commit/d7ca8a9), [`3bbc604`](https://github.com/dappros/ethora-chat-component/commit/3bbc604))
- **Fixed:** Unread counter no longer ramps up from `0` — the `loading` flag stays true while a room backfills history so the host can reveal the final count at once ([`7122abb`](https://github.com/dappros/ethora-chat-component/commit/7122abb), [`fb1a62a`](https://github.com/dappros/ethora-chat-component/commit/fb1a62a))
### Android SDK (`sdk-android`)
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android) | 5 commits
Broadcast / system-message rendering:
- **New:** System-message broadcasts now render as a centered banner ([`c8d671e`](https://github.com/dappros/ethora-sdk-android/commit/c8d671e))
- **Fixed:** MUC-SUB broadcasts with a bare `<item>` and any node are unwrapped correctly, and broadcasts no longer collapse onto each other ([`b2d152c`](https://github.com/dappros/ethora-sdk-android/commit/b2d152c), [`ab33ff5`](https://github.com/dappros/ethora-sdk-android/commit/ab33ff5), [`a97ffd2`](https://github.com/dappros/ethora-sdk-android/commit/a97ffd2))
- **Fixed:** Zero read-markers no longer permanently silence the unread badge ([`f02e8a6`](https://github.com/dappros/ethora-sdk-android/commit/f02e8a6))
### Platform & Infrastructure
- **Improved:** Server platform hardening and deployment-reliability improvements landed this week (details kept internal).
---
## Week 23–24 (Jun 1–10, 2026) — Version 26.06 ships
**Contributors:** Taras Filatov, r0man31, Dmytro Berberov, Roman Leshchuh
**Total commits:** ~70 across SDK/app repos + platform API | **Active repos:** 7
- **Milestone:** **Version 26.06 released** — the May development cycle shipped at the start of June. The 26.06 iteration was cut on May 26 and package versions rolled across the ecosystem on June 1 (`@ethora/setup` 26.06, `@ethora/mcp-server` 26.06, platform services). Development now continues on the next monthly iteration.
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 23 commits
Admin & onboarding overhaul week:
- **New:** Restructured admin navigation — top-level **Apps / Agents / Billing** sidebar, lifted page headers, branded app tile ([`5886546`](https://github.com/dappros/ethora-app-reactjs/commit/5886546), [`7689e38`](https://github.com/dappros/ethora-app-reactjs/commit/7689e38))
- **New:** Help & Support section in sidebar and admin panel, plus a universal admin footer linking to it ([`23735f8`](https://github.com/dappros/ethora-app-reactjs/commit/23735f8), [`23f19d5`](https://github.com/dappros/ethora-app-reactjs/commit/23f19d5))
- **New:** Native Book-a-Call form posting straight to the HubSpot Forms API, with first/last name + email prefilled from the current user and a consistent fallback across all three entry points ([`033218d`](https://github.com/dappros/ethora-app-reactjs/commit/033218d), [`d9cb8f9`](https://github.com/dappros/ethora-app-reactjs/commit/d9cb8f9), [`8baccbe`](https://github.com/dappros/ethora-app-reactjs/commit/8baccbe))
- **Improved:** `/app/settings` renamed to `/app/account` with a Status card, clearer Account header, Logout, and decluttered layout ([`17d4833`](https://github.com/dappros/ethora-app-reactjs/commit/17d4833), [`d1e2dad`](https://github.com/dappros/ethora-app-reactjs/commit/d1e2dad))
- **New:** Owner-aware Agents UI — visibility tab, public-creation warning, persona-card Edit link, public agents listed ([`4fed2ad`](https://github.com/dappros/ethora-app-reactjs/commit/4fed2ad), [`acced1f`](https://github.com/dappros/ethora-app-reactjs/commit/acced1f))
- **Improved:** Onboarding polish batch — titles, Account, Billing gate, Free plan labeling; lighter "Choose Your Path" modal ([`c0e944f`](https://github.com/dappros/ethora-app-reactjs/commit/c0e944f), [`72981aa`](https://github.com/dappros/ethora-app-reactjs/commit/72981aa))
- **Fixed:** Apps-list pagination, Enter submitting the new-app modal, Blocked Users tab styling ([`8a93d1a`](https://github.com/dappros/ethora-app-reactjs/commit/8a93d1a), [`30a0159`](https://github.com/dappros/ethora-app-reactjs/commit/30a0159))
### Platform API & AI Service
- **New:** "Lazy" agent lifecycle — agent bot instances now disconnect when idle and wake the moment a chat opens, with rate-limited cold-start spawning. Cuts steady-state XMPP connections dramatically on multi-tenant servers
- **New:** Superadmin agent moderation — cross-tenant agent list/get + visibility controls
- **New:** Platform Support Agent extended to apps created before auto-attach landed — every existing app now has a working agent too
- **Improved:** Agent RAG knowledge-base size reporting; private-visibility agents in list endpoints; accurate app totals in the apps API
### React Native SDK (`sdk-reactnative`)
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | 26.5.10 → 26.5.11+
- **New:** Font customization hook (`useChatFonts`) — host apps can now ship custom fonts through the chat surface ([`359d5a5`](https://github.com/dappros/ethora-chat-component-rn/commit/359d5a5), [`217bd3c`](https://github.com/dappros/ethora-chat-component-rn/commit/217bd3c))
- **Improved:** Unread state split into persisted vs ephemeral visibility (`visibleRoomJID`) — removes the main source of tab-mounted single-room unread regressions; bare room ids normalized to full MUC JIDs before join paths
- **Fixed:** Android unread edge cases, keyboard handling, `MessageInteractions`, media preview modal, header `RoomMenu`, global store/registry residue ([`ea29cd8`](https://github.com/dappros/ethora-chat-component-rn/commit/ea29cd8), [`d684fba`](https://github.com/dappros/ethora-chat-component-rn/commit/d684fba), [`fe82389`](https://github.com/dappros/ethora-chat-component-rn/commit/fe82389))
- **New:** "New messages" delimiter; flag to resolve single-room-view unreads; reconnect + caching-system fixes ([`4d3bbc3`](https://github.com/dappros/ethora-chat-component-rn/commit/4d3bbc3), [`577e4f8`](https://github.com/dappros/ethora-chat-component-rn/commit/577e4f8))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component)
- **New:** Font customization (v1) mirroring the RN work ([`19a12e8`](https://github.com/dappros/ethora-chat-component/commit/19a12e8), [`55977db`](https://github.com/dappros/ethora-chat-component/commit/55977db))
- **Fixed:** Broadcast handling ([`0faf7b6`](https://github.com/dappros/ethora-chat-component/commit/0faf7b6))
### Android SDK (`sdk-android`)
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android)
- **New:** Font customization (v1) + font fixes — completing the cross-platform theming story started with v1.0.42's dark mode ([`b41f3f8`](https://github.com/dappros/ethora-sdk-android/commit/b41f3f8), [`69555d6`](https://github.com/dappros/ethora-sdk-android/commit/69555d6))
### Monorepo & Infrastructure
- **New:** DOAP file describing XMPP protocol support (with `schema:logo`) — machine-readable capability manifest for the XMPP ecosystem ([`ddc1ac87`](https://github.com/dappros/ethora/commit/ddc1ac87), [`ec5a31a4`](https://github.com/dappros/ethora/commit/ec5a31a4))
- **Infrastructure:** CI submodule-bump workflow now runs as a matrix across every active YY.MM iteration branch, not just the highest; `mcp-cli` submodule renamed to `mcp-server`
- **Infrastructure:** Server-side video processing enabled end to end (ffmpeg pipeline) and widget conversation history wired through the message archive on production installs
---
## Week 22 (May 25–31, 2026) — 26.06 iteration cut; AI Agents overhaul Phases B & C
**Contributors:** Taras Filatov, r0man31, Dmytro Berberov, Roman Leshchuh, Yurii Tsymborovych
**Total commits:** ~39 across SDK/app repos + ~25 platform API | **Active repos:** 6
- **Milestone:** 26.06 iteration cut from 2605 (May 26) — all submodules switched to track the new iteration.
### Platform API & AI Service
The AI Agents architecture overhaul (Phases B + C) landed this week:
- **New:** Every newly created App now auto-attaches the platform **Support Agent** — fresh signups get a working AI agent in their first chat without any setup
- **Improved:** The AI service now reads its bot inventory and room membership from the platform's canonical data models, retiring the legacy write-back path — one source of truth for agents
- **New:** Agent persona self-update — agents can evolve their own `SOUL.MD` persona document through function calling
- **Fixed:** Direct messages to agents get replies, joined rooms persist across restarts, agents respond to widget visitors without needing an explicit mention
- **Fixed:** New default rooms auto-subscribe the owner and existing users; avatar/name lookups resolve against the correct app in cross-app scenarios
- **API:** Message-context endpoint — fetch the surrounding messages for any search hit
- **Fixed:** Video file path handling in the files API
### Bots Framework (`bots`)
> [ethora-bots](https://github.com/dappros/ethora-bots)
- **Docs:** Multi-agent simulation demo — several AI agents with distinct personas and RAG knowledge bases debate fictional scenarios in a shared room, with reproducible recipe and transcripts ([`a79332f`](https://github.com/dappros/ethora-bots/commit/a79332f))
### Android SDK (`sdk-android`) — v1.0.42
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android) | [CHANGELOG](https://github.com/dappros/ethora-sdk-android/blob/main/CHANGELOG.md)
- **New:** Dark-mode colour overrides across the host-facing theme API — `primaryDark`/`secondaryDark`, independent header/input-bar/input-text tinting, per-mode bubble + background colours. All nullable, defaulting to the light value, so existing hosts pass through unchanged ([`443df44`](https://github.com/dappros/ethora-sdk-android/commit/443df44))
- **New:** `ChatConfig.forceDarkTheme` — pin the chat surface to light/dark regardless of system setting, for hosts that own their theme switcher
- **Improved:** Theme resolution centralised in a `CompositionLocal` (single hex parse at the top of the tree); hex parsing hardened against malformed values ([`05eadbc`](https://github.com/dappros/ethora-sdk-android/commit/05eadbc))
### React Native SDK (`sdk-reactnative`) — 26.5.3 → 26.5.9
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | [CHANGELOG](https://github.com/dappros/ethora-chat-component-rn/blob/main/CHANGELOG.md)
Integration-hardening sprint driven by a customer feedback round:
- **Improved:** Expo packages moved to `peerDependencies` (26.5.3); `emoji-mart` removed and the optional-modules list trimmed (26.5.5) — lighter installs, fewer version conflicts ([`db4d63d`](https://github.com/dappros/ethora-chat-component-rn/commit/db4d63d), [`deb8d87`](https://github.com/dappros/ethora-chat-component-rn/commit/deb8d87))
- **New:** Actionable error overlay with Retry (26.5.4) ([`39e2305`](https://github.com/dappros/ethora-chat-component-rn/commit/39e2305))
- **Fixed:** Reconnect re-joins MUC rooms (messages sent after a drop actually deliver), unread tracking in tab navigators, idle-auth loop, translated-message reconciliation (26.5.9) ([`a2cc01b`](https://github.com/dappros/ethora-chat-component-rn/commit/a2cc01b))
- **Fixed:** Outbound sends queued across XMPP (re)connect races; `expo-av` → `expo-video` migration; media preview/choose modals ([`53a7369`](https://github.com/dappros/ethora-chat-component-rn/commit/53a7369), [`a554b60`](https://github.com/dappros/ethora-chat-component-rn/commit/a554b60))
- **Testing:** Regression tests covering the full customer feedback round; build pipeline + CI ([`2e01eba`](https://github.com/dappros/ethora-chat-component-rn/commit/2e01eba), [`45fe891`](https://github.com/dappros/ethora-chat-component-rn/commit/45fe891))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component)
- **Fixed:** Group-chat member avatars — `getDataFromXml` accepts `photo`/`photoURL`/`profileImage`, profile modal enriches members from `usersSet` ([`2dd52cb`](https://github.com/dappros/ethora-chat-component/commit/2dd52cb), [`2cfb1e0`](https://github.com/dappros/ethora-chat-component/commit/2cfb1e0))
- **Fixed:** `notifyMembersChanged`, header rendering, websocket message spam ([`699728c`](https://github.com/dappros/ethora-chat-component/commit/699728c), [`f99fcdf`](https://github.com/dappros/ethora-chat-component/commit/f99fcdf))
### Sample Android (`sample-android`)
> [ethora-sample-android](https://github.com/dappros/ethora-sample-android)
- **Improved:** JitPack integration + custom colour demo wiring ([`853665f`](https://github.com/dappros/ethora-sample-android/commit/853665f))
---
## Week 20–21 (May 10–24, 2026) — React Native SDK relaunch + cross-platform test blitz
**Contributors:** Taras Filatov, r0man31, Dmytro Berberov, Roman Leshchuh, Yurii Tsymborovych
**Total commits:** ~194 across SDK/app repos (busiest fortnight of the quarter) | **Active repos:** 9
### React Native SDK (`sdk-reactnative`) — the relaunch
> [ethora-chat-component-rn](https://github.com/dappros/ethora-chat-component-rn) | [CHANGELOG](https://github.com/dappros/ethora-chat-component-rn/blob/main/CHANGELOG.md)
~110 commits transformed the RN component into a true drop-in library:
- **New:** Ships as a drop-in npm library with a metro shim helper for consumers ([`11b6ac6`](https://github.com/dappros/ethora-chat-component-rn/commit/11b6ac6))
- **New:** Web-parity flows ported — `initBeforeLoad`, QoS, notifications, persistence; built-in `RoomList` in `ChatWrapper` mirroring the web UI ([`15e6da0`](https://github.com/dappros/ethora-chat-component-rn/commit/15e6da0), [`a5c992f`](https://github.com/dappros/ethora-chat-component-rn/commit/a5c992f))
- **New:** Optimistic pending message bubble flipping to delivered on echo; single-room toggle; email+appToken login mode; 3-tab developer testbed (Setup / Chat / Logs) ([`b1204d7`](https://github.com/dappros/ethora-chat-component-rn/commit/b1204d7), [`0b5d8d6`](https://github.com/dappros/ethora-chat-component-rn/commit/0b5d8d6))
- **Improved:** Testbed migrated to Expo SDK 54 / RN 0.81.5 / React 19.1; eslint wired and cleaned (357 errors → 0); relicensed to MIT ([`b0cc50f`](https://github.com/dappros/ethora-chat-component-rn/commit/b0cc50f), [`815df4c`](https://github.com/dappros/ethora-chat-component-rn/commit/815df4c), [`12bb180`](https://github.com/dappros/ethora-chat-component-rn/commit/12bb180))
- **Fixed:** Spam-tap send merge (two compounding bugs), full logout teardown contract, chat cache limits + unread counter, typing self-detect ([`40d91be`](https://github.com/dappros/ethora-chat-component-rn/commit/40d91be), [`21c28e0`](https://github.com/dappros/ethora-chat-component-rn/commit/21c28e0))
- **Testing:** Massive unit-test layer landed May 16 (one-day blitz: reducers, XMPP builders, hooks, middleware, L2 component layer — ~580 Jest tests by month end); Maestro e2e flows + testIDs ([`79fc0fa`](https://github.com/dappros/ethora-chat-component-rn/commit/79fc0fa))
- **Refactored:** Product-code-policy sweep — placeholder defaults, no tracked credentials, tenant-specific notes scrubbed ([`0577ca9`](https://github.com/dappros/ethora-chat-component-rn/commit/0577ca9))
### Android SDK (`sdk-android`) — v1.0.34 → v1.0.41
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android) | [CHANGELOG](https://github.com/dappros/ethora-sdk-android/blob/main/CHANGELOG.md)
The unread-counting system was rebuilt end to end:
- **New:** `ChatService.lifecycle.onChatPaused/onChatResumed` host API + Compose-native auto-detection of "actively viewing" (window position + focus + lifecycle state) ([`e1833b4`](https://github.com/dappros/ethora-sdk-android/commit/e1833b4))
- **New:** `EthoraChatBootstrap.recomputeUnread()` safety net + `RoomStoreUnreadDbg` verbose diagnostics ([`1cf3a6a`](https://github.com/dappros/ethora-sdk-android/commit/1cf3a6a))
- **Fixed:** Cross-device read-marker sync against ejabberd `mod_private` (single-quote XML attributes), unread listener pinned at `false` on fresh installs, room/user JID collision misclassifying incoming messages as own ([`6102996`](https://github.com/dappros/ethora-sdk-android/commit/6102996))
- **Fixed:** Server-initiated stream termination (login-elsewhere `conflict`) now triggers immediate reconnect instead of a ~13-minute dead socket ([`5600eee`](https://github.com/dappros/ethora-sdk-android/commit/5600eee))
- **Fixed:** MUC joins on stricter `mod_muc` configs — device-resource suffix dropped from join nickname ([`8c64708`](https://github.com/dappros/ethora-sdk-android/commit/8c64708))
- **Fixed:** Rapid-fire sends land in order with XEP-0359 `archiveId` reconciliation; edit/delete resolve the right bubble after bursts; scroll/pagination edge cases ([`0ef64bc`](https://github.com/dappros/ethora-sdk-android/commit/0ef64bc))
- **New:** Apache License 2.0 added ([`af5cae0`](https://github.com/dappros/ethora-sdk-android/commit/af5cae0))
- **Testing:** chat-core unit-test layer + Compose UI tests seeded and consolidated ([`9824c1a`](https://github.com/dappros/ethora-sdk-android/commit/9824c1a))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component)
- **Fixed:** Unread counter stabilised during init via per-room baseline; unread-on-unmount; connecting state; room member counting ([`fed8714`](https://github.com/dappros/ethora-chat-component/commit/fed8714), [`e94791d`](https://github.com/dappros/ethora-chat-component/commit/e94791d), [`6427b36`](https://github.com/dappros/ethora-chat-component/commit/6427b36))
- **Fixed:** Auth flow, `users/my` handling, serialization, system-message + chat-box widths ([`53a6e45`](https://github.com/dappros/ethora-chat-component/commit/53a6e45), [`587b93f`](https://github.com/dappros/ethora-chat-component/commit/587b93f))
- **Testing:** Vitest + React Testing Library scaffold with cross-platform `data-testid` pattern; test files excluded from publish build ([`ce09594`](https://github.com/dappros/ethora-chat-component/commit/ce09594), [`9ffd382`](https://github.com/dappros/ethora-chat-component/commit/9ffd382))
### iOS SDK (`sdk-swift`)
> [ethora-sdk-swift](https://github.com/dappros/ethora-sdk-swift)
- **Fixed:** Delete message ([`ff6f244`](https://github.com/dappros/ethora-sdk-swift/commit/ff6f244))
- **Testing:** Core L1 tests (stores, parser, cache, hooks) + L2 ViewModel tests mirroring the Android coverage; accessibility IDs seeded for E2E ([`d8125f0`](https://github.com/dappros/ethora-sdk-swift/commit/d8125f0), [`764d556`](https://github.com/dappros/ethora-sdk-swift/commit/764d556))
### Web App (`app-reactjs`)
- **New:** Video calls added to the web app (May 21) ([`918c9b8`](https://github.com/dappros/ethora-app-reactjs/commit/918c9b8))
### Platform API & Chat Server
- **API:** `GET /v2/apps/:appId/messages/search` — full-text message search with visibility filtering
- **New:** New server-side message-archiving mode on the chat server — the foundation under message search and widget conversation history
- **Fixed:** User-identity normalisation (duplicate app-prefix collapse) with migration tooling for existing deployments
### Setup CLI (`@ethora/setup`) — first npm publish
> [ethora-setup](https://github.com/dappros/ethora-setup) | [npm](https://www.npmjs.com/package/@ethora/setup)
- **Milestone:** First public npm publish (26.5.0), then 26.5.1 + 26.5.2 ([`ccf7669`](https://github.com/dappros/ethora-setup/commit/ccf7669))
- **New:** Android environment pre-flight (JAVA_HOME / ANDROID_HOME / emulator); auto `npm install` after cloning JS samples; RN testbed opens pre-filled ([`27943c3`](https://github.com/dappros/ethora-setup/commit/27943c3), [`ca18250`](https://github.com/dappros/ethora-setup/commit/ca18250))
- **Improved:** XMPP host derived from the API URL; base app domain defaults ([`6b2eb9b`](https://github.com/dappros/ethora-setup/commit/6b2eb9b))
### MCP Server (`mcp-cli` → `mcp-server`)
> [ethora-mcp-server](https://github.com/dappros/ethora-mcp-server) | [npm](https://www.npmjs.com/package/@ethora/mcp-server)
- **Milestone:** Repo renamed to `ethora-mcp-server`; 26.5.2 + 26.5.3 published to npm and the official MCP Registry ([`b38add7`](https://github.com/dappros/ethora-mcp-server/commit/b38add7), [`35b1c81`](https://github.com/dappros/ethora-mcp-server/commit/35b1c81))
- **Improved:** Claude-ecosystem efficiency pass — all 80 tools annotated (`readOnly`/`destructive`/`idempotent`), descriptions trimmed ~40%, alias tools env-gated, `tools/list` footprint cut ~25%
- **New:** One-click Cursor install, Cline quickstart with verified agent-loop transcript, Smithery + Open Plugin manifests
### Cross-platform testing initiative (all repos)
A unified testing layer now spans all four client platforms with shared test-id conventions: JUnit + Compose tests (Android), XCTest L1/L2 (iOS), Vitest + RTL (web component), Playwright (web app), Maestro E2E (iOS + RN). Each repo's README gained a 4-platform testing overview.
---
## Week 18–19 (Apr 23 – May 9, 2026) — AI website widget + Agents Phase 1
**Contributors:** Taras Filatov, Dmytro Berberov, Roman Leshchuh, r0man31, Yurii Tsymborovych
**Total commits:** ~139 across SDK/app repos + ~35 platform API | **Active repos:** 8
### Platform API & AI Service
The embeddable AI website widget got a real backend:
- **API:** `POST /v2/widget/sessions` — provisions a website visitor with a persistent chat room and invites the App's active Agent automatically
- **API:** `GET /v2/apps/:appId/widget/conversations` — admin view over every widget conversation
- **New:** Visitor metadata captured + surfaced — country, OS, browser, user agent
- **API:** Archive-backed chat history endpoints — read a room's full server-side message history, plus a cleanup/delete endpoint
- **New:** The widget bot is the App's active Agent (persona included in session responses), replacing the earlier fixed-bot wiring
- **New:** Tenant-owner session powering the web app's App Switcher, with self-healing provisioning and clear error surfacing
- **Fixed:** Broadcast messages stamp sender identity so chats render the configured name
- **Improved:** B2B user-management endpoints accept more identity formats; apps list page size raised to 200
### AI Chat Widget (`ai-chat-widget`)
> [ethora-ai-chat-widget](https://github.com/dappros/ethora-ai-chat-widget)
The embeddable website widget moved to its production architecture:
- **New:** Switched to the persistent-room (MUC) variant — the widget provisions a session, joins the visitor's room, and chats in group mode, so conversations survive page reloads ([`ab9ad60`](https://github.com/dappros/ethora-ai-chat-widget/commit/ab9ad60))
- **New:** Active Agent's name + photo on bot bubbles; persona + `data-*` override params consumed from the embed snippet ([`faa3ed0`](https://github.com/dappros/ethora-ai-chat-widget/commit/faa3ed0), [`e1775da`](https://github.com/dappros/ethora-ai-chat-widget/commit/e1775da))
- **Fixed:** Production WebSocket endpoint resolution, optimistic-message dedupe, input gated on room join, version baked into the bundle ([`fa5fd8b`](https://github.com/dappros/ethora-ai-chat-widget/commit/fa5fd8b), [`752a58e`](https://github.com/dappros/ethora-ai-chat-widget/commit/752a58e))
### Chat Server & Infrastructure
- **Improved:** Chat server upgraded to ejabberd 26.04 on OTP 28 across managed installs
### Web App (`app-reactjs`)
> [ethora-app-reactjs](https://github.com/dappros/ethora-app-reactjs) | 43 commits
The AI Agents admin suite took shape:
- **New:** Widget Conversations panel — message history modal, CSV export (selected + full list), bulk delete with confirm, visitor metadata popover ([`1fe1338`](https://github.com/dappros/ethora-app-reactjs/commit/1fe1338), [`178b814`](https://github.com/dappros/ethora-app-reactjs/commit/178b814), [`ca28cba`](https://github.com/dappros/ethora-app-reactjs/commit/ca28cba), [`87430ca`](https://github.com/dappros/ethora-app-reactjs/commit/87430ca))
- **New:** Embed snippet emits `data-app-id` for the MUC widget; persona-card refresh with snippet redesign ([`06cce86`](https://github.com/dappros/ethora-app-reactjs/commit/06cce86), [`12d836a`](https://github.com/dappros/ethora-app-reactjs/commit/12d836a))
- **New:** Agents panel — avatar upload, chat-row bot chips with Remove, live Start/Stop refresh, Test message button, per-room Test + Leave actions ([`9e2db4b`](https://github.com/dappros/ethora-app-reactjs/commit/9e2db4b), [`c288a62`](https://github.com/dappros/ethora-app-reactjs/commit/c288a62), [`e9d7ec1`](https://github.com/dappros/ethora-app-reactjs/commit/e9d7ec1))
- **New:** App Switcher in the Chats page — tenant owners switch XMPP context between their apps ([`592f0b6`](https://github.com/dappros/ethora-app-reactjs/commit/592f0b6), [`0666515`](https://github.com/dappros/ethora-app-reactjs/commit/0666515))
- **New:** Default broadcast sender + per-broadcast override in app settings ([`e757265`](https://github.com/dappros/ethora-app-reactjs/commit/e757265))
- **Improved:** AI surfaces greyed out when AI features are disabled; pagination for non-superadmin apps lists ([`746535d`](https://github.com/dappros/ethora-app-reactjs/commit/746535d), [`56801d4`](https://github.com/dappros/ethora-app-reactjs/commit/56801d4))
- **Testing:** Diagnostics harness for live remote-environment debugging — widget E2E + history probes ([`48654a4`](https://github.com/dappros/ethora-app-reactjs/commit/48654a4))
### iOS SDK (`sdk-swift`)
> [ethora-sdk-swift](https://github.com/dappros/ethora-sdk-swift)
Reliability sprint:
- **Fixed:** Reconnection errors, background reconnect, message retry after disconnect ([`af71763`](https://github.com/dappros/ethora-sdk-swift/commit/af71763), [`9669cd5`](https://github.com/dappros/ethora-sdk-swift/commit/9669cd5))
- **New:** Real-time room create/delete, leave chat, unread tracking from outside the project, multi-message selection, message caching ([`b1910ea`](https://github.com/dappros/ethora-sdk-swift/commit/b1910ea), [`b6dc10d`](https://github.com/dappros/ethora-sdk-swift/commit/b6dc10d), [`a27b3a2`](https://github.com/dappros/ethora-sdk-swift/commit/a27b3a2))
- **Improved:** Media preview reworked; checkmark colours; logout documented; source comments translated to English ([`bebf3c8`](https://github.com/dappros/ethora-sdk-swift/commit/bebf3c8), [`c2d1f2d`](https://github.com/dappros/ethora-sdk-swift/commit/c2d1f2d))
### React.js SDK (`sdk-reactjs`)
> [ethora-chat-component](https://github.com/dappros/ethora-chat-component)
- **Fixed:** Avatar resolution pipeline — `photo`/`photoURL`/`profileImage` attributes accepted; live messages enriched through full author resolution; "Deleted User" un-sticks once identity is available ([`2244f87`](https://github.com/dappros/ethora-chat-component/commit/2244f87), [`371e674`](https://github.com/dappros/ethora-chat-component/commit/371e674), [`345e246`](https://github.com/dappros/ethora-chat-component/commit/345e246))
- **Fixed:** MUC presence + history restored on fresh private-chat create; rooms slice cleared on logout (cross-app leak); JWT login; multi-message support ([`77f76ae`](https://github.com/dappros/ethora-chat-component/commit/77f76ae), [`573c00a`](https://github.com/dappros/ethora-chat-component/commit/573c00a), [`eb1a9a2`](https://github.com/dappros/ethora-chat-component/commit/eb1a9a2))
- **Refactored:** XMPP session lifecycle unified; presence timeouts standardised ([`7cf1ad6`](https://github.com/dappros/ethora-chat-component/commit/7cf1ad6))
### Android SDK (`sdk-android`) — v1.0.29 → v1.0.33
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android) | [CHANGELOG](https://github.com/dappros/ethora-sdk-android/blob/main/CHANGELOG.md)
- **New:** In-bubble timestamp + sent indicator on message bubbles ([CHANGELOG 26.04.30](https://github.com/dappros/ethora-sdk-android/blob/main/CHANGELOG.md))
- **New:** `EthoraChatSdk.initialize(context)` / `shutdown()` — one-shot idempotent process-level lifecycle for SDK persistence
- **Fixed:** Duplicate DataStore instances on Activity recreation; bootstrap socket preserved when the Chat composable unmounts (background unread listeners keep working); media bubbles fall back to a file icon when the preview URL fails
### Setup CLI (`@ethora/setup`)
> [ethora-setup](https://github.com/dappros/ethora-setup)
- **Fixed:** React.js flow writes runtime keys to gitignored `.env.local` (including `VITE_APP_TOKEN`), dev-server command corrected to `npm run dev` ([`7976082`](https://github.com/dappros/ethora-setup/commit/7976082), [`8199319`](https://github.com/dappros/ethora-setup/commit/8199319))
- **New:** Android pre-flight check for the required Android Platform SDK ([`33c2610`](https://github.com/dappros/ethora-setup/commit/33c2610))
### Sample Android (`sample-android`)
> [ethora-sample-android](https://github.com/dappros/ethora-sample-android)
- **Improved:** Gradle 9.4.1 upgrade, early SDK bootstrap in `Application`, git SHA + branch build stamping, `.env` policy compliance ([`40b89fc`](https://github.com/dappros/ethora-sample-android/commit/40b89fc), [`8255c43`](https://github.com/dappros/ethora-sample-android/commit/8255c43))
---
## Week 17 (Apr 16–22, 2026)
### Android SDK (`sdk-android`)
> [ethora-sdk-android](https://github.com/dappros/ethora-sdk-android) | [CHANGELOG](https://github.com/dappros/ethora-sdk-android/blob/main/CHANGELOG.md)
Major feature release (Apr 21):
- **New:** URL link previews in messages — new `UrlPreviewStore` renders link cards inline ([`2de87c6`](https://github.com/dappros/ethora-sdk-android/commit/2de87c6))
- **New:** Connection state monitoring — `ConnectionStore` + `ConnectionHook` expose live connection status to host apps
- **New:** Event dispatcher — `ChatEvents` + `ChatEventDispatcher` let host apps subscribe to chat lifecycle events
- **Docs:** Feature documentation + Android ↔ iOS platform comparison + restructured README ([`35909da`](https://github.com/dappros/ethora-sdk-android/commit/35909da))
- **Refactored:** Sample app extracted into [`ethora-sample-android`](https://github.com/dappros/ethora-sample-android) — SDK repo no longer tracks `sample-chat-app/` ([`86fd0a2`](https://github.com/dappros/ethora-sdk-android/commit/86fd0a2))
- **Fixed:** Message loader + XMPP websocket edge cases, `ChatRoomView` rendering ([`9998279`](https://github.com/dappros/ethora-sdk-android/commit/9998279))
### iOS SDK (`sdk-swift`)
> [ethora-sdk-swift](https://github.com/dappros/ethora-sdk-swift) | [CHANGELOG](https://github.com/dappros/ethora-sdk-swift/blob/main/CHANGELOG.md)
- **New:** `UnreadStateBridge` hook for badge propagation to host apps ([`83208b9`](https://github.com/dappros/ethora-sdk-swift/commit/83208b9))
- **Testing:** `UnreadStateBridgeTests` added ([`83208b9`](https://github.com/dappros/ethora-sdk-swift/commit/83208b9))
- **Docs:** Full README + INSTALLATION overhaul, new `features.md` ([`0e1605f`](https://github.com/dappros/ethora-sdk-swift/commit/0e1605f))
- **Refactored:** API surface alignment across `AppConfig`, `AuthAPI`, `RoomsAPI`, `XMPPClient`, `MessageParser`, `ChatRoomViewModel`, `RoomListView` ([`146c52f`](https://github.com/dappros/ethora-sdk-swift/commit/146c52f))
- **Refactored:** `Examples/` folder removed — playground moving to dedicated sample repo ([`97d54f9`](https://github.com/dappros/ethora-sdk-swift/commit/97d54f9))
### Sample Android (`sample-android`)
> [ethora-sample-android](https://github.com/dappros/ethora-sample-android) | [CHANGELOG](https://github.com/dappros/ethora-sample-android/blob/main/CHANGELOG.md)
- **Refactored:** Package namespace `com.ethora.sample` → `com.ethora.samplechatapp` ([`74d0521`](https://github.com/dappros/ethora-sample-android/commit/74d0521))
- **New:** Firebase push notifications wired — `EthoraApplication`, `EthoraFirebaseMessagingService`, AndroidManifest entries
- **New:** `MainActivity` rewritten as full playground-style sample (881 lines)
- **API:** `buildConfigField` schema updated — added `ETHORA_USER_JWT` + `ETHORA_ROOM_JID`, removed `ETHORA_APP_TOKEN`
### Setup CLI (`@ethora/setup`) — v26.04
> [ethora-setup](https://github.com/dappros/ethora-setup) | [CHANGELOG](https://github.com/dappros/ethora-setup/blob/main/CHANGELOG.md)
- **Improved:** Server presets switched to canonical `chat.ethora.com` defaults (Cloud Production + Cloud QA) ([`5c83f05`](https://github.com/dappros/ethora-setup/commit/5c83f05))
- **Fixed:** `MainActivity.kt` patcher generalised to accept any host — was silently no-op'ing after SDK templates moved off `ethoradev.com` ([`35d47ef`](https://github.com/dappros/ethora-setup/commit/35d47ef))
---
## Week 15–16 (Apr 2–15, 2026)
### iOS SDK (`sdk-swift`)
- **New:** SDK playground (`Examples/SDKPlayground/`) — Setup / Chat / Logs tabs for exercising SDK features ([`53a8839`](https://github.com/dappros/ethora-sdk-swift/commit/53a8839),