@principal-ai/control-tower-core 0.3.2 → 0.4.1

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.
@@ -8,6 +8,7 @@
8
8
  * backed by Redis or another shared data store.
9
9
  */
10
10
  import type { BaseServer } from "../server/BaseServer.js";
11
+ import type { Message } from "../types/index.js";
11
12
  import type { ActivityUpdate, DeviceInfo, PresenceChangeEvent, PresenceConfig, PresenceStatus, UserPresence } from "../types/presence.js";
12
13
  import type { ExtendedUserPresence, PresenceExtension } from "./PresenceExtension.js";
13
14
  import { PresenceManager } from "./PresenceManager.js";
@@ -59,5 +60,44 @@ export declare class DefaultPresenceManager<TExtendedData = Record<string, unkno
59
60
  * Get total unique user count
60
61
  */
61
62
  getUniqueUserCount(): number;
63
+ /**
64
+ * Convert UserPresence to SerializableUserPresence
65
+ * Converts the devices Map to a plain object for JSON serialization
66
+ */
67
+ private serializePresence;
68
+ /**
69
+ * Handle presence WebSocket messages
70
+ *
71
+ * This method handles core presence messages and delegates to extensions
72
+ * for extension-specific messages. Use this with CustomMessageHandler.
73
+ *
74
+ * @param userId - Authenticated user ID
75
+ * @param deviceId - Device/client ID
76
+ * @param message - The WebSocket message
77
+ * @param sendResponse - Callback to send response
78
+ * @returns true if the message was handled, false otherwise
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const server = new ServerBuilder()
83
+ * .withPresenceManager(presenceManager)
84
+ * .withCustomMessageHandler(async (clientId, message, sendResponse) => {
85
+ * const client = server.getClient(clientId);
86
+ * if (!client?.authenticated || !client.userId) return false;
87
+ * const deviceId = getDeviceIdForClient(clientId);
88
+ * return presenceManager.handlePresenceMessage(
89
+ * client.userId,
90
+ * deviceId,
91
+ * message,
92
+ * sendResponse
93
+ * );
94
+ * })
95
+ * .build();
96
+ * ```
97
+ */
98
+ handlePresenceMessage(userId: string, deviceId: string, message: Message, sendResponse: (response: {
99
+ type: string;
100
+ payload: unknown;
101
+ }) => Promise<void>): Promise<boolean>;
62
102
  }
63
103
  //# sourceMappingURL=DefaultPresenceManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultPresenceManager.d.ts","sourceRoot":"","sources":["../../src/abstractions/DefaultPresenceManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EACX,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACX,oBAAoB,EACpB,iBAAiB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAWvD,qBAAa,sBAAsB,CAClC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACtC,SAAQ,eAAe;IACxB,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,MAAM,CAAC,CAAa;gBAG3B,MAAM,CAAC,EAAE,cAAc,GAAG;QACzB,UAAU,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,EAAE,CAAC;KAChD;IAMF;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAInC;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3C;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC;IAgIlB,gBAAgB,CACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAuEzB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAiC7D,eAAe,CACpB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAyBhD,gBAAgB,CACrB,OAAO,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAa/B,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC,EAAE,CAAC;IA4BhE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IASrD,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,GACpB,OAAO,CAAC,YAAY,CAAC;IAUlB,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA4EnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;OAEG;IACH,uBAAuB,IAAI,MAAM;IAIjC;;OAEG;IACH,kBAAkB,IAAI,MAAM;CAG5B"}
