Commit Graph
68 Commits
Author SHA1 Message Date
osmaczko 4f18e4f10b feat: tail the session log in a developer console
The stack's account of a failure was scattered across four writers in three processes and reachable only from a terminal, so anyone running the app from a launcher had no way to see why something did not work, and no way to attach that account to a report. The console tails the file the host assigns and filters it by domain, severity and text, with an export for the whole file or for exactly what the filters pass.

Every failure the backend reports now goes to the log as well as the strip, through one reporter, which is also what stops a reason the module could not supply from rendering as a trailing colon.

Only a bounded window of the file is held, shared out between domains rather than kept strictly newest first, and a domain gives up its ordinary lines before its severe ones. A writer producing thousands of lines a minute would otherwise push every quieter one out of reach within minutes, leaving a filter chip counting lines nothing could show and a header counting errors that were no longer there. What a line says about itself outranks what relayed it, so a severity the writer stated beats the pseudo level the host stamped, and a field naming a module beats the innermost scope beside it.
2026-07-28 08:51:07 +02:00
osmaczko 9a53caeb73 feat: hold failures on a status bar instead of a passing toast
A toast covered the conversation for four seconds and then took the only copy of the message with it, so two failures in quick succession left the first unread and unrecoverable. The strip across the foot keeps the newest one until it is activated and counts the ones behind it.
2026-07-27 13:49:18 +02:00
osmaczko 5f223d812d fix: keep a pending member on the roster across chat switches
The pending marker was tracked in the backend as a single set of addresses for whichever conversation was open, so switching away had to clear it or its rows would leak into the next group. Coming back re-read the roster from the module, which listed committed members only, and the invite vanished from the panel until the group committed it minutes later.

