@shadowob/shared 1.1.0 → 1.1.3

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.
@@ -1,3 +1,5 @@
1
+ export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, M as MentionSuggestion, c as MentionSuggestionTrigger, d as Message, e as MessageMention, f as MessageMentionKind, g as MessageMentionRange, h as MessageMetadata, N as Notification, i as NotificationType, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, T as Thread, U as UpdateMessageRequest } from '../message.types-lG4qBSus.cjs';
2
+
1
3
  type AgentStatus = 'running' | 'stopped' | 'error';
2
4
  type AgentKernelType = 'claude-code' | 'cursor' | 'mcp-server' | 'custom';
3
5
  type AgentCapability = 'chat' | 'code-gen' | 'code-review' | 'research' | 'tools' | 'file-access';
@@ -72,7 +74,7 @@ interface Friendship {
72
74
  createdAt: string;
73
75
  updatedAt: string;
74
76
  }
75
- type FriendSource = 'friend' | 'owned_claw' | 'rented_claw';
77
+ type FriendSource = 'friend' | 'owned_agent' | 'rented_agent';
76
78
  interface FriendEntry {
77
79
  friendshipId: string;
78
80
  /** Where this friend entry comes from */
@@ -88,122 +90,6 @@ interface FriendEntry {
88
90
  createdAt: string;
89
91
  }
90
92
 
91
- interface Message {
92
- id: string;
93
- content: string;
94
- channelId: string;
95
- authorId: string;
96
- threadId: string | null;
97
- replyToId: string | null;
98
- isEdited: boolean;
99
- isPinned: boolean;
100
- createdAt: string;
101
- updatedAt: string;
102
- author?: {
103
- id: string;
104
- username: string;
105
- displayName: string;
106
- avatarUrl: string | null;
107
- isBot: boolean;
108
- };
109
- attachments?: Attachment[];
110
- reactions?: ReactionGroup[];
111
- }
112
- interface Attachment {
113
- id: string;
114
- messageId: string;
115
- filename: string;
116
- url: string;
117
- contentType: string;
118
- size: number;
119
- width: number | null;
120
- height: number | null;
121
- createdAt: string;
122
- }
123
- interface ReactionGroup {
124
- emoji: string;
125
- count: number;
126
- userIds: string[];
127
- }
128
- interface Thread {
129
- id: string;
130
- name: string;
131
- channelId: string;
132
- parentMessageId: string;
133
- creatorId: string;
134
- isArchived: boolean;
135
- createdAt: string;
136
- updatedAt: string;
137
- }
138
- interface SendMessageRequest {
139
- content: string;
140
- threadId?: string;
141
- replyToId?: string;
142
- }
143
- interface UpdateMessageRequest {
144
- content: string;
145
- }
146
- type NotificationType = 'mention' | 'reply' | 'dm' | 'system';
147
- interface Notification {
148
- id: string;
149
- userId: string;
150
- type: NotificationType;
151
- title: string;
152
- body: string | null;
153
- referenceId: string | null;
154
- referenceType: string | null;
155
- isRead: boolean;
156
- createdAt: string;
157
- }
158
- interface DmChannel {
159
- id: string;
160
- userAId: string;
161
- userBId: string;
162
- lastMessageAt: string | null;
163
- createdAt: string;
164
- otherUser?: {
165
- id: string;
166
- username: string;
167
- displayName: string;
168
- avatarUrl: string | null;
169
- status: string;
170
- };
171
- }
172
- /** DM message — mirrors channel Message but scoped to DM channels */
173
- interface DmMessage {
174
- id: string;
175
- content: string;
176
- dmChannelId: string;
177
- authorId: string;
178
- replyToId: string | null;
179
- isEdited: boolean;
180
- createdAt: string;
181
- updatedAt: string;
182
- author?: {
183
- id: string;
184
- username: string;
185
- displayName: string;
186
- avatarUrl: string | null;
187
- isBot: boolean;
188
- };
189
- attachments?: DmAttachment[];
190
- reactions?: ReactionGroup[];
191
- }
192
- interface DmAttachment {
193
- id: string;
194
- dmMessageId: string;
195
- filename: string;
196
- url: string;
197
- contentType: string;
198
- size: number;
199
- width: number | null;
200
- height: number | null;
201
- createdAt: string;
202
- }
203
- interface UpdateDmMessageRequest {
204
- content: string;
205
- }
206
-
207
93
  interface Server {
208
94
  id: string;
209
95
  name: string;
@@ -248,6 +134,7 @@ interface User {
248
134
  avatarUrl: string | null;
249
135
  status: UserStatus;
250
136
  isBot: boolean;
137
+ membership?: UserMembership;
251
138
  createdAt: string;
252
139
  updatedAt: string;
253
140
  }
@@ -265,14 +152,30 @@ interface LoginRequest {
265
152
  }
266
153
  interface RegisterRequest {
267
154
  email: string;
268
- username: string;
269
- displayName: string;
155
+ username?: string;
156
+ displayName?: string;
270
157
  password: string;
158
+ inviteCode?: string;
271
159
  }
272
160
  interface AuthResponse {
273
161
  user: User;
274
162
  accessToken: string;
275
163
  refreshToken: string;
276
164
  }
165
+ interface UserMembershipTier {
166
+ id: string;
167
+ level: number;
168
+ label: string;
169
+ capabilities: string[];
170
+ }
171
+ interface UserMembership {
172
+ status: string;
173
+ tier: UserMembershipTier;
174
+ level: number;
175
+ isMember: boolean;
176
+ memberSince?: string | null;
177
+ inviteCodeId?: string | null;
178
+ capabilities: string[];
179
+ }
277
180
 
278
- export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, Attachment, AuthResponse, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, DmAttachment, DmChannel, DmMessage, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, Message, Notification, NotificationType, ReactionGroup, RegisterRequest, SendMessageRequest, Server, Thread, UpdateChannelRequest, UpdateDmMessageRequest, UpdateMessageRequest, UpdateServerRequest, User, UserProfile, UserStatus };
181
+ export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, AuthResponse, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, RegisterRequest, Server, UpdateChannelRequest, UpdateServerRequest, User, UserMembership, UserMembershipTier, UserProfile, UserStatus };
@@ -1,3 +1,5 @@
1
+ export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, M as MentionSuggestion, c as MentionSuggestionTrigger, d as Message, e as MessageMention, f as MessageMentionKind, g as MessageMentionRange, h as MessageMetadata, N as Notification, i as NotificationType, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, T as Thread, U as UpdateMessageRequest } from '../message.types-lG4qBSus.js';
2
+
1
3
  type AgentStatus = 'running' | 'stopped' | 'error';