1
+ {"version":3,"file":"DefaultPresenceManager.d.ts","sourceRoot":"","sources":["../../src/abstractions/DefaultPresenceManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACX,cAAc,EACd,UAAU,EAEV,mBAAmB,EACnB,cAAc,EAKd,cAAc,EAEd,YAAY,EACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACX,oBAAoB,EACpB,iBAAiB,EAEjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAWvD,qBAAa,sBAAsB,CAClC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACtC,SAAQ,eAAe;IACxB,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,MAAM,CAAC,CAAa;gBAG3B,MAAM,CAAC,EAAE,cAAc,GAAG;QACzB,UAAU,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,EAAE,CAAC;KAChD;IAMF;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAInC;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3C;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC;IAgIlB,gBAAgB,CACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAuEzB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAiC7D,eAAe,CACpB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAyBhD,gBAAgB,CACrB,OAAO,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAa/B,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC,EAAE,CAAC;IA4BhE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IASrD,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,GACpB,OAAO,CAAC,YAAY,CAAC;IAUlB,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA4EnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;OAEG;IACH,uBAAuB,IAAI,MAAM;IAIjC;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,qBAAqB,CAC1B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAC3E,OAAO,CAAC,OAAO,CAAC;CA2JnB"}
@@ -393,5 +393,171 @@ class DefaultPresenceManager extends PresenceManager_js_1.PresenceManager {
393
393
  getUniqueUserCount() {
394
394
  return this.userPresences.size + this.gracePeriodEntries.size;
395
395
  }
396
+ /**
397
+ * Convert UserPresence to SerializableUserPresence
398
+ * Converts the devices Map to a plain object for JSON serialization
399
+ */
400
+ serializePresence(presence) {
401
+ const { devices, extended, ...rest } = presence;
402
+ return {
403
+ ...rest,
404
+ devices: Object.fromEntries(devices),
405
+ // Spread extended data at top level for compatibility
406
+ ...(extended || {}),
407
+ };
408
+ }
409
+ /**
410
+ * Handle presence WebSocket messages
411
+ *
412
+ * This method handles core presence messages and delegates to extensions
413
+ * for extension-specific messages. Use this with CustomMessageHandler.
414
+ *
415
+ * @param userId - Authenticated user ID
416
+ * @param deviceId - Device/client ID
417
+ * @param message - The WebSocket message
418
+ * @param sendResponse - Callback to send response
419
+ * @returns true if the message was handled, false otherwise
420
+ *
421
+ * @example
422
+ * ```typescript
423
+ * const server = new ServerBuilder()
424
+ * .withPresenceManager(presenceManager)
425
+ * .withCustomMessageHandler(async (clientId, message, sendResponse) => {
426
+ * const client = server.getClient(clientId);
427
+ * if (!client?.authenticated || !client.userId) return false;
428
+ * const deviceId = getDeviceIdForClient(clientId);
429
+ * return presenceManager.handlePresenceMessage(
430
+ * client.userId,
431
+ * deviceId,
432
+ * message,
433
+ * sendResponse
434
+ * );
435
+ * })
436
+ * .build();
437
+ * ```
438
+ */
439
+ async handlePresenceMessage(userId, deviceId, message, sendResponse) {
440
+ switch (message.type) {
441
+ case "presence:get_users": {
442
+ const onlineUsers = await this.getOnlineUsers();
443
+ const users = onlineUsers.map((u) => this.serializePresence(u));
444
+ const response = {
445
+ users,
446
+ stats: {
447
+ totalOnline: users.length,
448
+ },
449
+ };
450
+ await sendResponse({ type: "presence:get_users", payload: response });
451
+ return true;
452
+ }
453
+ case "presence:get_user": {
454
+ const { userId: targetUserId } = message.payload;
455
+ const userPresence = await this.getUserPresence(targetUserId);
456
+ const response = {
457
+ user: userPresence ? this.serializePresence(userPresence) : null,
458
+ };
459
+ await sendResponse({ type: "presence:get_user", payload: response });
460
+ return true;
461
+ }
462
+ case "presence:set_status": {
463
+ const { status, statusMessage } = message.payload;
464
+ await this.setUserStatus(userId, status);
465
+ // Broadcast status change
466
+ if (this.config.broadcastPresenceUpdates && this.server) {
467
+ const experimental = this.server.experimental;
468
+ await experimental?.broadcastAuthenticated({
469
+ type: "presence:status_changed",
470
+ payload: { userId, status, statusMessage },
471
+ });
472
+ }
473
+ const response = { success: true };
474
+ await sendResponse({ type: "presence:set_status", payload: response });
475
+ return true;
476
+ }
477
+ case "presence:set_visibility": {
478
+ const { visible } = message.payload;
479
+ // Visibility is handled by extensions
480
+ // Find an extension that can handle visibility
481
+ for (const ext of this.extensions) {
482
+ if (typeof ext.setVisibility === "function") {
483
+ ext.setVisibility(userId, visible);
484
+ break;
485
+ }
486
+ }
487
+ const response = { success: true };
488
+ await sendResponse({ type: "presence:set_visibility", payload: response });
489
+ return true;
490
+ }
491
+ case "presence:repo_status_update": {
492
+ const { repoId, gitStatus } = message.payload;
493
+ // Find extension that can handle git status update
494
+ let updated = false;
495
+ for (const ext of this.extensions) {
496
+ if (typeof ext.updateRepositoryGitStatus === "function") {
497
+ updated = ext.updateRepositoryGitStatus(userId, repoId, deviceId, gitStatus);
498
+ break;
499
+ }
500
+ }
501
+ if (!updated) {
502
+ const response = {
503
+ success: false,
504
+ message: "Repository session not found",
505
+ };
506
+ await sendResponse({ type: "presence:repo_status_update", payload: response });
507
+ return true;
508
+ }
509
+ // Broadcast status change
510
+ if (this.config.broadcastPresenceUpdates && this.server) {
511
+ // Check visibility
512
+ let visible = true;
513
+ for (const ext of this.extensions) {
514
+ const shouldShow = await ext.shouldBeVisible?.(userId);
515
+ if (shouldShow === false) {
516
+ visible = false;
517
+ break;
518
+ }
519
+ }
520
+ if (visible) {
521
+ const experimental = this.server.experimental;
522
+ await experimental?.broadcastAuthenticated({
523
+ type: "presence:repo_status_changed",
524
+ payload: { userId, repoId, deviceId, gitStatus },
525
+ });
526
+ }
527
+ }
528
+ const response = {
529
+ success: true,
530
+ message: "Status updated",
531
+ };
532
+ await sendResponse({ type: "presence:repo_status_update", payload: response });
533
+ return true;
534
+ }
535
+ default: {
536
+ // Try extension handlers
537
+ for (const ext of this.extensions) {
538
+ if (ext.handleMessage) {
539
+ const result = await ext.handleMessage(userId, deviceId, message.type, message.payload);
540
+ if (result) {
541
+ // Send response
542
+ await sendResponse({
543
+ type: message.type,
544
+ payload: result.response,
545
+ });
546
+ // Handle broadcast if specified
547
+ if (result.broadcast && this.server) {
548
+ const experimental = this.server.experimental;
549
+ await experimental?.broadcastAuthenticated({
550
+ type: result.broadcast.type,
551
+ payload: result.broadcast.payload,
552
+ });
553
+ }
554
+ return true;
555
+ }
556
+ }
557
+ }
558
+ return false; // Message not handled
559
+ }
560
+ }
561
+ }
396
562
  }
397
563
  exports.DefaultPresenceManager = DefaultPresenceManager;
@@ -9,8 +9,31 @@
9
9
  * - Control visibility of users
10
10
  * - React to room joins/leaves
11
11
  * - Track application-specific presence state
12
+ * - Handle custom WebSocket messages
12
13
  */
13
14
  import type { UserPresence } from "../types/presence.js";
15
+ /**
16
+ * Result from handling a presence message
17
+ */
18
+ export interface PresenceMessageHandlerResult {
19
+ /**
20
+ * Response payload to send back to the client
21
+ */
22
+ response: unknown;
23
+ /**
24
+ * Optional broadcast payload to send to other clients
25
+ * If provided, will be broadcast to all authenticated clients
26
+ */
27
+ broadcast?: {
28
+ type: string;
29
+ payload: unknown;
30
+ /**
31
+ * If true, exclude the sender from the broadcast
32
+ * @default true
33
+ */
34
+ excludeSender?: boolean;
35
+ };
36
+ }
14
37
  /**
15
38
  * Extension for adding custom presence data and behavior
16
39
  *
@@ -106,6 +129,45 @@ export interface PresenceExtension<TExtendedData = Record<string, unknown>> {
106
129
  * Use this for cleanup tasks like persisting state.
107
130
  */
108
131
  destroy?(): Promise<void> | void;
132
+ /**
133
+ * Lifecycle: Called when presence state should be cleaned up for a user
134
+ *
135
+ * Use this for cleaning up user-specific state when they go fully offline.
136
+ *
137
+ * @param userId - User identifier
138
+ */
139
+ onPresenceCleanup?(userId: string): Promise<void> | void;
140
+ /**
141
+ * Handle extension-specific WebSocket messages
142
+ *
143
+ * Return a result if the message was handled, undefined if not.
144
+ * The presence manager will send the response and handle any broadcasts.
145
+ *
146
+ * @param userId - User identifier
147
+ * @param deviceId - Device/client identifier
148
+ * @param messageType - The message type (e.g., 'presence:repo_status_update')
149
+ * @param payload - The message payload
150
+ * @returns Handler result with response and optional broadcast, or undefined if not handled
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * async handleMessage(userId, deviceId, type, payload) {
155
+ * if (type === 'presence:repo_status_update') {
156
+ * const { repoId, gitStatus } = payload;
157
+ * this.updateGitStatus(userId, repoId, deviceId, gitStatus);
158
+ * return {
159
+ * response: { success: true, message: 'Status updated' },
160
+ * broadcast: {
161
+ * type: 'presence:repo_status_changed',
162
+ * payload: { userId, repoId, deviceId, gitStatus }
163
+ * }
164
+ * };
165
+ * }
166
+ * return undefined;
167
+ * }
168
+ * ```
169
+ */
170
+ handleMessage?(userId: string, deviceId: string, messageType: string, payload: unknown): Promise<PresenceMessageHandlerResult | undefined> | PresenceMessageHandlerResult | undefined;
109
171
  }