The module's roster now flags an invite it has not committed yet, so the marker is read per conversation from the module instead of being tracked here, and survives any number of switches. memberCount stays committed-only, and a pending invite no longer counts as being on the roster when a message arrives from an address the panel has not seen. The same rev answers the roster call for a direct conversation, where it used to error, so the details panel resolves the peer's address instead of leaving the row blank.
2026-07-27 08:10:49 +02:00
osmaczko 05fcb984d0 fix: hold the side columns to their widths and open a conversation ready to type
A layout nested in another layout fills by default, so the sidebar and the right column took the slack meant for the thread: at 1024px the sidebar rendered 415px against a design of 320. Both are pinned to their widths now, the thread carries a floor so a window too narrow for three columns clips the right one rather than the middle, and selecting a conversation puts the caret in its composer.
2026-07-25 23:06:07 +02:00
osmaczko 3054388bc4 refactor: take the design system's monospace token
Every hex identifier the chat shows named the platform's generic monospace family itself, behind a local token standing in for one the design system did not have. It has one now, so the stand-in and its upstream TODO go.
2026-07-25 22:54:54 +02:00
osmaczko edcad71d31 test: cover the redesign's new components standalone
Every component has to instantiate from its declared properties alone, with mock data and no host context, and the chat vocabulary the redesign added had no such proof: the icon button, the day chip, the facepile and its overflow, the panel heading and its count, a detail row's copy, and the thread header holding one line of description whatever it is given.
2026-07-25 22:54:44 +02:00
osmaczko 1e3d672b6e refactor: copy a member's address from the row's own menu
A copy button appeared on every roster row the pointer crossed, so a list whose whole job is to say who is in the group was never at rest. A right-click on a row now offers Copy address, and the row itself is nothing but the member's face, identity and standing, with an invitation that has not committed saying so in words.
2026-07-25 22:54:44 +02:00
osmaczko 2b24d8b174 refactor: give the right column the roster and the facts on demand
A group's roster had a header and a floating button and nothing else, while the conversation's own facts (its full description, what kind it is, its id, the other participant's address) were locked in two modal dialogs that had to be dismissed before the thread could be read again. The roster is now a card with its count in the heading and Add member pinned to the foot, and one details panel above it carries what both dialogs did, opening and closing from the thread header without covering anything.
2026-07-25 22:54:44 +02:00
osmaczko 821162ebf5 refactor: rebuild the thread around who is speaking
A thread of identical bubbles under a bare title gave no answer to "who is this and who else is here", and the composer carried a labelled button and a growing row of hints for a field that only ever sends text. The header now names the conversation with its avatar, one elided line of description and the faces of its members, and offers its remaining facts behind one toggle; a message carries its sender's face and name in their own colour where a run of theirs begins, dates ride on a chip over the thread rather than a rule through it, and the composer is one pill with the send action at its end.
2026-07-25 22:54:44 +02:00
osmaczko 6919dceff9 refactor: lay the sidebar out as cards
The panes met edge to edge with only a hairline between them, so nothing on screen was grouped and the eye had to find the boundaries. The sidebar is now a conversations card over the account card on an inset background, its rows carry the avatar with the time and unread count stacked out of the name's way, and one full-width New chat button naming what each entry starts replaces the header and its menu. The status strip goes with it: the connection state belongs on the account card, and the messages it carried were either failures the toast already reports or narration of what the list itself shows.
2026-07-25 22:54:44 +02:00
osmaczko 6e6d2a2e1e feat: give every identity an avatar
A list of hex labels reads as one undifferentiated column, and the eye needs something faster than eight characters to tell one conversation or member from another. Every model now carries the initials and a colour ramp for its row's identity, hashed the same way in one place so an account keeps its colour across the sidebar, the roster and this account's own card, and a group is squared off and glyphed so it reads apart from a person.
2026-07-25 22:54:44 +02:00
osmaczko 27af083d13 feat: draw the chat's own icon set
The redesign leans on glyphs the design system does not carry (a group, a person, an info toggle, a send arrow, an add-member, a caret), and the hosts' Qt has no SVG image plugin, so the module can only load rasters. The sources live under tools/icons with a script that renders them, so a glyph can be edited rather than redrawn, and the existing copy icon is re-cut from the same stroke family.
2026-07-25 22:54:44 +02:00
osmaczko ebefe70d19 feat: keep this account's address on screen
Sharing an address took three actions (a button, a dialog, a copy) for a value the app already knows the moment it is online, and the footer printed an installation id nobody can act on instead. The backend now reads get_address() on the online transition and publishes it, and an account card at the foot of the sidebar carries the short identity, the connection state and the address itself with a copy beside it.
2026-07-25 22:54:44 +02:00
osmaczko 4710a19142 chore: pin the design system to its paired polish branch
The scroll-bar, sizing, scrim and focus fixes this branch pairs with live in logos-co/logos-design-system#39; a plain build of this branch should render with them instead of the module builder's pinned design system. A top-level input routes the builder's design-system input to that branch.
2026-07-25 22:54:44 +02:00
osmaczko 7f3edfde20 refactor: move the components' private helpers into a d object
An underscore prefix only labels a function internal while leaving it callable on the component's surface; holding it in a child QtObject actually scopes it away, the shape the design system's own controls use. The component tests switch from the removed helpers to the action buttons' clicked signal, which exercises the same guards through the surface a user reaches.
2026-07-24 18:02:17 +02:00
osmaczko adeeb14d3f fix: keep the error toast clear of the composer
The transient error toast was bottom-centered in the window overlay, which laid it over the message input and send button, the exact controls a failed action points the user back to. Show it as a top-center banner instead.
2026-07-24 17:59:18 +02:00
osmaczko 9c35874316 fix: make the group self-marker legible
The "you" tag that marks the current user in a group's member list was set in the badge text size, small enough to be awkward to read beside the member name.

Size it like the name.
2026-07-24 17:59:18 +02:00
osmaczko 30aac3c287 fix: size dialog display areas to what they show
The address and description areas were fixed-height boxes taller than their usual contents, so a one-word description sat in an 80px well with a scrollbar down the side of it.

The address now takes the height of its content and stops at the height it used to have, scrolling past that. The description, where a content-sized scroll view sheared the label beneath it, is instead a plain text bounded to a few lines.
2026-07-24 17:59:18 +02:00
osmaczko 361743da0d fix: make the open conversation and an empty one readable in the list
The selected row's tint sat close enough to the hover tint that the open conversation was hard to pick out, and a conversation with no messages left its second line blank, which read as a rendering gap.

The selection is now distinctly tinted and an empty conversation says so where its last message would be.
2026-07-24 17:59:06 +02:00
osmaczko 868580e877 feat: copy a message from its context menu
Selecting message text worked, but the desktop reflex of right-clicking a message offered nothing, so copying meant dragging over the text first.

A right-click now opens a menu whose Copy takes the selection when there is one and the whole message otherwise. The rows share one menu.
2026-07-24 17:58:51 +02:00
osmaczko 148b70a392 feat: show details for a direct conversation
A direct conversation had no details surface at all: the Details button was reserved for groups, so there was nowhere to read or copy the address of the person you were talking to.

Details now opens for any conversation, with a dialog for direct ones carrying the peer's address and the conversation id. The address comes from the conversation's roster, which the backend now fetches for direct conversations too, and its row stays hidden until the roster provides one.
2026-07-24 17:58:51 +02:00
osmaczko 45eab78998 feat: give every copyable value a copy button next to it
Copying a member's address meant clicking the row with nothing saying so, and the dialogs put their copy action in the footer, away from the value it acts on.

Each copyable value now carries a copy button beside it, keeping the row click and the inline confirmation as they were.

The icon ships with the plugin rather than coming from the design system, so it renders on hosts whose design system predates it.
2026-07-24 17:58:33 +02:00
osmaczko 0e433befcd feat: start conversations from one New menu in the sidebar
The header carried two side-by-side buttons that truncated their own labels to "New gr...", plus a connectivity dot the status bar already shows.

A single "+ New" button now opens a menu with an entry per kind of conversation, and the dot is gone. Sharing your own address stays the full-width action at the foot of the list.
2026-07-24 17:57:50 +02:00
osmaczko 8b771f45e8 fix: mark a conversation someone else started as unseen
A conversation arriving from an invitation appeared in the sidebar with nothing to distinguish it, so a group someone added you to slid in unnoticed among the existing rows.

An incoming conversation now carries the unread badge until it is opened, the same as an unread message does.
2026-07-24 17:57:50 +02:00
osmaczko e954e507d6 fix: count invited members separately in the group details
The details dialog rendered its plural source string literally, "1 member(s)", and counted only the committed roster, so a group with an invitation in flight looked like it had lost the invited person.

It now reads "3 members, 1 invited", with the backend reporting outstanding invitations alongside the roster size.
2026-07-24 17:57:50 +02:00
osmaczko de629920d6 fix: say what a pending member means without the protocol
Inviting someone reported "peer joins when the group commits", the explainer named deMLS and its commit timer, and a pending row's tooltip read "waiting for commit". None of that means anything to the person waiting for a friend to show up in a group.

The same facts, including the up-to-a-minute wait, are now stated in the user's terms.
2026-07-24 17:57:50 +02:00
osmaczko d2db8027b3 fix: let status messages go quiet
The status bar kept the last event it was handed, so "Address ready" or an invite confirmation sat there for the rest of the session and read as the app's current state.

A message now clears after a few seconds; the connectivity label and the identity stay, since those are state rather than announcements.
2026-07-24 17:57:50 +02:00
osmaczko 3f47d08028 fix: keep a message the module refused
The composer cleared on submit and the failure path only raised a toast, so a rejected message was gone: the text had already been dropped from the field and from the conversation's draft.

The backend now reports the refused message and the thread offers it back in the composer, leaving a composer the user has already typed into alone.
2026-07-24 17:57:50 +02:00
osmaczko 1292a7cd59 fix: tell the user why the composer is closed
The composer showed "Chat not connected" whenever it was disabled, so a connected app with no conversation selected reported a connection problem it did not have.

It now names the actual cause, keeping the offline wording for offline and asking for a selection otherwise.
2026-07-24 17:57:50 +02:00
osmaczko 06db28c610 fix: switch conversations without flashing the previous one
Selecting a conversation updated the header, the message model and the roster as three independent streams, and the view renders them through separate replicas, so a switch showed the previous conversation's rows under the new title, then a false "No messages yet", then the real thread.

The backend now reports which conversation the models actually hold, and the panes render rows only while that matches the selection: a thread still loading stays blank for a moment, then shows placeholder bubbles, and only a settled model may call a thread empty.

The sidebar and the header no longer wait for that round trip at all: a clicked row carries its own name, kind and description, which the view applies straight away and drops once the backend confirms the switch.
2026-07-24 17:57:50 +02:00
osmaczko 6a2883e186 fix: format every timestamp through one authority
Message bubbles formatted their own clock time in QML while the conversation list formatted its in the model, so the same kind of value showed up in two shapes at once, "16:44:34" next to "4:45 PM".

Both now render the system locale's short time with the seconds field dropped, and the bubble takes its label from a model role instead of formatting.
2026-07-23 19:11:18 +02:00
osmaczko e6f2682e70 feat: take chat storage from the host-assigned session directory (#43)
* feat: take chat storage from the host-assigned session directory

The platform assigns every module instance its own persistence directory, so picking one here duplicated a decision the host had already made and left the init contract claiming an owner it did not have.

The standalone runner's `--user-dir` now selects the session directory the multi-instance dev and CI flows key off, so one host-level knob keeps two instances' state apart instead of a chat-specific environment variable.

* feat: stop choosing the delivery node's port

Running several instances on one host meant inventing a distinct delivery port for each and threading it through an environment variable, the docs, and both doc-test drivers, a coordination burden that bought nothing the transport cannot decide for itself.

chat_module's init no longer takes a port and its delivery node listens on ports it picks itself, so a session directory is the only thing that has to differ per instance.
2026-07-22 20:13:03 +02:00
osmaczko 7d504eeadf feat: rename the 1:1 flow to "DM" (#42)
The button that starts a one-to-one conversation read as "New chat" directly beneath the "Chat" pane title, so the name of the conversation type collided with the name of the application; calling that type a DM tells the two conversation types apart at a glance.

"conversation" stays the umbrella term covering both DMs and groups, and "Chat" stays the product name, so the pane header and the backend status strings keep their wording.
2026-07-21 13:03:08 +02:00
osmaczko 46e7f84049 feat: make message text selectable and copyable (#41)
Getting a message body out of the app meant retyping it: the bubble rendered its content as a plain Text, which has no selection support.

Selecting text moves focus off the composer, so Enter stops sending until the user clicks back into it. That is inherent to the selected item being the one that receives Ctrl+C, and is accepted rather than papered over with focus-restoring machinery that would fight the user mid-selection.
2026-07-21 11:12:09 +02:00
osmaczko b118c53ffd chore(deps): pin chat_module to the v0.2.0 release tag (#40)
chat_module v0.2.0 releases the commit this flake already pinned by raw rev, so the pin moves to the release tag; the locked rev is unchanged.
v0.2.0
2026-07-17 17:27:36 +02:00
osmaczko 51168b4d85 feat: UX polish across the chat UI (#36)
UX follow-ups across the chat UI that need no libchat change, as nine self-contained commits that each pass the QML checks on their own.

- Preserve New Group and New Conversation drafts across a close, and bound the group name (64) and description (280) with a live over-limit counter.
- Clearer sidebar actions ("New chat" / "New group", chat first), actionable empty states, and an unread badge recoloured to primary with dark ink and an accessible count.
- Order conversations by recency through a QSortFilterProxyModel, and show a relative activity date ("14:03", "Yesterday", or a short date) supplied by the model.
- Fix the thread header at 48px so the three pane headers align, and reveal a truncated subtitle in a hover tooltip.
- Add a group Details dialog (full description, member count, copyable conversation id) reachable from the thread header.
- Group consecutive messages and separate threads by day, from roles the message model derives from the previous message.
- Replace the single-line composer with a multi-line editor that grows then scrolls; Enter sends, Shift+Enter inserts a newline.
- Move member-add to a dialog with copy feedback, and retire the now-unused SubmitRow.
- Show a one-line preview of the latest message in each conversation row, capped at 160 characters to match the module.

Pins chat_module to the merged logos-chat-module #49 so a rehydrate reads back each conversation's preview.
2026-07-17 09:18:54 +02:00
osmaczko 7169bdd2a0 feat: create groups with a name and description (#35)
Creating a group opened an unnamed conversation labelled "Group <short-id>". A new dialog now collects a required group name and an optional description: the shared name becomes every member's display name for the conversation, and the description shows under the title in the message thread header. Metadata is set once at creation, so a joiner reads the same name and description the creator set.

Display name precedence is the local nickname, then the group's shared name, then the "Group <short-id>" fallback. The chat_module pin moves to the commit that adds the name and description to create_group_conversation, the Conversation record, and the conversation_created event; the backend threads them through the conversation model and exposes the current conversation's description as a property the thread header binds.
2026-07-17 00:02:42 +02:00
osmaczko bb8aac041e feat: pending indicator, explainer, and event-driven roster for member-add (#33)
Adding a member gave no feedback: the roster only showed the peer ~a commit later, and only via a manual refresh button or a message from them. The status bar was the sole hint the invite was in flight.

Show the invite immediately and let the module tell us when it lands.

- A just-invited member appears at once as a busy row (spinner, dimmed, tooltip "waiting for commit"), tracked in a per-conversation pending set. A roster refresh that finds the member in the committed roster drops the pending marker; the set is cleared on conversation switch.
- The roster now auto-refreshes from the module's members_changed event (surfaced from libchat), so a remote join updates the list with no user action. Bump the chat_module pin to the rev that emits it.
- Remove the members refresh button and its signal; the event replaces manual refresh.
- First time a user adds a member, an explainer dialog describes the commit delay, with a "Don't show this again" checkbox persisted via QtCore Settings.
2026-07-16 10:42:11 +02:00
osmaczko c0f8e020a0 refactor(qml): Logos design system + ChatUi module (#34)
* refactor: rebuild the chat view as a design-system ChatUi module

Reworks the chat UI from two large hand-themed QML files into a pure-QML ChatUi component module on the platform design system. ChatView.qml drops from ~825 lines to thin composition; everything below it is standalone-instantiable and Theme-driven.

- Theme: moves onto Logos.Theme and Logos.Controls, dropping the duplicated dark palette and the inline colour literals.
- Structure: ChatStore is the sole reader of the injected logos context; panes, delegates and leaf components take their data and services through declared properties, so each instantiates on its own with mock data.
- Behaviour: i18n marking (qsTr, %1 args, Locale.ShortFormat times, disambiguation comments), Accessible roles, keyboard navigation on the conversation and member lists, per-conversation composer drafts, and an overlay-layer toast.
- Hardening: plain-text rendering on all peer- and backend-bound text as markup-injection defence, plus guarded dialog focus and close policy.
- Messages: the model is ordered newest-first in C++ and the thread uses ListView.BottomToTop, so the newest row pins to the visual bottom natively and all imperative scroll management is gone; switching conversations replaces the thread in a single model reset rather than clear-then-repopulate, so the view never flashes through an empty state.
- Clipboard: addresses copy through a small standalone ClipboardProxy, used directly by the members pane and the address dialog, since QML exposes no native clipboard type.
- doctests: the exchange and group inspector drivers and the walkthrough specs are updated to the new component object names and UI text (Chat and Members headers, New/Send/Copy address buttons).

C++ backend strings and the .ts/.qm translation pipeline are out of scope.

* test+ci: qml component tests, storybook, and qmllint CI

Adds a Qt Quick Test that instantiates every ChatUi component standalone and checks the key behaviours, a storybook harness for visual inspection, and a qml-checks workflow that runs qmllint and the tests.

The CHAT_UI_QML_DEVTOOLS CMake option registers the pure-QML module for qmllint and qmltypes generation; it is off by default and not shipped, so the packaged .lgx stays byte-identical.

* docs: update the module structure and UI labels for the ChatUi refactor

The QML frontend is no longer a single ChatView.qml but a pure-QML ChatUi component module, so the module-structure tree reflects the new layout.

The refactor renamed the conversation-header buttons to New and Group, the member invite to Add, and made the roster reload an icon button; the run docs are corrected from the old + new / + group / + / roster-refresh labels.

* docs: refresh the exchange screenshots for the restyled UI

Regenerated by the two-instance-exchange run against this branch, so the walkthrough images show the design-system UI (Chat header, New/Group buttons, Send composer, in-bubble timestamps) rather than the old hand-themed look.
2026-07-15 08:16:41 +02:00
osmaczko 2732086653 feat: group conversations UI (#31)
* feat: group conversations UI

The UI surfaced only 1:1 conversations, but chat_module now exposes GroupV2
groups, so the UI needs to create them, display their roster, and grow them.

- ChatBackend gains create_group_conversation / add_group_member and exposes
  the current conversation's group view state (currentIsGroup,
  currentDisplayName, memberCount) as replicated backend properties: across
  the QtRO boundary a model replica carries roles and data() but not the
  source model's custom Q_INVOKABLE methods or a reliable rowCount(), so that
  whole-model state is derived on the source side and pushed as properties.
  refreshMembers reads the roster as [GroupMember] records.
- MemberListModel drives the members panel; a member with no confirmed
  account renders as "unknown_account".
- ConversationListModel marks group rows; ChatView shows the members panel
  and per-message sender labels only for groups; MembersPane hosts the roster
  and the add-member field.
- Pin chat_module to the merged GroupV2 commit on chat-module master (#43): its
  GroupV2 contract (create_group_conversation, add_group_member,
  list_group_members, the conversation kind and message sender fields) isn't in
  a released tag yet, so pin the exact commit and re-pin as chat_module advances.

* test: add a three-party group-chat doc-test and CI gate

Exercise the group UI end to end: three headless app instances form a group,
grow it member by member, and render the roster, captured as a screenshot.

- doctests/chat-ui-group.test.yaml plus doctests/group/ drive three instances
  on ports distinct from the exchange spec, so both specs can run in one job
  without their module hosts colliding; nix run .#group launches the
  screenshot app.
- doctests.yml runs the group spec alongside exchange; group-chat.yml is a
  dedicated Ubuntu gate that runs the three-party driver from the checkout.

* docs: document running multiple instances on one machine

Running side-by-side instances was only covered in the linked
two-instance-exchange doc. Add it to the README's How to Run directly: the
per-instance env vars (CHAT_MODULE_INSTANCE_PATH, CHAT_MODULE_DELIVERY_PORT, and
QML_INSPECTOR_PORT when driving an instance via the inspector), a copy-paste
two-window example and how to scale to more, with the exchange/group drivers
linked for the full flow.

* docs: correct delivery-module version in README

The Dependencies and Related Repositories tables listed the delivery-module
runtime pin as v0.1.2; the flake pins v0.1.3. Match them.
2026-07-10 11:17:33 +02:00
osmaczko 8311ce8844 feat: adapt to chat_module's account-addressed DirectV1 API (#30)
* feat: adapt to chat_module's account-addressed DirectV1 API

chat_module (pinned at 5c79789 on master) replaces intro bundles with
installation addresses and turns persistence off: create_intro_bundle()
is gone in favour of get_address() -> tstr,
create_conversation(peer_address) sends only the cryptographic invite
(the first message follows via send_message once the peer has joined),
and chats are ephemeral, so nothing survives an app restart.

- pin the chat_module flake input at 5c79789
- ChatBackend/.rep/QML: requestMyBundle/bundleReady and the bundle
  dialogs become requestMyAddress/addressReady and address dialogs; the
  new-conversation dialog takes only the peer address (the first
  message is typed in the thread once the conversation opens)
- run-exchange.mjs: share the address, open the conversation with it,
  and gate Bob's first message on Alice having joined, mirroring
  chat-module's own two-instance doc-test ordering
- #exchange app: ephemerality invalidates the relaunch-from-history
  display design, so run-exchange.sh gains KEEP_INSTANCES and
  run-exchange-show.sh keeps both finished instances alive, exposing
  the capture port only after the round-trip as a TCP proxy
  (port-proxy.mjs) onto Alice's live inspector
- doctests, workflows, README, docs: bundle flow rewritten as the
  address flow; docs/images/exchange screenshots are stale until
  regenerated by the two-instance-exchange job's artifact

* fix: elide the status-bar ID so long installation names fit

The new chat_module reports a long hex installation name; rendered
unconstrained it overflows the status-bar row and the three status
texts draw on top of each other (visible in the regenerated exchange
screenshots). Cap the ID text's width and elide it in the middle.

* docs: refresh the exchange screenshots for the address flow

Captured by the two-instance-exchange CI job on this branch: the
address dialog replaces the intro-bundle dialog and the status bar
shows the elided installation id.

* test: dump instance logs on any failed exchange run

The exchange harness surfaced the app logs only when an inspector port
never bound. A run that reached both inspectors but timed out waiting for
Online, or never received the message, exited with no diagnostics. Move
the dump into cleanup so every failed run shows each instance's
boot/runtime output.

* ci: fix the exchange doc-test (ubuntu-only round-trip, buildable app)

The two-party exchange doc-test needs live P2P networking between two
nodes that GitHub's macOS runners can't provide, so it failed on macOS
while passing on ubuntu. It is already gated on ubuntu by
two-instance-exchange.yml, so run it on ubuntu only; macOS keeps the
single-instance chat-ui spec.

Also expose the exchange runner as packages.<sys>.exchange so the
doc-test runner's `nix build .#exchange` pre-build resolves, warming the
store and dropping the misleading "does not provide attribute" log line.
2026-07-06 17:41:46 +02:00
e859c7253b chore(deps): bump chat_module and delivery module pins (#29)
* chore(deps): bump chat_module and delivery module pins

- logos-delivery-module: raw commit 2577383 -> v0.1.3 release tag
  (carries the zerokit/RLN nix build fix, delivery-module #49)
- chat_module: a58b5ff -> 4fe912a, current master carrying the same
  delivery v0.1.3 pin (chat-module #41); re-pin to the v0.1.2 tag
  once that release is published

Both delivery pins (top-level and nested under chat_module) now
resolve to the same rev, keeping the lockstep intact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(deps): re-pin chat_module to the v0.1.2 release tag

v0.1.2 is published (and repointed to include the metadata version
bump, chat-module #42), so the interim master-rev pin can go.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: bump module version to 0.1.2

A chat_ui v0.1.2 release follows once this PR merges.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Susanna Bekker <susanna.bekker@gmail.com>
v0.1.2
2026-07-02 14:09:33 +01:00
osmaczko 99c8c9862d feat/adapt to chat_module migration to Rust SDK (#25)
* feat: consume chat_module over LIDL and adopt the universal typed-backend

Rework the chat UI app to talk to chat_module through the generated LIDL client,
and adopt logos-module-builder's universal typed-backend interface in place of
the hand-written plugin/interface glue.

ChatBackend now derives from the generated QtRO source and LogosUiPluginContext:
the builder generates the *Plugin/*Interface glue from ChatBackend.rep +
metadata.json, so src/chat_ui_plugin.{h,cpp}, src/chat_ui_interface.h, and the
unused ChatConfig.h are removed. Module calls go through the typed
modules().chat_module client (init, status, conversation and message calls), and
events are subscribed through the same client. Backend setup moves into
onContextReady() -- the moment the framework has wired modules() -- replacing the
QTimer::singleShot deferral.

Also: take the initial conversation snapshot before seeding delivery state so the
first render is consistent; defer module refetches out of event callbacks to
avoid a QtRO re-entrancy stall; clamp the error toast and derive the selection
tint from the theme; default the delivery preset to logos.test.

* build: wire the universal QML module, pin deps, bump to 0.1.1

metadata.json declares interface: universal with the codegen rep/backend
overrides, so mkLogosQmlModule generates the plugin glue from ChatBackend.rep;
CMakeLists.txt drops the removed glue sources. Pin logos-delivery-module to the
zerokit-fix commit and chat_module to an explicit rev, and set the version to
0.1.1.

* test: add the two-instance message-exchange doc-test and CI

Add an executable doc-test that drives two app instances through a full message
exchange (Alice publishes an intro bundle, Bob sends, Alice receives and replies,
Bob sees the round-trip), capturing a screenshot at each step. The exchange is
scripted in doctests/exchange/ (a CI driver and a display variant) and declared
in the chat-ui doc-test specs. Two workflows run it: doctests.yml renders the
screenshots, and two-instance-exchange.yml runs the Linux two-instance
round-trip; macOS exercises the same exchange spec through doctests.yml.

* docs: document the two-instance exchange and drop the stale spec

Add docs/two-instance-exchange.md walking through the message-exchange doc-test
with the captured screenshots, update README for the universal interface and the
one-time GitHub Pages setup, and remove the outdated docs/spec.md.

* docs: note resolveInstancePath returns the module's persistence dir

It's passed to chat_module via init() for identity.db + history.json; the UI
only picks the location and never reads it.

* build: re-pin chat_module and refresh the flake to builder lockstep

chat_module advances to the rebased rev; logos-module-builder moves to the
thread-safe inter-module-calls SDK, matching the builder chat_module consumes.

* build: re-pin chat_module to the merged master rev

feat/lp-protocol-migration merged to master as a58b5ff (#32); tree-identical to the prior 5380e9e pin, so this is a metadata-only bump.
2026-06-25 21:51:25 +02:00
Khushboo-dev-cpp 7f51db696c Merge pull request #27 from logos-co/chore/bump-nix-bundle-lgx
chore: bump nix-bundle-lgx
2026-06-22 21:11:16 +02:00
Khushboo Mehta a648bddf13 chore: bump nix-bundle-lgx
Transitive override of logos-module-builder/nix-bundle-lgx so the LGX
bundler copies display_name from metadata.json into the embedded
manifest.json
2026-06-22 17:26:42 +00:00
Khushboo-dev-cpp e0895d0097 Merge pull request #26 from logos-co/chore/add-display-name
feat: add display_name field for module
2026-06-19 17:05:03 +02:00
Khushboo Mehta 2cb478f80d feat: add display_name field for module 2026-06-19 13:56:30 +00:00
Khushboo-dev-cpp 46d1a52ed3 Merge pull request #18 from logos-co/feat/portToNewUiUseModuleBuilder
feat: use new ui module type qml + c++ backend and the new logos-module-builder
v0.1.0
2026-04-20 19:25:02 +02:00
Khushboo Mehta 3bd50f2297 feat: use new ui module type qml + c++ backend and the new logos-module-builder 2026-04-20 19:24:20 +02:00
Igor Sirotin 463088afb0 chore: rename project (#17) 2026-03-20 23:12:54 +00:00