Commit Graph
3 Commits
Author SHA1 Message Date
Jean-Pierre MartineauandClaude Opus 4.8 a03dedb09c Add message delivery retry, channel capacity discovery, and a compose byte budget
Three interrelated improvements to the chat/channel experience:

Outgoing byte budget & unified transcript (ui/chat.py, ui/tui/prompt.py):
- Cap outgoing messages at MeshCore's UTF-8 limits (150B direct, 130B
  channel) and block over-limit sends, keeping the buffer intact to trim.
- Show a live `used/limit` gauge in the compose bar whose used count steps
  green→yellow→orange→red by bytes remaining, with truer yellow/orange hues.
- Color the overflow characters red in the compose line (multibyte-safe).
- Render direct chats with the same grouped, per-sender layout as channels
  (headers, day dividers) instead of one line per message.

Direct-message delivery retry (services/chat_service.py, persistence,
core/models.py, tools/chat.py, ui/tui/session.py):
- Track outbound acked state (None awaiting / True / False) with a persisted
  row_id, add resend_direct + update_chat_ack, and wire Ctrl-R to retry the
  latest unacknowledged message in place with ⏳/✅/❌ delivery glyphs.

Channel slot capacity discovery (core/channels.py, core/connection.py,
ui/channels.py, tools):
- Discover the firmware's real channel-slot count via a bounded read-only
  probe (Device.channel_capacity) instead of assuming 8; show used/total in
  the manager and refresh the chat slot→identity cache after any mutation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 23:12:25 -04:00
Jean-Pierre MartineauandClaude Opus 4.8 4c725bd22a Key channel history by identity and mark channel openness in chat
Store channel messages under a slot-independent channel identity (sha256 of
the effective secret) instead of the raw slot index, so reordering or re-keying
slots no longer scrambles history. DB schema v3->v4 adds a channel_id column
with an idempotent migration and a lazy backfill that maps legacy rows to the
channel currently in each slot.

Recognize the firmware's fixed-key default "Public" channel as public: add
DEFAULT_PUBLIC_SECRET / KNOWN_PUBLIC_SECRETS and split is_name_derived (key
reproducible from the name, so it can be re-derived on write) from
is_public_channel (shared meshwide). The default channel no longer mislabels
itself as private, and its well-known key is preserved on edit/reorder.

Lead each chat picker row with a glyph: the channel's openness marker
(# name-derived, globe fixed-key public, lock private) or, for a direct chat,
a speech balloon once we've exchanged messages and a person before. A shared
channel_glyph() keeps the channel manager and the picker in sync.

Round out the messaging UX: live callable row titles and plain-text filtering
in the TUI select screen, plus assorted device-picker, monitor, route-map, and
config-editor menu refinements.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 20:31:44 -04:00
Jean-Pierre MartineauandClaude Opus 4.8 6856b682b1 Add channel/direct chat feature and polish the passive-monitor UX
Introduce channel and direct messaging: an always-on ChatService that
records inbound messages to history, a live full-screen chat screen, and
a chat tool (interactive picker plus send/history/list/listen CLI). This
bumps the DB schema to v3 and adds the supporting models, repository
queries, and connection wiring.

Also polish the monitor/menu UX:
- Stop console log handlers from corrupting the full-screen TUI by
  detaching the RichHandler for the life of the session (file logging
  continues); most visible when toggling the monitor.
- Colour only the header's monitor glyph (green ● on, red ○ off).
- Crop the header to a single line instead of wrapping on narrow terminals.
- Drop the redundant toggle-confirmation window so toggling returns
  straight to the main menu.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 17:41:12 -04:00