110
172
  /**
111
173
  * Extended user presence with custom data
@@ -1 +1 @@
1
- {"version":3,"file":"PresenceExtension.d.ts","sourceRoot":"","sources":["../../src/abstractions/PresenceExtension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACzE;;;;;;OAMG;IACH,YAAY,CAAC,CACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAExB;;;;;;;OAOG;IACH,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEvE;;;;;;OAMG;IACH,iBAAiB,CAAC,CACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAExB;;;;;OAKG;IACH,oBAAoB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE9E;;;;;;;;OAQG;IACH,YAAY,CAAC,CACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAExB;;;;;;OAMG;IACH,UAAU,CAAC,CACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAExB;;;;;;;OAOG;IACH,eAAe,CAAC,CACf,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC;IAExD;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAE7D;;;;;;OAMG;IACH,UAAU,CAAC,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,GACnD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAExB;;;;OAIG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEpC;;;;OAIG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC5E,SAAQ,YAAY;IACpB;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;CACzB"}
1
+ {"version":3,"file":"PresenceExtension.d.ts","sourceRoot":"","sources":["../../src/abstractions/PresenceExtension.ts"],"names":[],"mappings":"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"}
@@ -10,5 +10,6 @@
10
10
  * - Control visibility of users
11
11
  * - React to room joins/leaves
12
12
  * - Track application-specific presence state
13
+ * - Handle custom WebSocket messages
13
14
  */