2
4
  type AgentKernelType = 'claude-code' | 'cursor' | 'mcp-server' | 'custom';
3
5
  type AgentCapability = 'chat' | 'code-gen' | 'code-review' | 'research' | 'tools' | 'file-access';
@@ -72,7 +74,7 @@ interface Friendship {
72
74
  createdAt: string;
73
75
  updatedAt: string;
74
76
  }
75
- type FriendSource = 'friend' | 'owned_claw' | 'rented_claw';
77
+ type FriendSource = 'friend' | 'owned_agent' | 'rented_agent';
76
78
  interface FriendEntry {
77
79
  friendshipId: string;
78
80
  /** Where this friend entry comes from */
@@ -88,122 +90,6 @@ interface FriendEntry {
88
90
  createdAt: string;
89
91
  }
90
92
 
91
- interface Message {
92
- id: string;
93
- content: string;
94
- channelId: string;
95
- authorId: string;
96
- threadId: string | null;
97
- replyToId: string | null;
98
- isEdited: boolean;
99
- isPinned: boolean;
100
- createdAt: string;
101
- updatedAt: string;
102
- author?: {
103
- id: string;
104
- username: string;
105
- displayName: string;
106
- avatarUrl: string | null;
107
- isBot: boolean;
108
- };
109
- attachments?: Attachment[];
110
- reactions?: ReactionGroup[];
111
- }
112
- interface Attachment {
113
- id: string;
114
- messageId: string;
115
- filename: string;
116
- url: string;
117
- contentType: string;
118
- size: number;
119
- width: number | null;
120
- height: number | null;
121
- createdAt: string;
122
- }
123
- interface ReactionGroup {
124
- emoji: string;
125
- count: number;
126
- userIds: string[];
127
- }
128
- interface Thread {
129
- id: string;
130
- name: string;
131
- channelId: string;
132
- parentMessageId: string;
133
- creatorId: string;
134
- isArchived: boolean;
135
- createdAt: string;
136
- updatedAt: string;
137
- }
138
- interface SendMessageRequest {
139
- content: string;
140
- threadId?: string;
141
- replyToId?: string;
142
- }
143
- interface UpdateMessageRequest {
144
- content: string;
145
- }
146
- type NotificationType = 'mention' | 'reply' | 'dm' | 'system';
147
- interface Notification {
148
- id: string;
149
- userId: string;
150
- type: NotificationType;
151
- title: string;
152
- body: string | null;
153
- referenceId: string | null;
154
- referenceType: string | null;
155
- isRead: boolean;
156
- createdAt: string;
157
- }
158
- interface DmChannel {
159
- id: string;
160
- userAId: string;
161
- userBId: string;
162
- lastMessageAt: string | null;
163
- createdAt: string;
164
- otherUser?: {
165
- id: string;
166
- username: string;
167
- displayName: string;
168
- avatarUrl: string | null;
169
- status: string;
170
- };
171
- }
172
- /** DM message — mirrors channel Message but scoped to DM channels */
173
- interface DmMessage {
174
- id: string;
175
- content: string;
176
- dmChannelId: string;
177
- authorId: string;
178
- replyToId: string | null;
179
- isEdited: boolean;
180
- createdAt: string;
181
- updatedAt: string;
182
- author?: {
183
- id: string;
184
- username: string;
185
- displayName: string;
186
- avatarUrl: string | null;
187
- isBot: boolean;
188
- };
189
- attachments?: DmAttachment[];
190
- reactions?: ReactionGroup[];
191
- }
192
- interface DmAttachment {
193
- id: string;
194
- dmMessageId: string;
195
- filename: string;
196
- url: string;
197
- contentType: string;
198
- size: number;
199
- width: number | null;
200
- height: number | null;
201
- createdAt: string;
202
- }
203
- interface UpdateDmMessageRequest {
204
- content: string;
205
- }
206
-
207
93
  interface Server {
208
94
  id: string;
209
95
  name: string;
@@ -248,6 +134,7 @@ interface User {
248
134
  avatarUrl: string | null;
249
135
  status: UserStatus;
250
136
  isBot: boolean;
137
+ membership?: UserMembership;
251
138
  createdAt: string;
252
139
  updatedAt: string;
253
140
  }
@@ -265,14 +152,30 @@ interface LoginRequest {
265
152
  }
266
153
  interface RegisterRequest {
267
154
  email: string;
268
- username: string;
269
- displayName: string;
155
+ username?: string;
156
+ displayName?: string;
270
157
  password: string;
158
+ inviteCode?: string;
271
159
  }
272
160
  interface AuthResponse {
273
161
  user: User;
274
162
  accessToken: string;
275
163
  refreshToken: string;
276
164
  }
165
+ interface UserMembershipTier {
166
+ id: string;
167
+ level: number;
168
+ label: string;
169
+ capabilities: string[];
170
+ }
171
+ interface UserMembership {
172
+ status: string;
173
+ tier: UserMembershipTier;
174
+ level: number;
175
+ isMember: boolean;
176
+ memberSince?: string | null;
177
+ inviteCodeId?: string | null;
178
+ capabilities: string[];
179
+ }
277
180
 
278
- export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, Attachment, AuthResponse, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, DmAttachment, DmChannel, DmMessage, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, Message, Notification, NotificationType, ReactionGroup, RegisterRequest, SendMessageRequest, Server, Thread, UpdateChannelRequest, UpdateDmMessageRequest, UpdateMessageRequest, UpdateServerRequest, User, UserProfile, UserStatus };
181
+ export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, AuthResponse, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, RegisterRequest, Server, UpdateChannelRequest, UpdateServerRequest, User, UserMembership, UserMembershipTier, UserProfile, UserStatus };
@@ -21,6 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var utils_exports = {};
22
22
  __export(utils_exports, {
23
23
  CAT_AVATAR_COUNT: () => CAT_AVATAR_COUNT,
24
+ assignMentionRanges: () => assignMentionRanges,
25
+ buildMentionMarkdownLinks: () => buildMentionMarkdownLinks,
26
+ canonicalMentionToken: () => canonicalMentionToken,
27
+ canonicalizeMentionContent: () => canonicalizeMentionContent,
28
+ escapeMarkdownLinkLabel: () => escapeMarkdownLinkLabel,
24
29
  formatDate: () => formatDate,
25
30
  generateInviteCode: () => generateInviteCode,
26
31
  generateRandomCatConfig: () => generateRandomCatConfig,
@@ -28,8 +33,12 @@ __export(utils_exports, {
28
33
  getCatAvatar: () => getCatAvatar,
29
34
  getCatAvatarByUserId: () => getCatAvatarByUserId,
30
35
  getCatSvgString: () => getCatSvgString,
36
+ isCanonicalMentionToken: () => isCanonicalMentionToken,
31
37
  isValidEmail: () => isValidEmail,
38
+ mentionDisplayText: () => mentionDisplayText,
39
+ parseCanonicalMentionToken: () => parseCanonicalMentionToken,
32
40
  renderCatSvg: () => renderCatSvg,
41
+ segmentTextByMentions: () => segmentTextByMentions,
33
42
  slugify: () => slugify
34
43
  });
35
44
  module.exports = __toCommonJS(utils_exports);
@@ -217,6 +226,190 @@ function renderCatSvg(config) {
217
226
  return `data:image/svg+xml,${encodeURIComponent(svg.replace(/\n\s*/g, ""))}`;
218
227
  }
219
228
 
229
+ // src/utils/message-mentions.ts
230
+ function uniqueValues(values) {
231
+ return Array.from(new Set(values.filter((value) => !!value)));
232
+ }
233
+ function canonicalMentionToken(mention) {
234
+ if (mention.kind === "channel") return `<#${mention.channelId ?? mention.targetId}>`;
235
+ if (mention.kind === "server") return `<@server:${mention.serverId ?? mention.targetId}>`;
236
+ if (mention.kind === "here" || mention.kind === "everyone") {
237
+ const scope = mention.serverId ?? mention.targetId;
238
+ return scope ? `<!${mention.kind}:${scope}>` : `<!${mention.kind}>`;
239
+ }
240
+ return `<@${mention.userId ?? mention.targetId}>`;
241
+ }
242
+ function parseCanonicalMentionToken(token) {
243
+ const user = token.match(/^<@([^>:]+)>$/u);
244
+ if (user?.[1]) return { kind: "user", targetId: user[1] };
245
+ const server = token.match(/^<@server:([^>]+)>$/u);
246
+ if (server?.[1]) return { kind: "server", targetId: server[1] };
247
+ const channel = token.match(/^<#([^>]+)>$/u);
248
+ if (channel?.[1]) return { kind: "channel", targetId: channel[1] };
249
+ const broadcast = token.match(/^<!(here|everyone)(?::([^>]+))?>$/u);
250
+ if (broadcast?.[1] === "here" || broadcast?.[1] === "everyone") {
251
+ return {
252
+ kind: broadcast[1],
253
+ ...broadcast[2] ? { targetId: broadcast[2] } : {}
254
+ };
255
+ }
256
+ return null;
257
+ }
258
+ function isCanonicalMentionToken(token) {
259
+ return parseCanonicalMentionToken(token) !== null;
260
+ }
261
+ function matchTextsForMention(mention) {
262
+ return uniqueValues([mention.token, mention.sourceToken, canonicalMentionToken(mention)]);
263
+ }
264
+ function isValidRange(content, mention, range) {
265
+ if (!range) return false;
266
+ if (!Number.isInteger(range.start) || !Number.isInteger(range.end)) return false;
267
+ if (range.start < 0 || range.end <= range.start || range.end > content.length) return false;
268
+ const sourceText = content.slice(range.start, range.end);
269
+ return matchTextsForMention(mention).includes(sourceText);
270
+ }
271
+ function overlaps(a, b) {
272
+ return a.start < b.end && b.start < a.end;
273
+ }
274
+ function canUseRange(range, used) {
275
+ return !used.some((candidate) => overlaps(candidate, range));
276
+ }
277
+ function findOccurrences(content, token, used) {
278
+ const occurrences = [];
279
+ let index = content.indexOf(token);
280
+ while (index >= 0) {
281
+ const range = { start: index, end: index + token.length };
282
+ if (canUseRange(range, used)) occurrences.push(range);
283
+ index = content.indexOf(token, index + token.length);
284
+ }
285
+ return occurrences;
286
+ }
287
+ function addCandidate(candidates, used, mention, range, order, sourceText) {
288
+ if (!canUseRange(range, used)) return;
289
+ const matchedText = sourceText ?? mention.sourceToken ?? mention.token;
290
+ used.push(range);
291
+ candidates.push({
292
+ start: range.start,
293
+ end: range.end,
294
+ order,
295
+ sourceText: matchedText,
296
+ mention: { ...mention, range }
297
+ });
298
+ }
299
+ function segmentTextByMentions(content, mentions) {
300
+ if (!content) return [];
301
+ const usableMentions = (mentions ?? []).filter((mention) => mention.token);
302
+ if (usableMentions.length === 0) return [{ type: "text", text: content }];
303
+ const candidates = [];
304
+ const usedRanges = [];
305
+ const pendingByText = /* @__PURE__ */ new Map();
306
+ usableMentions.forEach((mention, order) => {
307
+ if (isValidRange(content, mention, mention.range)) {
308
+ addCandidate(
309
+ candidates,
310
+ usedRanges,
311
+ mention,
312
+ mention.range,
313
+ order,
314
+ content.slice(mention.range.start, mention.range.end)
315
+ );
316
+ return;
317
+ }
318
+ for (const text of matchTextsForMention(mention)) {
319
+ const pending = pendingByText.get(text) ?? [];
320
+ pending.push({ mention, order });
321
+ pendingByText.set(text, pending);
322
+ }
323
+ });
324
+ const pendingGroups = Array.from(pendingByText.entries()).sort((a, b) => {
325
+ const lengthDelta = b[0].length - a[0].length;
326
+ if (lengthDelta !== 0) return lengthDelta;
327
+ return a[1][0].order - b[1][0].order;
328
+ });
329
+ for (const [token, pending] of pendingGroups) {
330
+ const occurrences = findOccurrences(content, token, usedRanges);
331
+ if (occurrences.length === 0) continue;
332
+ if (pending.length === 1) {
333
+ const { mention, order } = pending[0];
334
+ for (const range of occurrences) {
335
+ addCandidate(candidates, usedRanges, mention, range, order, token);
336
+ }
337
+ continue;
338
+ }
339
+ pending.forEach(({ mention, order }, index) => {
340
+ const range = occurrences[index];
341
+ if (range) addCandidate(candidates, usedRanges, mention, range, order, token);
342
+ });
343
+ }
344
+ candidates.sort((a, b) => a.start - b.start || b.end - a.end || a.order - b.order);
345
+ const segments = [];
346
+ let cursor = 0;
347
+ for (const candidate of candidates) {
348
+ if (candidate.start < cursor) continue;
349
+ if (candidate.start > cursor) {
350
+ segments.push({ type: "text", text: content.slice(cursor, candidate.start) });
351
+ }
352
+ const text = content.slice(candidate.start, candidate.end);
353
+ segments.push({
354
+ type: "mention",
355
+ text,
356
+ range: { start: candidate.start, end: candidate.end },
357
+ mention: { ...candidate.mention, sourceToken: candidate.sourceText }
358
+ });
359
+ cursor = candidate.end;
360
+ }
361
+ if (cursor < content.length) {
362
+ segments.push({ type: "text", text: content.slice(cursor) });
363
+ }
364
+ return segments.length > 0 ? segments : [{ type: "text", text: content }];
365
+ }
366
+ function assignMentionRanges(content, mentions) {
367
+ return segmentTextByMentions(content, mentions).filter((segment) => {
368
+ return segment.type === "mention";
369
+ }).map((segment) => ({
370
+ ...segment.mention,
371
+ token: segment.mention.token || segment.text,
372
+ range: segment.range
373
+ }));
374
+ }
375
+ function canonicalizeMentionContent(content, mentions) {
376
+ const canonicalMentions = [];
377
+ let nextContent = "";
378
+ for (const segment of segmentTextByMentions(content, mentions)) {
379
+ if (segment.type === "text") {
380
+ nextContent += segment.text;
381
+ continue;
382
+ }
383
+ const token = canonicalMentionToken(segment.mention);
384
+ const start = nextContent.length;
385
+ nextContent += token;
386
+ canonicalMentions.push({
387
+ ...segment.mention,
388
+ token,
389
+ sourceToken: segment.text === token ? segment.mention.sourceToken : segment.text,
390
+ range: { start, end: start + token.length }
391
+ });
392
+ }
393
+ return { content: nextContent, mentions: canonicalMentions };
394
+ }
395
+ function mentionDisplayText(mention) {
396
+ return mention.label || mention.token;
397
+ }
398
+ function escapeMarkdownLinkLabel(label) {
399
+ return label.replace(/\\/g, "\\\\").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
400
+ }
401
+ function buildMentionMarkdownLinks(content, mentions, hrefForMention) {
402
+ const linkedMentions = [];
403
+ const markdown = segmentTextByMentions(content, mentions).map((segment) => {
404
+ if (segment.type === "text") return segment.text;
405
+ const href = hrefForMention(segment.mention, linkedMentions.length);
406
+ if (!href) return segment.text;
407
+ linkedMentions.push(segment.mention);
408
+ return `[${escapeMarkdownLinkLabel(mentionDisplayText(segment.mention))}](${href})`;
409
+ }).join("");
410
+ return { markdown, mentions: linkedMentions };
411
+ }
412
+
220
413
  // src/utils/pixel-cats.ts
221
414
  var variants = [
222
415
  // 0: Shadow — Black cat (logo style)
@@ -349,6 +542,11 @@ function slugify(text) {
349
542
  // Annotate the CommonJS export names for ESM import in node:
350
543
  0 && (module.exports = {
351
544
  CAT_AVATAR_COUNT,
545
+ assignMentionRanges,
546
+ buildMentionMarkdownLinks,
547
+ canonicalMentionToken,
548
+ canonicalizeMentionContent,
549
+ escapeMarkdownLinkLabel,
352
550
  formatDate,
353
551
  generateInviteCode,
354
552
  generateRandomCatConfig,
@@ -356,7 +554,11 @@ function slugify(text) {
356
554
  getCatAvatar,
357
555
  getCatAvatarByUserId,
358
556
  getCatSvgString,
557
+ isCanonicalMentionToken,
359
558
  isValidEmail,
559
+ mentionDisplayText,
560
+ parseCanonicalMentionToken,
360
561
  renderCatSvg,
562
+ segmentTextByMentions,
361
563
  slugify
362
564
  });
@@ -1,3 +1,5 @@
1
+ import { g as MessageMentionRange, e as MessageMention } from '../message.types-lG4qBSus.cjs';
2
+
1
3
  type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor';
2
4
  type CatExpression = 'smile' | 'open' | 'flat' | 'sad' | 'surprised' | 'kawaii' | 'winking' | 'smirk';
3
5
  type CatDecoration = 'none' | 'glasses' | 'blush' | 'scar' | 'flower' | 'fish' | 'headband';
@@ -15,6 +17,43 @@ interface CatConfig {
15
17
  declare function generateRandomCatConfig(): CatConfig;
16
18
  declare function renderCatSvg(config: CatConfig): string;
17
19
 
20
+ type MessageMentionTextSegment = {
21
+ type: 'text';
22
+ text: string;
23
+ } | {
24
+ type: 'mention';
25
+ text: string;
26
+ range: MessageMentionRange;
27
+ mention: MessageMention;
28
+ };
29
+ declare function canonicalMentionToken(mention: Pick<MessageMention, 'kind' | 'targetId'> & Partial<MessageMention>): string;
30
+ declare function parseCanonicalMentionToken(token: string): {
31
+ kind: 'user';
32
+ targetId: string;
33
+ } | {
34
+ kind: 'channel';
35
+ targetId: string;
36
+ } | {
37
+ kind: 'server';
38
+ targetId: string;
39
+ } | {
40
+ kind: 'here' | 'everyone';
41
+ targetId?: string;
42
+ } | null;
43
+ declare function isCanonicalMentionToken(token: string): boolean;
44
+ declare function segmentTextByMentions(content: string, mentions: readonly MessageMention[] | null | undefined): MessageMentionTextSegment[];
45
+ declare function assignMentionRanges(content: string, mentions: readonly MessageMention[] | null | undefined): MessageMention[];
46
+ declare function canonicalizeMentionContent(content: string, mentions: readonly MessageMention[] | null | undefined): {
47
+ content: string;
48
+ mentions: MessageMention[];
49
+ };
50
+ declare function mentionDisplayText(mention: Pick<MessageMention, 'label' | 'token'>): string;
51
+ declare function escapeMarkdownLinkLabel(label: string): string;
52
+ declare function buildMentionMarkdownLinks(content: string, mentions: readonly MessageMention[] | null | undefined, hrefForMention: (mention: MessageMention, index: number) => string | null | undefined): {
53
+ markdown: string;
54
+ mentions: MessageMention[];
55
+ };
56
+
18
57
  /**
19
58
  * Pixel Art Cat Avatar System
20
59
  * 8 unique cat variants with distinct color schemes inspired by the Shadow logo
@@ -38,4 +77,4 @@ declare function formatDate(date: string | Date): string;
38
77
  declare function isValidEmail(email: string): boolean;
39
78
  declare function slugify(text: string): string;
40
79
 
41
- export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isValidEmail, renderCatSvg, slugify };
80
+ export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type MessageMentionTextSegment, assignMentionRanges, buildMentionMarkdownLinks, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, slugify };