@ai-matrx/messaging 0.3.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.cts CHANGED
@@ -17,10 +17,22 @@ import { RealtimeClientLike, RealtimeManager } from '@ai-matrx/realtime';
17
17
  * is the JSON boundary — `metadata` and `action_data` are host/DB-generated
18
18
  * shapes this package does not own (the data 0.2.1 `Json = unknown` lesson).
19
19
  */
20
- /** Nominal id types. A conversation id can never be passed where a user id goes. */
21
- declare const brand: unique symbol;
20
+ /**
21
+ * Nominal id types. A conversation id can never be passed where a user id goes.
22
+ *
23
+ * 🚨 THE MARKER IS A NAMED PROPERTY, NOT A `unique symbol`. This package ships
24
+ * two entries built as two separate bundles, so a `declare const brand: unique
25
+ * symbol` is DECLARED TWICE — and two unique symbols are two different types.
26
+ * `ConversationId` from `@ai-matrx/messaging` then does not match
27
+ * `ConversationId` from `@ai-matrx/messaging/react`, which makes the two
28
+ * entries unusable together: the first consumer hit exactly that, calling
29
+ * `asConversationId` from the core and passing it to a hook. A structural
30
+ * marker is identical in both declarations, so the brands unify — and it still
31
+ * cannot be produced by accident, which is all nominal typing needs to do.
32
+ * (The marker is types-only; nothing writes it at runtime.)
33
+ */
22
34
  type Brand<T, B extends string> = T & {
23
- readonly [brand]: B;
35
+ readonly __mxBrand: B;
24
36
  };
25
37
  type ConversationId = Brand<string, "ConversationId">;
26
38
  type MessageId = Brand<string, "MessageId">;
@@ -828,6 +840,17 @@ interface MessageActionRenderer<TPayload = unknown> {
828
840
  type ReferenceRenderer = ComponentType<{
829
841
  reference: MatrxReference;
830
842
  }>;
843
+ /**
844
+ * A host's renderer for a raw ```matrx fence — the body between the backticks.
845
+ *
846
+ * This package understands one fence dialect: its own. A platform's fences are
847
+ * its platform's business (Matrx's are `__kind` directive shells resolved
848
+ * through a kind registry), and only the app can draw them. Give us this and
849
+ * EVERY fence in a message goes to you, parsed or not.
850
+ */
851
+ type FenceRenderer = ComponentType<{
852
+ body: string;
853
+ }>;
831
854
  /**
832
855
  * App chrome wrapped around ONE message bubble or ONE conversation row.
833
856
  *
@@ -858,6 +881,7 @@ interface MessagingHost {
858
881
  /** Host surfaces for action kinds whose answer is a card, not a chip. */
859
882
  readonly actionRenderers: ReadonlyMap<string, MessageActionRenderer>;
860
883
  readonly renderReference: ReferenceRenderer | null;
884
+ readonly renderFence: FenceRenderer | null;
861
885
  readonly wrapMessage: ComponentType<MessageWrapperProps> | null;
862
886
  readonly wrapConversationRow: ComponentType<ConversationRowWrapperProps> | null;
863
887
  }