14
15
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -5,7 +5,7 @@ export { DefaultPresenceManager } from "./DefaultPresenceManager.js";
5
5
  export { DefaultRoomManager } from "./DefaultRoomManager.js";
6
6
  export { EventListener, TypedEventEmitter, UnsubscribeFn, } from "./EventEmitter.js";
7
7
  export { LockManager } from "./LockManager.js";
8
- export { type ExtendedUserPresence, type PresenceExtension, } from "./PresenceExtension.js";
8
+ export { type ExtendedUserPresence, type PresenceExtension, type PresenceMessageHandlerResult, } from "./PresenceExtension.js";
9
9
  export { PresenceManager } from "./PresenceManager.js";
10
10
  export { RoomManager } from "./RoomManager.js";
11
11
  export { IStorageAdapter, StorageOperation } from "./StorageAdapter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/abstractions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACN,aAAa,EACb,iBAAiB,EACjB,aAAa,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/abstractions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACN,aAAa,EACb,iBAAiB,EACjB,aAAa,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,4BAA4B,GACjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../../src/client/BaseClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../../src/client/BaseClient.ts"],"names":[],"mappings":"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"}
@@ -331,6 +331,12 @@ class BaseClient extends EventEmitter_js_1.TypedEventEmitter {
331
331
  case "error":
332
332
  await this.handleServerError(message.payload);
333
333
  break;
334
+ default:
335
+ // Emit unrecognized message types as events for custom handlers
336
+ // This allows PresenceClient and other extensions to receive
337
+ // server-initiated messages like presence:user_online, presence:repo_status_changed
338
+ await this.emit(message.type, message.payload);
339
+ break;
334
340
  }
335
341
  }
