xPulse
πŸ‡¬πŸ‡§ EN

xPulse Chat – Roadmap

As of: March 2026 Companion documents: TOOL_chat_concept-ui-layout.md, MAIN_roadmap-ecosystem.md


Version Overview

v1.2.0 Bug fixes, performance, pairing UI [LIVE]
v1.3.0 UI/CSS refactoring + app shell layout [PROGRESS|TESTING]
v1.4.0 Components + i18n (de/en) [PLANNED]
v1.5.0 Themes (dark/light) [PLANNED]
v1.6.0 Profile features + avatar + chat images [PLANNED]
v1.7.0 Emojis, stickers, GIFs [PLANNED]
v1.8.0 Chat history paging (lazy render, local) [PLANNED]
v1.9.0 Peer sync (history + profile via DataChannel) [PLANNED]
v2.0.0 Abrax – AI assistant via @xpulse/ai [PLANNED]

v1.3.0 – App Shell + Landing Page + Project Foundation

Status: PROGRESS Β· Staging: rc-1-3-0.stage.xpulse.one

UI/UX

Project Foundation


v1.4.0 – Components + i18n

Status: PLANNED Prerequisite: Verdaccio running, @xpulse/theme + @xpulse/theme available

Extraction

i18n

Feedback

Docs


v1.5.0 – Themes


v1.6.0 – Profile Features + Avatar + Chat Images


v1.7.0 – Emojis, Stickers, GIFs


v1.8.0 – Chat History Paging

Prerequisite: v1.6.0 completed (IndexedDB)

Lazy rendering of chat history: initially only the last 50 messages are rendered. Older messages can be loaded via button (50 at a time, cursor-based via timestamp). All data comes from local storage – no network required.

Features


v1.9.0 – Peer Sync

Version: v1.9.0 (after v1.6.0 – IndexedDB prerequisite for image sync)

Problem

Chat history and profile data currently only exist locally in localStorage (via session.js). If Peer A writes a new message while Peer B is offline, that message is gone for B forever. Similarly, B always only sees A's login name – no display name, no avatar, no current profile state.

Goal

When two peers connect, two things are synchronised – without a server, purely P2P over the DataChannel:

  1. Profile sync – current display name, avatar, etc. from A β†’ B and vice versa
  2. History sync – missing messages since the last shared timestamp

How It Works (Draft)

Peer A connects to Peer B
↓
── Phase 1: Profile Sync ────────────────────────────
A sends: { type: 'sync:profile', displayName: 'Alex', avatar: null, updatedAt: ... }
B stores A's profile locally β†’ from now on shows "Alex" instead of login name
B sends the same back β†’ A knows B's current profile state
↓
── Phase 2: History Sync ────────────────────────────
A sends: { type: 'sync:request', lastTs: 1710000000000 }
(= timestamp of the last known message from B)
B responds: { type: 'sync:response', messages: [...] }
(= all messages B sent after lastTs)
A stores missing messages in localStorage + renders them
B does the same in the other direction

Profile Data in Sync

Field Description From Version
displayName Displayed name (freely chosen, β‰  login) v1.7.0
avatar Base64 thumbnail or null v1.7.0
updatedAt Timestamp of last profile change v1.7.0

Profile sync is therefore already useful from v1.7.0 onwards – once display name exists. History sync can come earlier (no profile required).

Limitations (by design)

Open Questions

Topic Status
Maximum sync depth? (all messages or only last N / last X days) TBD
What happens with very long history? (DataChannel size limit) TBD
Conflict handling on simultaneous sync? TBD
Encryption of sync payload? Yes – same AES-GCM crypto as normal messages
Avatar sync: size limit? (DataChannel ~256KB chunks) TBD

Possible Version


v2.0.0 – Abrax (Codename: Abra)

Status: PLANNED Prerequisite: v1.9.0 completed, @xpulse/ai package ready Concept: COMP_ai_concept.md

AI integration via @xpulse/ai – a special AI peer in the peers list, with full conversation context, streaming, and full user control over provider, model, and personality. Browser-to-provider directly, no detour via xPulse server.

AI Peer

Provider & Settings (Profile)

Chat Info Panel

i18n

Chat UX

en/roadmap.md 2026-04-17