@@ -889,6 +913,8 @@ interface MessagingProviderProps {
889
913
  onOpenReference?: ((reference: MatrxReference) => void) | undefined;
890
914
  /** Draw references with the app's own renderer instead of the package card. */
891
915
  renderReference?: ReferenceRenderer | undefined;
916
+ /** Draw ```matrx fences with the app's own renderer — every fence, parsed or not. */
917
+ renderFence?: FenceRenderer | undefined;
892
918
  /** App chrome (a right-click menu, a drop target) around each message bubble. */
893
919
  wrapMessage?: ComponentType<MessageWrapperProps> | undefined;
894
920
  /** App chrome around each conversation row. */
@@ -1077,11 +1103,6 @@ declare function Avatar(props: {
1077
1103
  declare function DeliveryTick(props: {
1078
1104
  state: DeliveryState;
1079
1105
  }): React.ReactElement | null;
1080
- /**
1081
- * A reference card. NO DEAD ENDS: when the host wired `onOpenReference` it is a
1082
- * button that opens; when it did not, it renders as a labeled, non-interactive
1083
- * card with a title explaining why — never a button that does nothing.
1084
- */
1085
1106
  declare function ReferenceCard(props: {
1086
1107
  reference: MatrxReference;
1087
1108
  onOpen?: ((reference: MatrxReference) => void) | null;
@@ -1289,13 +1310,6 @@ declare function formatConversationTime(isoString: string | null, now?: number,
1289
1310
  declare function formatMessageTime(isoString: string, locale?: string): string;
1290
1311
  /** The separator between day groups in a thread. */
1291
1312
  declare function formatDateSeparator(isoString: string, now?: number, locale?: string): string;
1292
- declare function getInitials(name: string): string;
1293
- /**
1294
- * A stable palette index for an avatar with no image. Deterministic on the id,
1295
- * so the same person is the same color on every device and every reload — a
1296
- * random color per render is a surprisingly loud bug.
1297
- */
1298
- declare function avatarPaletteIndex(seed: string, buckets?: number): number;
1299
1313
  /**
1300
1314
  * Group consecutive messages by the same sender within a window, the way every
1301
1315
  * good chat UI does — one avatar and one name per burst.
@@ -1363,6 +1377,20 @@ type TextSegment = {
1363
1377
  } | {
1364
1378
  readonly type: "reference";
1365
1379
  readonly reference: MatrxReference;
1380
+ }
1381
+ /**
1382
+ * A ```matrx fence this package could not resolve into references.
1383
+ *
1384
+ * It is NOT dropped. Platforms carry richer fence dialects than this
1385
+ * package's own array shape — Matrx's is a `__kind` directive shell whose
1386
+ * items are typed per noun, resolvable only by the app's kind registry — and
1387
+ * a fence silently deleted on render is a message that lost a paragraph
1388
+ * between the sender and the reader. The host draws it (`renderFence`), or
1389
+ * the package draws an honest inert card. Never a code block of JSON.
1390
+ */
1391
+ | {
1392
+ readonly type: "fence";
1393
+ readonly body: string;
1366
1394
  };
1367
1395
  /** Every reference a message carries, from both transports, de-duplicated. */
1368
1396
  declare function extractReferences(content: string, structured?: readonly MatrxReference[]): readonly MatrxReference[];
@@ -1380,4 +1408,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1380
1408
  /** Serialize picked references into a fence the platform's other readers accept. */
1381
1409
  declare function composeFence(references: readonly MatrxReference[]): string;
1382
1410
 
1383
- export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, avatarPaletteIndex, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, getInitials, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
1411
+ export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
package/dist/react.d.ts CHANGED
@@ -17,10 +17,22 @@ import { RealtimeClientLike, RealtimeManager } from '@ai-matrx/realtime';
17
17
  * is the JSON boundary — `metadata` and `action_data` are host/DB-generated
18
18
  * shapes this package does not own (the data 0.2.1 `Json = unknown` lesson).
19
19
  */
20
- /** Nominal id types. A conversation id can never be passed where a user id goes. */
21
- declare const brand: unique symbol;
20
+ /**
21
+ * Nominal id types. A conversation id can never be passed where a user id goes.
22
+ *
23
+ * 🚨 THE MARKER IS A NAMED PROPERTY, NOT A `unique symbol`. This package ships
24
+ * two entries built as two separate bundles, so a `declare const brand: unique
25
+ * symbol` is DECLARED TWICE — and two unique symbols are two different types.
26
+ * `ConversationId` from `@ai-matrx/messaging` then does not match
27
+ * `ConversationId` from `@ai-matrx/messaging/react`, which makes the two
28
+ * entries unusable together: the first consumer hit exactly that, calling
29
+ * `asConversationId` from the core and passing it to a hook. A structural
30
+ * marker is identical in both declarations, so the brands unify — and it still
31
+ * cannot be produced by accident, which is all nominal typing needs to do.
32
+ * (The marker is types-only; nothing writes it at runtime.)
33
+ */
22
34
  type Brand<T, B extends string> = T & {
23
- readonly [brand]: B;
35
+ readonly __mxBrand: B;
24
36
  };
25
37
  type ConversationId = Brand<string, "ConversationId">;
26
38
  type MessageId = Brand<string, "MessageId">;
@@ -828,6 +840,17 @@ interface MessageActionRenderer<TPayload = unknown> {
828
840
  type ReferenceRenderer = ComponentType<{
829
841
  reference: MatrxReference;
830
842
  }>;
843
+ /**
844
+ * A host's renderer for a raw ```matrx fence — the body between the backticks.
845
+ *
846
+ * This package understands one fence dialect: its own. A platform's fences are
847
+ * its platform's business (Matrx's are `__kind` directive shells resolved
848
+ * through a kind registry), and only the app can draw them. Give us this and
849
+ * EVERY fence in a message goes to you, parsed or not.
850
+ */
851
+ type FenceRenderer = ComponentType<{
852
+ body: string;
853
+ }>;
831
854
  /**
832
855
  * App chrome wrapped around ONE message bubble or ONE conversation row.
833
856
  *
@@ -858,6 +881,7 @@ interface MessagingHost {
858
881
  /** Host surfaces for action kinds whose answer is a card, not a chip. */
859
882
  readonly actionRenderers: ReadonlyMap<string, MessageActionRenderer>;
860
883
  readonly renderReference: ReferenceRenderer | null;
884
+ readonly renderFence: FenceRenderer | null;
861
885
  readonly wrapMessage: ComponentType<MessageWrapperProps> | null;
862
886
  readonly wrapConversationRow: ComponentType<ConversationRowWrapperProps> | null;
863
887
  }
@@ -889,6 +913,8 @@ interface MessagingProviderProps {
889
913
  onOpenReference?: ((reference: MatrxReference) => void) | undefined;
890
914
  /** Draw references with the app's own renderer instead of the package card. */
891
915
  renderReference?: ReferenceRenderer | undefined;
916
+ /** Draw ```matrx fences with the app's own renderer — every fence, parsed or not. */
917
+ renderFence?: FenceRenderer | undefined;
892
918
  /** App chrome (a right-click menu, a drop target) around each message bubble. */
893
919
  wrapMessage?: ComponentType<MessageWrapperProps> | undefined;
894
920
  /** App chrome around each conversation row. */
@@ -1077,11 +1103,6 @@ declare function Avatar(props: {
1077
1103
  declare function DeliveryTick(props: {
1078
1104
  state: DeliveryState;
1079
1105
  }): React.ReactElement | null;
1080
- /**
1081
- * A reference card. NO DEAD ENDS: when the host wired `onOpenReference` it is a
1082
- * button that opens; when it did not, it renders as a labeled, non-interactive
1083
- * card with a title explaining why — never a button that does nothing.
1084
- */
1085
1106
  declare function ReferenceCard(props: {
1086
1107
  reference: MatrxReference;
1087
1108
  onOpen?: ((reference: MatrxReference) => void) | null;
@@ -1289,13 +1310,6 @@ declare function formatConversationTime(isoString: string | null, now?: number,
1289
1310
  declare function formatMessageTime(isoString: string, locale?: string): string;
1290
1311
  /** The separator between day groups in a thread. */
1291
1312
  declare function formatDateSeparator(isoString: string, now?: number, locale?: string): string;
1292
- declare function getInitials(name: string): string;
1293
- /**
1294
- * A stable palette index for an avatar with no image. Deterministic on the id,
1295
- * so the same person is the same color on every device and every reload — a
1296
- * random color per render is a surprisingly loud bug.
1297
- */
1298
- declare function avatarPaletteIndex(seed: string, buckets?: number): number;
1299
1313
  /**
1300
1314
  * Group consecutive messages by the same sender within a window, the way every
1301
1315
  * good chat UI does — one avatar and one name per burst.
@@ -1363,6 +1377,20 @@ type TextSegment = {
1363
1377
  } | {
1364
1378
  readonly type: "reference";
1365
1379
  readonly reference: MatrxReference;
1380
+ }
1381
+ /**
1382
+ * A ```matrx fence this package could not resolve into references.
1383
+ *
1384
+ * It is NOT dropped. Platforms carry richer fence dialects than this
1385
+ * package's own array shape — Matrx's is a `__kind` directive shell whose
1386
+ * items are typed per noun, resolvable only by the app's kind registry — and
1387
+ * a fence silently deleted on render is a message that lost a paragraph
1388
+ * between the sender and the reader. The host draws it (`renderFence`), or
1389
+ * the package draws an honest inert card. Never a code block of JSON.
1390
+ */
1391
+ | {
1392
+ readonly type: "fence";
1393
+ readonly body: string;
1366
1394
  };
1367
1395
  /** Every reference a message carries, from both transports, de-duplicated. */
1368
1396
  declare function extractReferences(content: string, structured?: readonly MatrxReference[]): readonly MatrxReference[];
@@ -1380,4 +1408,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1380
1408
  /** Serialize picked references into a fence the platform's other readers accept. */
1381
1409
  declare function composeFence(references: readonly MatrxReference[]): string;
1382
1410
 
1383
- export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, avatarPaletteIndex, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, getInitials, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
1411
+ export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
package/dist/react.js CHANGED
@@ -222,21 +222,32 @@ function splitText(content) {
222
222
  if (start > cursor) {
223
223
  segments.push({ type: "text", value: content.slice(cursor, start) });
224
224
  }
225
- parseFenceBody(match[1] ?? "").forEach((reference) => {
226
- segments.push({ type: "reference", reference });
227
- });
225
+ const body = match[1] ?? "";
226
+ const references = parseFenceBody(body);
227
+ if (references.length === 0) {
228
+ segments.push({ type: "fence", body });
229
+ } else {
230
+ references.forEach((reference) => {
231
+ segments.push({ type: "reference", reference });
232
+ });
233
+ }
228
234
  cursor = start + match[0].length;
229
235
  }
230
236
  if (cursor < content.length) {
231
237
  segments.push({ type: "text", value: content.slice(cursor) });
232
238
  }
233
239
  return segments.filter(
234
- (segment) => segment.type === "reference" || segment.value.trim().length > 0
240
+ (segment) => segment.type !== "text" || segment.value.trim().length > 0
235
241
  );
236
242
  }
237
243
  function summarizeText(content, maxLength = 140) {
238
244
  const parts = splitText(content).map(
239
- (segment) => segment.type === "text" ? segment.value : segment.reference.label
245
+ (segment) => segment.type === "text" ? segment.value : segment.type === "reference" ? segment.reference.label : (
246
+ // A fence we cannot read still SAYS something. Collapsing it to
247
+ // nothing is how a reference-only message becomes an inbox row that
248
+ // reads "No messages yet" — a screen telling a lie.
249
+ "Reference"
250
+ )
240
251
  );
241
252
  const flattened = parts.join(" ").replace(/\s+/g, " ").trim();
242
253
  if (flattened.length <= maxLength) return flattened;
@@ -1794,6 +1805,7 @@ function MessagingRuntime(props) {
1794
1805
  return map;
1795
1806
  }, [renderers]);
1796
1807
  const renderReference = props.renderReference ?? null;
1808
+ const renderFence = props.renderFence ?? null;
1797
1809
  const wrapMessage = props.wrapMessage ?? null;
1798
1810
  const wrapConversationRow = props.wrapConversationRow ?? null;
1799
1811
  const host = useMemo(() => {
@@ -1806,10 +1818,20 @@ function MessagingRuntime(props) {
1806
1818
  openReference: referenceRef.current ?? null,
1807
1819
  actionRenderers: rendererMap,
1808
1820
  renderReference,
1821
+ renderFence,
1809
1822
  wrapMessage,
1810
1823
  wrapConversationRow
1811
1824
  };
1812
- }, [engine, actionRegistry, ai, rendererMap, renderReference, wrapMessage, wrapConversationRow]);
1825
+ }, [
1826
+ engine,
1827
+ actionRegistry,
1828
+ ai,
1829
+ rendererMap,
1830
+ renderReference,
1831
+ renderFence,
1832
+ wrapMessage,
1833
+ wrapConversationRow
1834
+ ]);
1813
1835
  const MessagingContext = messagingContext();
1814
1836
  return /* @__PURE__ */ jsx(MessagingContext.Provider, { value: host, children });
1815
1837
  }
@@ -1885,20 +1907,6 @@ function formatDateSeparator(isoString, now = Date.now(), locale) {
1885
1907
  day: "numeric"
1886
1908
  });
1887
1909
  }
1888
- function getInitials(name) {
1889
- const parts = name.trim().split(/\s+/).filter(Boolean);
1890
- if (parts.length === 0) return "?";
1891
- const first = parts[0]?.[0] ?? "";
1892
- const last = parts.length > 1 ? parts.at(-1)?.[0] ?? "" : "";
1893
- return `${first}${last}`.toUpperCase() || "?";
1894
- }
1895
- function avatarPaletteIndex(seed, buckets = 8) {
1896
- let hash = 0;
1897
- for (let index = 0; index < seed.length; index += 1) {
1898
- hash = hash * 31 + seed.charCodeAt(index) | 0;
1899
- }
1900
- return Math.abs(hash) % buckets;
1901
- }
1902
1910
  function groupMessages(messages, args = {}) {
1903
1911
  const windowMs = args.windowMs ?? 5 * MINUTE;
1904
1912
  const now = args.now ?? Date.now();
@@ -2267,6 +2275,9 @@ function resolveActor(message, sender) {
2267
2275
  };
2268
2276
  }
2269
2277
 
2278
+ // src/react/parts.tsx
2279
+ import { avatarPaletteIndex, getInitials } from "@ai-matrx/kit/format";
2280
+
2270
2281
  // src/react/icons.tsx
2271
2282
  import { jsx as jsx2 } from "react/jsx-runtime";
2272
2283
  function Icon(props) {
@@ -2400,6 +2411,20 @@ function DeliveryTick(props) {
2400
2411
  return null;
2401
2412
  }
2402
2413
  }
2414
+ function UnreadableReference() {
2415
+ return /* @__PURE__ */ jsxs(
2416
+ "span",
2417
+ {
2418
+ className: "mx-msg__reference mx-msg__reference--inert",
2419
+ title: "This message names something in a reference format this app has not wired. Pass renderFence to <MessagingProvider> to render it.",
2420
+ children: [
2421
+ /* @__PURE__ */ jsx3(LinkIcon, {}),
2422
+ /* @__PURE__ */ jsx3("span", { className: "mx-msg__reference-type", children: "reference" }),
2423
+ "Reference"
2424
+ ]
2425
+ }
2426
+ );
2427
+ }
2403
2428
  function ReferenceCard(props) {
2404
2429
  const { reference, onOpen } = props;
2405
2430
  const href = reference.href;
@@ -2764,6 +2789,7 @@ function MessageBubble(props) {
2764
2789
  const { message, isMine } = props;
2765
2790
  const host = useMessagingHost();
2766
2791
  const HostReference = host?.renderReference ?? null;
2792
+ const HostFence = host?.renderFence ?? null;
2767
2793
  const MessageChrome = host?.wrapMessage ?? null;
2768
2794
  if (message.deletedAt !== null) {
2769
2795
  return /* @__PURE__ */ jsx4("div", { className: "mx-msg__bubble mx-msg__bubble--deleted", children: "Message deleted" });
@@ -2778,7 +2804,7 @@ function MessageBubble(props) {
2778
2804
  const bubble = /* @__PURE__ */ jsxs2(Fragment, { children: [
2779
2805
  /* @__PURE__ */ jsxs2("div", { className: classes, children: [
2780
2806
  splitText(message.content).map(
2781
- (segment, index) => segment.type === "text" ? /* @__PURE__ */ jsx4("span", { children: segment.value }, index) : HostReference !== null ? /* @__PURE__ */ jsx4(
2807
+ (segment, index) => segment.type === "text" ? /* @__PURE__ */ jsx4("span", { children: segment.value }, index) : segment.type === "fence" ? HostFence !== null ? /* @__PURE__ */ jsx4(HostFence, { body: segment.body }, `fence:${index}`) : /* @__PURE__ */ jsx4(UnreadableReference, {}, `fence:${index}`) : HostReference !== null ? /* @__PURE__ */ jsx4(
2782
2808
  HostReference,
2783
2809
  {
2784
2810
  reference: segment.reference
@@ -3030,7 +3056,6 @@ export {
3030
3056
  asMessageId,
3031
3057
  asOrganizationId,
3032
3058
  asUserId,
3033
- avatarPaletteIndex,
3034
3059
  composeFence,
3035
3060
  conversationTopic,
3036
3061
  createActionRegistry,
@@ -3048,7 +3073,6 @@ export {
3048
3073
  formatLastSeen,
3049
3074
  formatMessageTime,
3050
3075
  formatTypists,
3051
- getInitials,
3052
3076
  groupMessages,
3053
3077
  inboxTopic,
3054
3078
  invalidResponse,