336
342
  catch (error) {
@@ -5,7 +5,7 @@
5
5
  * Automatically handles connection, authentication, and presence event forwarding.
6
6
  */
7
7
  import { TypedEventEmitter } from "../abstractions/EventEmitter.js";
8
- import type { SerializableUserPresence } from "../types/presence.js";
8
+ import type { SerializableUserPresence, SharedGitStatus } from "../types/presence.js";
9
9
  import { BaseClient, type ClientConfig } from "./BaseClient.js";
10
10
  export interface PresenceClientConfig {
11
11
  /**
@@ -55,6 +55,15 @@ export interface PresenceClientEvents {
55
55
  status: string;
56
56
  statusMessage?: string;
57
57
  };
58
+ /**
59
+ * Repository git status changed (another user updated their status)
60
+ */
61
+ repoStatusChanged: {
62
+ userId: string;
63
+ repoId: string;
64
+ deviceId: string;
65
+ gitStatus: SharedGitStatus;
66
+ };
58
67
  /**
59
68
  * Connected to presence system
60
69
  */
@@ -170,6 +179,16 @@ export declare class PresenceClient extends TypedEventEmitter<PresenceClientEven
170
179
  * @param repoId Repository ID (format: "owner/repo")
171
180
  */
172
181
  reportRepoFocused(repoId: string): Promise<void>;
182
+ /**
183
+ * Update git status for a repository
184
+ *
185
+ * Sends the current git status (branch, dirty state, file changes) to the
186
+ * presence system, which broadcasts it to other users viewing the same repo.
187
+ *
188
+ * @param repoId Repository ID (format: "owner/repo")
189
+ * @param gitStatus The current git status to share
190
+ */
191
+ updateRepoStatus(repoId: string, gitStatus: SharedGitStatus): Promise<void>;
173
192
  /**
174
193
  * Get the underlying BaseClient
175
194
  */
@@ -1 +1 @@
1
- {"version":3,"file":"PresenceClient.d.ts","sourceRoot":"","sources":["../../src/client/PresenceClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAKX,wBAAwB,EACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC;IAE3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAEnD;;OAEG;IACH,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAEhC;;OAEG;IACH,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE1E;;OAEG;IACH,SAAS,EAAE,EAAE,CAAC;IAEd;;OAEG;IACH,YAAY,EAAE,EAAE,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IAExB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,cAAe,SAAQ,iBAAiB,CAAC,oBAAoB,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAiB;gBAE9B,MAAM,EAAE,oBAAoB;IAiBxC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBjC;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAQ3D;;;;;OAKG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAQ/E;;;;;;OAMG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAQpF;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjF;;;;OAIG;IACG,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpD;;;;;OAKG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrE;;;;OAIG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD;;;;OAIG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtD;;OAEG;IACH,SAAS,IAAI,UAAU;IAIvB;;OAEG;IACH,WAAW,IAAI,OAAO;IAMtB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;CAwD5B"}
1
+ {"version":3,"file":"PresenceClient.d.ts","sourceRoot":"","sources":["../../src/client/PresenceClient.ts"],"names":[],"mappings":"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"}
@@ -178,6 +178,21 @@ class PresenceClient extends EventEmitter_js_1.TypedEventEmitter {
178
178
  throw new Error(response.error || "Failed to report repo focused");
179
179
  }
180
180
  }
181
+ /**
182
+ * Update git status for a repository
183
+ *
184
+ * Sends the current git status (branch, dirty state, file changes) to the
185
+ * presence system, which broadcasts it to other users viewing the same repo.
186
+ *
187
+ * @param repoId Repository ID (format: "owner/repo")
188
+ * @param gitStatus The current git status to share
189
+ */
190
+ async updateRepoStatus(repoId, gitStatus) {
191
+ const response = await this.client.request("presence:repo_status_update", { repoId, gitStatus });
192
+ if (!response.success) {
193
+ throw new Error(response.message || "Failed to update repo status");
194
+ }
195
+ }
181
196
  /**
182
197
  * Get the underlying BaseClient
183
198
  */
@@ -223,6 +238,17 @@ class PresenceClient extends EventEmitter_js_1.TypedEventEmitter {
223
238
  });
224
239
  }
225
240
  });
241
+ this.client.on("presence:repo_status_changed", (data) => {
242
+ if (data && typeof data === "object") {
243
+ const payload = data;
244
+ void this.emit("repoStatusChanged", {
245
+ userId: payload.userId,
246
+ repoId: payload.repoId,
247
+ deviceId: payload.deviceId,
248
+ gitStatus: payload.gitStatus,
249
+ });
250
+ }
251
+ });
226
252
  // Handle disconnection
227
253
  this.client.on("disconnected", () => {
228
254
  void this.emit("disconnected", {});
package/dist/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export { type PeerConnection, type PeerConnectionState, WebRTCSignalingAdapter,
4
4
  export { BrowserWebSocketTransportAdapter, type BrowserWebSocketConfig, type WebSocketClientConfig, WebSocketClientTransportAdapter, WebSocketServerTransportAdapter, type WebSocketServerTransportConfig, } from "./adapters/websocket/index.js";
5
5
  export { BaseClient, ClientBuilder, type ClientConfig, type ClientEvents, PresenceClient, type PresenceClientConfig, type PresenceClientEvents, } from "./client/index.js";
6
6
  export { BaseServer, type ConnectedClient, type CustomMessageHandler, ExperimentalAPI, ServerBuilder, type ServerConfig, type ServerEvents, } from "./server/index.js";
7
- export { ActivityUpdate, AuthenticatePayload, AuthenticateResult, AuthResult, BaseEvent, BranchChangeEvent, BroadcastOptions, BroadcastResult, ClientPredicate, CloseHandler, CommitEvent, ConnectionOptions, ConnectionState, CursorPositionEvent, DeviceInfo, ErrorHandler, Event, EventType, ExperimentalFeatureConfig, ExperimentalFeatureError, ExperimentalUsageEvent, FileAction, FileChangeEvent, GitStatusEvent, JWTConfig, Lock, LockPriority, LockQueueItem, LockRequest, LockState, LockType, Message, MessageHandler, PresenceActionResponse, PresenceChangeEvent, PresenceConfig, PresenceGetRepoUsersResponse, PresenceGetUserResponse, PresenceGetUsersResponse, PresenceStats, PresenceStatus, RepositorySession, Room, RoomConfig, RoomPermission, RoomState, RoomUser, SerializableUserPresence, TokenPayload, UserPresence, UserStatus, } from "./types/index.js";
7
+ export { ActivityUpdate, AuthenticatePayload, AuthenticateResult, AuthResult, BaseEvent, BranchChangeEvent, BroadcastOptions, BroadcastResult, ClientPredicate, CloseHandler, CommitEvent, ConnectionOptions, ConnectionState, CursorPositionEvent, DeviceInfo, ErrorHandler, Event, EventType, ExperimentalFeatureConfig, ExperimentalFeatureError, ExperimentalUsageEvent, FileAction, FileChangeEvent, GitStatusEvent, JWTConfig, Lock, LockPriority, LockQueueItem, LockRequest, LockState, LockType, Message, MessageHandler, PresenceActionResponse, PresenceChangeEvent, PresenceConfig, PresenceGetRepoUsersResponse, PresenceGetUserResponse, PresenceGetUsersResponse, PresenceRepoStatusChangedEvent, PresenceRepoStatusUpdateRequest, PresenceRepoStatusUpdateResponse, PresenceStats, PresenceStatus, RepositorySession, SharedGitStatus, Room, RoomConfig, RoomPermission, RoomState, RoomUser, SerializableUserPresence, TokenPayload, UserPresence, UserStatus, } from "./types/index.js";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,GACb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,eAAe,EACf,KAAK,gBAAgB,EAErB,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAC3B,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC1B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACN,gCAAgC,EAChC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,+BAA+B,EAC/B,KAAK,8BAA8B,GACnC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACN,UAAU,EACV,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,eAAe,EACf,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,WAAW,EACX,iBAAiB,EAEjB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,KAAK,EAEL,SAAS,EAET,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,SAAS,EACT,IAAI,EACJ,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EAET,QAAQ,EACR,OAAO,EACP,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,EACxB,aAAa,EAEb,cAAc,EACd,iBAAiB,EACjB,IAAI,EACJ,UAAU,EAEV,cAAc,EACd,SAAS,EACT,QAAQ,EACR,wBAAwB,EAExB,YAAY,EACZ,YAAY,EACZ,UAAU,GACV,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,GACb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,eAAe,EACf,KAAK,gBAAgB,EAErB,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAC3B,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC1B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACN,gCAAgC,EAChC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,+BAA+B,EAC/B,KAAK,8BAA8B,GACnC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACN,UAAU,EACV,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,eAAe,EACf,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,WAAW,EACX,iBAAiB,EAEjB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,KAAK,EAEL,SAAS,EAET,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,SAAS,EACT,IAAI,EACJ,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EAET,QAAQ,EACR,OAAO,EACP,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,EAC/B,gCAAgC,EAChC,aAAa,EAEb,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,IAAI,EACJ,UAAU,EAEV,cAAc,EACd,SAAS,EACT,QAAQ,EACR,wBAAwB,EAExB,YAAY,EACZ,YAAY,EACZ,UAAU,GACV,MAAM,kBAAkB,CAAC"}