@superatomai/sdk-node 0.0.19 → 0.0.20

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/index.mjs CHANGED
@@ -411,7 +411,8 @@ var UserPromptRequestMessageSchema = z3.object({
411
411
  });
412
412
  var UserPromptSuggestionsPayloadSchema = z3.object({
413
413
  prompt: z3.string(),
414
- limit: z3.number().int().positive().default(5)
414
+ limit: z3.number().int().positive().default(5),
415
+ similarityThreshold: z3.number().min(0).max(1).default(0.4)
415
416
  });
416
417
  var UserPromptSuggestionsMessageSchema = z3.object({
417
418
  id: z3.string(),
@@ -498,11 +499,28 @@ var ActionsRequestMessageSchema = z3.object({
498
499
  type: z3.literal("ACTIONS"),
499
500
  payload: ActionsRequestPayloadSchema
500
501
  });
502
+ var DashboardQueryFiltersSchema = z3.object({
503
+ dashboardId: z3.string().optional(),
504
+ projectId: z3.string().optional(),
505
+ createdBy: z3.number().optional(),
506
+ updatedBy: z3.number().optional(),
507
+ name: z3.string().optional()
508
+ });
501
509
  var DashboardsRequestPayloadSchema = z3.object({
502
- operation: z3.enum(["create", "update", "delete", "getAll", "getOne"]),
510
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
503
511
  data: z3.object({
512
+ id: z3.number().optional(),
504
513
  dashboardId: z3.string().optional(),
505
- dashboard: DSLRendererPropsSchema.optional()
514
+ projectId: z3.string().optional(),
515
+ name: z3.string().optional(),
516
+ description: z3.string().optional(),
517
+ createdBy: z3.number().optional(),
518
+ updatedBy: z3.number().optional(),
519
+ dashboard: DSLRendererPropsSchema.optional(),
520
+ // Query operation fields
521
+ filters: DashboardQueryFiltersSchema.optional(),
522
+ limit: z3.number().optional(),
523
+ sort: z3.enum(["ASC", "DESC"]).optional()
506
524
  }).optional()
507
525
  });
508
526
  var DashboardsRequestMessageSchema = z3.object({
@@ -511,11 +529,28 @@ var DashboardsRequestMessageSchema = z3.object({
511
529
  type: z3.literal("DASHBOARDS"),
512
530
  payload: DashboardsRequestPayloadSchema
513
531
  });
532
+ var ReportQueryFiltersSchema = z3.object({
533
+ reportId: z3.string().optional(),
534
+ projectId: z3.string().optional(),
535
+ createdBy: z3.number().optional(),
536
+ updatedBy: z3.number().optional(),
537
+ name: z3.string().optional()
538
+ });
514
539
  var ReportsRequestPayloadSchema = z3.object({
515
- operation: z3.enum(["create", "update", "delete", "getAll", "getOne"]),
540
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
516
541
  data: z3.object({
542
+ id: z3.number().optional(),
517
543
  reportId: z3.string().optional(),
518
- report: DSLRendererPropsSchema2.optional()
544
+ projectId: z3.string().optional(),
545
+ name: z3.string().optional(),
546
+ description: z3.string().optional(),
547
+ createdBy: z3.number().optional(),
548
+ updatedBy: z3.number().optional(),
549
+ report: DSLRendererPropsSchema2.optional(),
550
+ // Query operation fields
551
+ filters: ReportQueryFiltersSchema.optional(),
552
+ limit: z3.number().optional(),
553
+ sort: z3.enum(["ASC", "DESC"]).optional()
519
554
  }).optional()
520
555
  });
521
556
  var ReportsRequestMessageSchema = z3.object({
@@ -524,6 +559,36 @@ var ReportsRequestMessageSchema = z3.object({
524
559
  type: z3.literal("REPORTS"),
525
560
  payload: ReportsRequestPayloadSchema
526
561
  });
562
+ var UIQueryFiltersSchema = z3.object({
563
+ uiId: z3.string().optional(),
564
+ projectId: z3.string().optional(),
565
+ createdBy: z3.number().optional(),
566
+ updatedBy: z3.number().optional(),
567
+ name: z3.string().optional()
568
+ });
569
+ var UIsRequestPayloadSchema = z3.object({
570
+ operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
571
+ data: z3.object({
572
+ id: z3.number().optional(),
573
+ uiId: z3.string().optional(),
574
+ projectId: z3.string().optional(),
575
+ name: z3.string().optional(),
576
+ description: z3.string().optional(),
577
+ createdBy: z3.number().optional(),
578
+ updatedBy: z3.number().optional(),
579
+ ui: DSLRendererPropsSchema.optional(),
580
+ // Query operation fields
581
+ filters: UIQueryFiltersSchema.optional(),
582
+ limit: z3.number().optional(),
583
+ sort: z3.enum(["ASC", "DESC"]).optional()
584
+ }).optional()
585
+ });
586
+ var UIsRequestMessageSchema = z3.object({
587
+ id: z3.string(),
588
+ from: MessageParticipantSchema,
589
+ type: z3.literal("UIS"),
590
+ payload: UIsRequestPayloadSchema
591
+ });
527
592
  var UIBlockSchema = z3.object({
528
593
  id: z3.string().optional(),
529
594
  userQuestion: z3.string().optional(),
@@ -547,10 +612,16 @@ var UIBlockSchema = z3.object({
547
612
  similarity: z3.number().optional()
548
613
  }).optional()
549
614
  });
615
+ var DBUIBlockSchema = z3.object({
616
+ id: z3.string(),
617
+ component: z3.record(z3.string(), z3.any()).nullable(),
618
+ analysis: z3.string().nullable(),
619
+ user_prompt: z3.string()
620
+ });
550
621
  var BookmarkDataSchema = z3.object({
551
622
  id: z3.number().optional(),
552
- uiblock: z3.any(),
553
- // JSON object
623
+ uiblock: DBUIBlockSchema,
624
+ // Typed JSON object
554
625
  created_at: z3.string().optional(),
555
626
  updated_at: z3.string().optional()
556
627
  });
@@ -560,7 +631,9 @@ var BookmarksRequestPayloadSchema = z3.object({
560
631
  id: z3.number().optional(),
561
632
  userId: z3.number().optional(),
562
633
  threadId: z3.string().optional(),
563
- uiblock: z3.any().optional()
634
+ name: z3.string().optional(),
635
+ description: z3.string().optional(),
636
+ uiblock: DBUIBlockSchema.optional()
564
637
  }).optional()
565
638
  });
566
639
  var BookmarksRequestMessageSchema = z3.object({
@@ -5586,12 +5659,13 @@ function sendDataResponse4(id, res, sendMessage, clientId) {
5586
5659
  }
5587
5660
 
5588
5661
  // src/handlers/user-prompt-suggestions.ts
5589
- async function handleUserPromptSuggestions(data, components, sendMessage) {
5662
+ async function handleUserPromptSuggestions(data, components, sendMessage, collections, userId) {
5590
5663
  try {
5591
5664
  const request = UserPromptSuggestionsMessageSchema.parse(data);
5592
5665
  const { id, payload, from } = request;
5593
- const { prompt, limit = 5 } = payload;
5666
+ const { prompt, limit = 5, similarityThreshold = 0.1 } = payload;
5594
5667
  const wsId = from.id;
5668
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Processing user prompt suggestions: ${prompt}`);
5595
5669
  if (!prompt || prompt.trim().length === 0) {
5596
5670
  sendResponse(id, {
5597
5671
  success: false,
@@ -5599,7 +5673,79 @@ async function handleUserPromptSuggestions(data, components, sendMessage) {
5599
5673
  }, sendMessage, wsId);
5600
5674
  return;
5601
5675
  }
5676
+ const componentSearchHandler = collections?.["components"]?.["search"];
5677
+ const bookmarkSearchHandler = collections?.["bookmarks"]?.["search"];
5678
+ let componentSuggestions = [];
5679
+ let bookmarkSuggestions = [];
5680
+ let useEmbeddingSearch = false;
5681
+ const searchPromises = [];
5682
+ if (componentSearchHandler) {
5683
+ searchPromises.push(
5684
+ (async () => {
5685
+ try {
5686
+ logger.info("Using embedding-based search for components");
5687
+ const result = await componentSearchHandler({ prompt, limit });
5688
+ if (result.success && result.suggestions) {
5689
+ componentSuggestions = result.suggestions.map((s) => ({
5690
+ ...s,
5691
+ suggestionType: "component"
5692
+ }));
5693
+ useEmbeddingSearch = true;
5694
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Found ${componentSuggestions.length} component suggestions`);
5695
+ }
5696
+ } catch (embeddingError) {
5697
+ logger.warn("Component embedding search failed:", embeddingError);
5698
+ }
5699
+ })()
5700
+ );
5701
+ }
5702
+ if (bookmarkSearchHandler && userId && userId !== "anonymous") {
5703
+ searchPromises.push(
5704
+ (async () => {
5705
+ try {
5706
+ logger.info(`Using embedding-based search for bookmarks (user: ${userId})`);
5707
+ const result = await bookmarkSearchHandler({ prompt, userId, limit });
5708
+ if (result.success && result.suggestions) {
5709
+ bookmarkSuggestions = result.suggestions.map((s) => ({
5710
+ ...s,
5711
+ suggestionType: "bookmark"
5712
+ }));
5713
+ useEmbeddingSearch = true;
5714
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Found ${bookmarkSuggestions.length} bookmark suggestions`);
5715
+ }
5716
+ } catch (embeddingError) {
5717
+ logger.warn("Bookmark embedding search failed:", embeddingError);
5718
+ }
5719
+ })()
5720
+ );
5721
+ }
5722
+ if (searchPromises.length > 0) {
5723
+ await Promise.all(searchPromises);
5724
+ }
5725
+ if (useEmbeddingSearch && (componentSuggestions.length > 0 || bookmarkSuggestions.length > 0)) {
5726
+ const filteredComponentSuggestions = componentSuggestions.filter(
5727
+ (s) => (s.similarity || 0) >= similarityThreshold
5728
+ );
5729
+ const filteredBookmarkSuggestions = bookmarkSuggestions.filter(
5730
+ (s) => (s.similarity || 0) >= similarityThreshold
5731
+ );
5732
+ const allSuggestions = [...filteredComponentSuggestions, ...filteredBookmarkSuggestions].sort((a, b) => (b.similarity || 0) - (a.similarity || 0)).slice(0, limit);
5733
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Filtered by threshold ${similarityThreshold}: ${componentSuggestions.length} -> ${filteredComponentSuggestions.length} components, ${bookmarkSuggestions.length} -> ${filteredBookmarkSuggestions.length} bookmarks`);
5734
+ sendResponse(id, {
5735
+ success: true,
5736
+ data: {
5737
+ prompt,
5738
+ suggestions: allSuggestions,
5739
+ count: allSuggestions.length,
5740
+ componentCount: filteredComponentSuggestions.length,
5741
+ bookmarkCount: filteredBookmarkSuggestions.length,
5742
+ message: `Found ${allSuggestions.length} suggestions (${filteredComponentSuggestions.length} components, ${filteredBookmarkSuggestions.length} bookmarks)`
5743
+ }
5744
+ }, sendMessage, wsId);
5745
+ return;
5746
+ }
5602
5747
  const displayComponents = components.filter((c) => c.isDisplayComp === true);
5748
+ logger.info(`[USER_PROMPT_SUGGESTIONS_REQ ${id}] Using token-based approach. Display components: ${displayComponents.length}`);
5603
5749
  if (!displayComponents || displayComponents.length === 0) {
5604
5750
  sendResponse(id, {
5605
5751
  success: true,
@@ -5937,10 +6083,10 @@ function sendResponse2(id, res, sendMessage, clientId) {
5937
6083
  }
5938
6084
 
5939
6085
  // src/handlers/components-list-response.ts
5940
- async function handleComponentListResponse(data, storeComponents) {
6086
+ async function handleComponentListResponse(data, storeComponents, collections) {
5941
6087
  try {
5942
6088
  const componentListResponse = ComponentListResponseMessageSchema.parse(data);
5943
- const { id, payload } = componentListResponse;
6089
+ const { payload } = componentListResponse;
5944
6090
  const componentsList = payload.components;
5945
6091
  if (!componentsList) {
5946
6092
  logger.error("Components list not found in the response");
@@ -5948,6 +6094,20 @@ async function handleComponentListResponse(data, storeComponents) {
5948
6094
  }
5949
6095
  const components = ComponentsSchema.parse(componentsList);
5950
6096
  storeComponents(components);
6097
+ const embedHandler = collections?.["components"]?.["embed"];
6098
+ if (embedHandler) {
6099
+ try {
6100
+ logger.info("Embedding display components for semantic search...");
6101
+ const result = await embedHandler({ components });
6102
+ if (result.success) {
6103
+ logger.info(`Successfully embedded ${result.count} display components`);
6104
+ } else {
6105
+ logger.warn("Failed to embed components:", result.error);
6106
+ }
6107
+ } catch (embedError) {
6108
+ logger.warn("Failed to embed components:", embedError);
6109
+ }
6110
+ }
5951
6111
  return;
5952
6112
  } catch (error) {
5953
6113
  logger.error("Failed to handle user prompt request:", error);
@@ -5965,7 +6125,7 @@ async function handleUsersRequest(data, sendMessage) {
5965
6125
  const password = requestData?.password;
5966
6126
  const fullname = requestData?.fullname;
5967
6127
  const role = requestData?.role;
5968
- if (from.type !== "admin") {
6128
+ if (from.type !== "admin" && operation !== "getOne" && operation !== "getAll") {
5969
6129
  sendResponse3(id, {
5970
6130
  success: false,
5971
6131
  error: "Unauthorized: Only admin can manage users"
@@ -6252,13 +6412,29 @@ function getDashboardManager() {
6252
6412
  }
6253
6413
 
6254
6414
  // src/handlers/dashboards.ts
6255
- async function handleDashboardsRequest(data, sendMessage) {
6415
+ async function handleDashboardsRequest(data, collections, sendMessage) {
6416
+ const executeCollection = async (collection, op, params) => {
6417
+ const handler = collections[collection]?.[op];
6418
+ if (!handler) {
6419
+ return null;
6420
+ }
6421
+ return await handler(params);
6422
+ };
6256
6423
  try {
6257
6424
  const request = DashboardsRequestMessageSchema.parse(data);
6258
6425
  const { id, payload, from } = request;
6259
6426
  const { operation, data: requestData } = payload;
6260
6427
  const dashboardId = requestData?.dashboardId;
6261
6428
  const dashboard = requestData?.dashboard;
6429
+ const projectId = requestData?.projectId;
6430
+ const name = requestData?.name;
6431
+ const description = requestData?.description;
6432
+ const createdBy = requestData?.createdBy;
6433
+ const updatedBy = requestData?.updatedBy;
6434
+ const numericId = requestData?.id;
6435
+ const filters = requestData?.filters;
6436
+ const limit = requestData?.limit;
6437
+ const sort = requestData?.sort;
6262
6438
  if (from.type !== "admin") {
6263
6439
  sendResponse4(id, {
6264
6440
  success: false,
@@ -6270,19 +6446,22 @@ async function handleDashboardsRequest(data, sendMessage) {
6270
6446
  const dashboardManager2 = getDashboardManager();
6271
6447
  switch (operation) {
6272
6448
  case "create":
6273
- await handleCreate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, from.id);
6449
+ await handleCreate2(id, dashboardId, dashboard, projectId, name, description, createdBy, executeCollection, dashboardManager2, sendMessage, from.id);
6274
6450
  break;
6275
6451
  case "update":
6276
- await handleUpdate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, from.id);
6452
+ await handleUpdate2(id, numericId, dashboardId, dashboard, name, description, updatedBy, executeCollection, dashboardManager2, sendMessage, from.id);
6277
6453
  break;
6278
6454
  case "delete":
6279
- await handleDelete2(id, dashboardId, dashboardManager2, sendMessage, from.id);
6455
+ await handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, from.id);
6280
6456
  break;
6281
6457
  case "getAll":
6282
- await handleGetAll2(id, dashboardManager2, sendMessage, from.id);
6458
+ await handleGetAll2(id, executeCollection, dashboardManager2, sendMessage, from.id);
6283
6459
  break;
6284
6460
  case "getOne":
6285
- await handleGetOne2(id, dashboardId, dashboardManager2, sendMessage, from.id);
6461
+ await handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, from.id);
6462
+ break;
6463
+ case "query":
6464
+ await handleQuery(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, from.id);
6286
6465
  break;
6287
6466
  default:
6288
6467
  sendResponse4(id, {
@@ -6298,7 +6477,7 @@ async function handleDashboardsRequest(data, sendMessage) {
6298
6477
  }, sendMessage);
6299
6478
  }
6300
6479
  }
6301
- async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, clientId) {
6480
+ async function handleCreate2(id, dashboardId, dashboard, projectId, name, description, createdBy, executeCollection, dashboardManager2, sendMessage, clientId) {
6302
6481
  if (!dashboardId || dashboardId.trim().length === 0) {
6303
6482
  sendResponse4(id, {
6304
6483
  success: false,
@@ -6306,21 +6485,50 @@ async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, send
6306
6485
  }, sendMessage, clientId);
6307
6486
  return;
6308
6487
  }
6309
- if (!dashboard) {
6488
+ if (!projectId) {
6310
6489
  sendResponse4(id, {
6311
6490
  success: false,
6312
- error: "Dashboard data is required"
6491
+ error: "Project ID is required"
6313
6492
  }, sendMessage, clientId);
6314
6493
  return;
6315
6494
  }
6316
6495
  try {
6496
+ const result = await executeCollection("dashboards", "create", {
6497
+ dashboardId,
6498
+ projectId,
6499
+ name: name || "",
6500
+ description,
6501
+ dashboard,
6502
+ createdBy
6503
+ });
6504
+ if (result && result.success) {
6505
+ logger.info(`[DB] Dashboard created successfully, ID: ${result.data?.id}`);
6506
+ sendResponse4(id, {
6507
+ success: true,
6508
+ data: {
6509
+ id: result.data?.id,
6510
+ dashboardId: result.data?.dashboardId,
6511
+ dashboard: result.data?.dashboard || dashboard,
6512
+ message: `Dashboard created successfully (DB)`
6513
+ }
6514
+ }, sendMessage, clientId);
6515
+ return;
6516
+ }
6517
+ } catch (dbError) {
6518
+ logger.warn(`[DB] Failed to create dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6519
+ }
6520
+ try {
6521
+ if (!dashboard) {
6522
+ dashboard = {};
6523
+ }
6317
6524
  const createdDashboard = dashboardManager2.createDashboard(dashboardId, dashboard);
6525
+ logger.info(`[FILE] Dashboard '${dashboardId}' created successfully`);
6318
6526
  sendResponse4(id, {
6319
6527
  success: true,
6320
6528
  data: {
6321
6529
  dashboardId,
6322
6530
  dashboard: createdDashboard,
6323
- message: `Dashboard '${dashboardId}' created successfully`
6531
+ message: `Dashboard '${dashboardId}' created successfully (File)`
6324
6532
  }
6325
6533
  }, sendMessage, clientId);
6326
6534
  } catch (error) {
@@ -6330,36 +6538,56 @@ async function handleCreate2(id, dashboardId, dashboard, dashboardManager2, send
6330
6538
  }, sendMessage, clientId);
6331
6539
  }
6332
6540
  }
6333
- async function handleUpdate2(id, dashboardId, dashboard, dashboardManager2, sendMessage, clientId) {
6334
- if (!dashboardId || dashboardId.trim().length === 0) {
6541
+ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, description, updatedBy, executeCollection, dashboardManager2, sendMessage, clientId) {
6542
+ if (!numericId) {
6335
6543
  sendResponse4(id, {
6336
6544
  success: false,
6337
- error: "Dashboard ID is required and cannot be empty"
6545
+ error: "Dashboard ID is required"
6338
6546
  }, sendMessage, clientId);
6339
6547
  return;
6340
6548
  }
6341
- if (!dashboard) {
6342
- sendResponse4(id, {
6343
- success: false,
6344
- error: "Dashboard data is required"
6345
- }, sendMessage, clientId);
6346
- return;
6549
+ try {
6550
+ const result = await executeCollection("dashboards", "update", {
6551
+ id: numericId,
6552
+ name,
6553
+ description,
6554
+ dashboard,
6555
+ updatedBy
6556
+ });
6557
+ if (result && result.success) {
6558
+ logger.info(`[DB] Dashboard updated successfully, ID: ${numericId}`);
6559
+ sendResponse4(id, {
6560
+ success: true,
6561
+ data: {
6562
+ id: numericId,
6563
+ dashboardId: result.data?.dashboardId,
6564
+ dashboard: result.data?.dashboard || dashboard,
6565
+ message: `Dashboard updated successfully (DB)`
6566
+ }
6567
+ }, sendMessage, clientId);
6568
+ return;
6569
+ }
6570
+ } catch (dbError) {
6571
+ logger.warn(`[DB] Failed to update dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6347
6572
  }
6573
+ const fileStorageId = dashboardId || String(numericId);
6348
6574
  try {
6349
- const updatedDashboard = dashboardManager2.updateDashboard(dashboardId, dashboard);
6575
+ const updatedDashboard = dashboardManager2.updateDashboard(fileStorageId, dashboard);
6350
6576
  if (!updatedDashboard) {
6351
6577
  sendResponse4(id, {
6352
6578
  success: false,
6353
- error: `Dashboard '${dashboardId}' not found`
6579
+ error: `Dashboard '${fileStorageId}' not found`
6354
6580
  }, sendMessage, clientId);
6355
6581
  return;
6356
6582
  }
6583
+ logger.info(`[FILE] Dashboard '${fileStorageId}' updated successfully`);
6357
6584
  sendResponse4(id, {
6358
6585
  success: true,
6359
6586
  data: {
6360
- dashboardId,
6587
+ id: numericId,
6588
+ dashboardId: fileStorageId,
6361
6589
  dashboard: updatedDashboard,
6362
- message: `Dashboard '${dashboardId}' updated successfully`
6590
+ message: `Dashboard '${fileStorageId}' updated successfully (File)`
6363
6591
  }
6364
6592
  }, sendMessage, clientId);
6365
6593
  } catch (error) {
@@ -6369,65 +6597,154 @@ async function handleUpdate2(id, dashboardId, dashboard, dashboardManager2, send
6369
6597
  }, sendMessage, clientId);
6370
6598
  }
6371
6599
  }
6372
- async function handleDelete2(id, dashboardId, dashboardManager2, sendMessage, clientId) {
6373
- if (!dashboardId || dashboardId.trim().length === 0) {
6600
+ async function handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
6601
+ if (!numericId) {
6374
6602
  sendResponse4(id, {
6375
6603
  success: false,
6376
- error: "Dashboard ID is required and cannot be empty"
6604
+ error: "Dashboard ID is required"
6377
6605
  }, sendMessage, clientId);
6378
6606
  return;
6379
6607
  }
6380
- const deleted = dashboardManager2.deleteDashboard(dashboardId);
6608
+ try {
6609
+ const result = await executeCollection("dashboards", "delete", { id: numericId });
6610
+ if (result && result.success) {
6611
+ logger.info(`[DB] Dashboard deleted successfully, ID: ${numericId}`);
6612
+ sendResponse4(id, {
6613
+ success: true,
6614
+ data: {
6615
+ id: numericId,
6616
+ message: `Dashboard deleted successfully (DB)`
6617
+ }
6618
+ }, sendMessage, clientId);
6619
+ return;
6620
+ }
6621
+ } catch (dbError) {
6622
+ logger.warn(`[DB] Failed to delete dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6623
+ }
6624
+ const fileStorageId = dashboardId || String(numericId);
6625
+ const deleted = dashboardManager2.deleteDashboard(fileStorageId);
6381
6626
  if (!deleted) {
6382
6627
  sendResponse4(id, {
6383
6628
  success: false,
6384
- error: `Dashboard '${dashboardId}' not found`
6629
+ error: `Dashboard '${fileStorageId}' not found`
6385
6630
  }, sendMessage, clientId);
6386
6631
  return;
6387
6632
  }
6633
+ logger.info(`[FILE] Dashboard '${fileStorageId}' deleted successfully`);
6388
6634
  sendResponse4(id, {
6389
6635
  success: true,
6390
6636
  data: {
6391
- dashboardId,
6392
- message: `Dashboard '${dashboardId}' deleted successfully`
6637
+ id: numericId,
6638
+ dashboardId: fileStorageId,
6639
+ message: `Dashboard '${fileStorageId}' deleted successfully (File)`
6393
6640
  }
6394
6641
  }, sendMessage, clientId);
6395
6642
  }
6396
- async function handleGetAll2(id, dashboardManager2, sendMessage, clientId) {
6643
+ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessage, clientId) {
6644
+ try {
6645
+ const result = await executeCollection("dashboards", "getAll", {});
6646
+ if (result && result.success) {
6647
+ logger.info(`[DB] Retrieved ${result.count} dashboards`);
6648
+ sendResponse4(id, {
6649
+ success: true,
6650
+ data: {
6651
+ dashboards: result.data,
6652
+ count: result.count,
6653
+ message: `Retrieved ${result.count} dashboards (DB)`
6654
+ }
6655
+ }, sendMessage, clientId);
6656
+ return;
6657
+ }
6658
+ } catch (dbError) {
6659
+ logger.warn(`[DB] Failed to get all dashboards, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6660
+ }
6397
6661
  const dashboards = dashboardManager2.getAllDashboards();
6398
- logger.info(`Admin retrieved all dashboards (count: ${dashboards.length})`);
6662
+ logger.info(`[FILE] Retrieved ${dashboards.length} dashboards`);
6399
6663
  sendResponse4(id, {
6400
6664
  success: true,
6401
6665
  data: {
6402
6666
  dashboards,
6403
6667
  count: dashboards.length,
6404
- message: `Retrieved ${dashboards.length} dashboards`
6668
+ message: `Retrieved ${dashboards.length} dashboards (File)`
6405
6669
  }
6406
6670
  }, sendMessage, clientId);
6407
6671
  }
6408
- async function handleGetOne2(id, dashboardId, dashboardManager2, sendMessage, clientId) {
6409
- if (!dashboardId || dashboardId.trim().length === 0) {
6672
+ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
6673
+ if (!numericId) {
6410
6674
  sendResponse4(id, {
6411
6675
  success: false,
6412
- error: "Dashboard ID is required and cannot be empty"
6676
+ error: "Dashboard ID is required"
6413
6677
  }, sendMessage, clientId);
6414
6678
  return;
6415
6679
  }
6416
- const dashboard = dashboardManager2.getDashboard(dashboardId);
6680
+ try {
6681
+ const result = await executeCollection("dashboards", "getOne", { id: numericId });
6682
+ if (result && result.success) {
6683
+ logger.info(`[DB] Retrieved dashboard ID: ${numericId}`);
6684
+ sendResponse4(id, {
6685
+ success: true,
6686
+ data: {
6687
+ id: numericId,
6688
+ dashboardId: result.data?.dashboardId,
6689
+ dashboard: result.data?.dashboard || result.data,
6690
+ message: `Retrieved dashboard (DB)`
6691
+ }
6692
+ }, sendMessage, clientId);
6693
+ return;
6694
+ }
6695
+ } catch (dbError) {
6696
+ logger.warn(`[DB] Failed to get dashboard, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6697
+ }
6698
+ const fileStorageId = dashboardId || String(numericId);
6699
+ const dashboard = dashboardManager2.getDashboard(fileStorageId);
6417
6700
  if (!dashboard) {
6418
6701
  sendResponse4(id, {
6419
6702
  success: false,
6420
- error: `Dashboard '${dashboardId}' not found`
6703
+ error: `Dashboard '${fileStorageId}' not found`
6421
6704
  }, sendMessage, clientId);
6422
6705
  return;
6423
6706
  }
6424
- logger.info(`Admin retrieved dashboard: ${dashboardId}`);
6707
+ logger.info(`[FILE] Retrieved dashboard: ${fileStorageId}`);
6425
6708
  sendResponse4(id, {
6426
6709
  success: true,
6427
6710
  data: {
6428
- dashboardId,
6711
+ id: numericId,
6712
+ dashboardId: fileStorageId,
6429
6713
  dashboard,
6430
- message: `Retrieved dashboard '${dashboardId}'`
6714
+ message: `Retrieved dashboard '${fileStorageId}' (File)`
6715
+ }
6716
+ }, sendMessage, clientId);
6717
+ }
6718
+ async function handleQuery(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, clientId) {
6719
+ try {
6720
+ const result = await executeCollection("dashboards", "query", {
6721
+ filters: filters || {},
6722
+ limit,
6723
+ sort
6724
+ });
6725
+ if (result && result.success) {
6726
+ logger.info(`[DB] Query returned ${result.count} dashboards`);
6727
+ sendResponse4(id, {
6728
+ success: true,
6729
+ data: {
6730
+ dashboards: result.data,
6731
+ count: result.count,
6732
+ message: `Query returned ${result.count} dashboards (DB)`
6733
+ }
6734
+ }, sendMessage, clientId);
6735
+ return;
6736
+ }
6737
+ } catch (dbError) {
6738
+ logger.warn(`[DB] Failed to query dashboards: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6739
+ }
6740
+ const dashboards = dashboardManager2.getAllDashboards();
6741
+ logger.info(`[FILE] Retrieved ${dashboards.length} dashboards (all - no query filter)`);
6742
+ sendResponse4(id, {
6743
+ success: true,
6744
+ data: {
6745
+ dashboards,
6746
+ count: dashboards.length,
6747
+ message: `Retrieved ${dashboards.length} dashboards (File - no query filter)`
6431
6748
  }
6432
6749
  }, sendMessage, clientId);
6433
6750
  }
@@ -6460,13 +6777,29 @@ function setReportManager(manager) {
6460
6777
  }
6461
6778
 
6462
6779
  // src/handlers/reports.ts
6463
- async function handleReportsRequest(data, sendMessage) {
6780
+ async function handleReportsRequest(data, collections, sendMessage) {
6781
+ const executeCollection = async (collection, op, params) => {
6782
+ const handler = collections[collection]?.[op];
6783
+ if (!handler) {
6784
+ return null;
6785
+ }
6786
+ return await handler(params);
6787
+ };
6464
6788
  try {
6465
6789
  const request = ReportsRequestMessageSchema.parse(data);
6466
6790
  const { id, payload, from } = request;
6467
6791
  const { operation, data: requestData } = payload;
6468
6792
  const reportId = requestData?.reportId;
6469
6793
  const report = requestData?.report;
6794
+ const projectId = requestData?.projectId;
6795
+ const name = requestData?.name;
6796
+ const description = requestData?.description;
6797
+ const createdBy = requestData?.createdBy;
6798
+ const updatedBy = requestData?.updatedBy;
6799
+ const numericId = requestData?.id;
6800
+ const filters = requestData?.filters;
6801
+ const limit = requestData?.limit;
6802
+ const sort = requestData?.sort;
6470
6803
  if (from.type !== "admin") {
6471
6804
  sendResponse5(id, {
6472
6805
  success: false,
@@ -6478,19 +6811,22 @@ async function handleReportsRequest(data, sendMessage) {
6478
6811
  const reportManager2 = getReportManager();
6479
6812
  switch (operation) {
6480
6813
  case "create":
6481
- await handleCreate3(id, reportId, report, reportManager2, sendMessage, from.id);
6814
+ await handleCreate3(id, reportId, report, projectId, name, description, createdBy, executeCollection, reportManager2, sendMessage, from.id);
6482
6815
  break;
6483
6816
  case "update":
6484
- await handleUpdate3(id, reportId, report, reportManager2, sendMessage, from.id);
6817
+ await handleUpdate3(id, numericId, reportId, report, name, description, updatedBy, executeCollection, reportManager2, sendMessage, from.id);
6485
6818
  break;
6486
6819
  case "delete":
6487
- await handleDelete3(id, reportId, reportManager2, sendMessage, from.id);
6820
+ await handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, from.id);
6488
6821
  break;
6489
6822
  case "getAll":
6490
- await handleGetAll3(id, reportManager2, sendMessage, from.id);
6823
+ await handleGetAll3(id, executeCollection, reportManager2, sendMessage, from.id);
6491
6824
  break;
6492
6825
  case "getOne":
6493
- await handleGetOne3(id, reportId, reportManager2, sendMessage, from.id);
6826
+ await handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, from.id);
6827
+ break;
6828
+ case "query":
6829
+ await handleQuery2(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, from.id);
6494
6830
  break;
6495
6831
  default:
6496
6832
  sendResponse5(id, {
@@ -6506,7 +6842,7 @@ async function handleReportsRequest(data, sendMessage) {
6506
6842
  }, sendMessage);
6507
6843
  }
6508
6844
  }
6509
- async function handleCreate3(id, reportId, report, reportManager2, sendMessage, clientId) {
6845
+ async function handleCreate3(id, reportId, report, projectId, name, description, createdBy, executeCollection, reportManager2, sendMessage, clientId) {
6510
6846
  if (!reportId || reportId.trim().length === 0) {
6511
6847
  sendResponse5(id, {
6512
6848
  success: false,
@@ -6514,21 +6850,50 @@ async function handleCreate3(id, reportId, report, reportManager2, sendMessage,
6514
6850
  }, sendMessage, clientId);
6515
6851
  return;
6516
6852
  }
6517
- if (!report) {
6853
+ if (!projectId) {
6518
6854
  sendResponse5(id, {
6519
6855
  success: false,
6520
- error: "Report data is required"
6856
+ error: "Project ID is required"
6521
6857
  }, sendMessage, clientId);
6522
6858
  return;
6523
6859
  }
6524
6860
  try {
6861
+ const result = await executeCollection("reports", "create", {
6862
+ reportId,
6863
+ projectId,
6864
+ name: name || "",
6865
+ description,
6866
+ report,
6867
+ createdBy
6868
+ });
6869
+ if (result && result.success) {
6870
+ logger.info(`[DB] Report created successfully, ID: ${result.data?.id}`);
6871
+ sendResponse5(id, {
6872
+ success: true,
6873
+ data: {
6874
+ id: result.data?.id,
6875
+ reportId: result.data?.reportId,
6876
+ report: result.data?.report || report,
6877
+ message: `Report created successfully (DB)`
6878
+ }
6879
+ }, sendMessage, clientId);
6880
+ return;
6881
+ }
6882
+ } catch (dbError) {
6883
+ logger.warn(`[DB] Failed to create report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6884
+ }
6885
+ try {
6886
+ if (!report) {
6887
+ report = {};
6888
+ }
6525
6889
  const createdReport = reportManager2.createReport(reportId, report);
6890
+ logger.info(`[FILE] Report '${reportId}' created successfully`);
6526
6891
  sendResponse5(id, {
6527
6892
  success: true,
6528
6893
  data: {
6529
6894
  reportId,
6530
6895
  report: createdReport,
6531
- message: `Report '${reportId}' created successfully`
6896
+ message: `Report '${reportId}' created successfully (File)`
6532
6897
  }
6533
6898
  }, sendMessage, clientId);
6534
6899
  } catch (error) {
@@ -6538,36 +6903,56 @@ async function handleCreate3(id, reportId, report, reportManager2, sendMessage,
6538
6903
  }, sendMessage, clientId);
6539
6904
  }
6540
6905
  }
6541
- async function handleUpdate3(id, reportId, report, reportManager2, sendMessage, clientId) {
6542
- if (!reportId || reportId.trim().length === 0) {
6906
+ async function handleUpdate3(id, numericId, reportId, report, name, description, updatedBy, executeCollection, reportManager2, sendMessage, clientId) {
6907
+ if (!numericId) {
6543
6908
  sendResponse5(id, {
6544
6909
  success: false,
6545
- error: "Report ID is required and cannot be empty"
6910
+ error: "Report ID is required"
6546
6911
  }, sendMessage, clientId);
6547
6912
  return;
6548
6913
  }
6549
- if (!report) {
6550
- sendResponse5(id, {
6551
- success: false,
6552
- error: "Report data is required"
6553
- }, sendMessage, clientId);
6554
- return;
6914
+ try {
6915
+ const result = await executeCollection("reports", "update", {
6916
+ id: numericId,
6917
+ name,
6918
+ description,
6919
+ report,
6920
+ updatedBy
6921
+ });
6922
+ if (result && result.success) {
6923
+ logger.info(`[DB] Report updated successfully, ID: ${numericId}`);
6924
+ sendResponse5(id, {
6925
+ success: true,
6926
+ data: {
6927
+ id: numericId,
6928
+ reportId: result.data?.reportId,
6929
+ report: result.data?.report || report,
6930
+ message: `Report updated successfully (DB)`
6931
+ }
6932
+ }, sendMessage, clientId);
6933
+ return;
6934
+ }
6935
+ } catch (dbError) {
6936
+ logger.warn(`[DB] Failed to update report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6555
6937
  }
6938
+ const fileStorageId = reportId || String(numericId);
6556
6939
  try {
6557
- const updatedReport = reportManager2.updateReport(reportId, report);
6940
+ const updatedReport = reportManager2.updateReport(fileStorageId, report);
6558
6941
  if (!updatedReport) {
6559
6942
  sendResponse5(id, {
6560
6943
  success: false,
6561
- error: `Report '${reportId}' not found`
6944
+ error: `Report '${fileStorageId}' not found`
6562
6945
  }, sendMessage, clientId);
6563
6946
  return;
6564
6947
  }
6948
+ logger.info(`[FILE] Report '${fileStorageId}' updated successfully`);
6565
6949
  sendResponse5(id, {
6566
6950
  success: true,
6567
6951
  data: {
6568
- reportId,
6952
+ id: numericId,
6953
+ reportId: fileStorageId,
6569
6954
  report: updatedReport,
6570
- message: `Report '${reportId}' updated successfully`
6955
+ message: `Report '${fileStorageId}' updated successfully (File)`
6571
6956
  }
6572
6957
  }, sendMessage, clientId);
6573
6958
  } catch (error) {
@@ -6577,65 +6962,154 @@ async function handleUpdate3(id, reportId, report, reportManager2, sendMessage,
6577
6962
  }, sendMessage, clientId);
6578
6963
  }
6579
6964
  }
6580
- async function handleDelete3(id, reportId, reportManager2, sendMessage, clientId) {
6581
- if (!reportId || reportId.trim().length === 0) {
6965
+ async function handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
6966
+ if (!numericId) {
6582
6967
  sendResponse5(id, {
6583
6968
  success: false,
6584
- error: "Report ID is required and cannot be empty"
6969
+ error: "Report ID is required"
6585
6970
  }, sendMessage, clientId);
6586
6971
  return;
6587
6972
  }
6588
- const deleted = reportManager2.deleteReport(reportId);
6973
+ try {
6974
+ const result = await executeCollection("reports", "delete", { id: numericId });
6975
+ if (result && result.success) {
6976
+ logger.info(`[DB] Report deleted successfully, ID: ${numericId}`);
6977
+ sendResponse5(id, {
6978
+ success: true,
6979
+ data: {
6980
+ id: numericId,
6981
+ message: `Report deleted successfully (DB)`
6982
+ }
6983
+ }, sendMessage, clientId);
6984
+ return;
6985
+ }
6986
+ } catch (dbError) {
6987
+ logger.warn(`[DB] Failed to delete report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
6988
+ }
6989
+ const fileStorageId = reportId || String(numericId);
6990
+ const deleted = reportManager2.deleteReport(fileStorageId);
6589
6991
  if (!deleted) {
6590
6992
  sendResponse5(id, {
6591
6993
  success: false,
6592
- error: `Report '${reportId}' not found`
6994
+ error: `Report '${fileStorageId}' not found`
6593
6995
  }, sendMessage, clientId);
6594
6996
  return;
6595
6997
  }
6998
+ logger.info(`[FILE] Report '${fileStorageId}' deleted successfully`);
6596
6999
  sendResponse5(id, {
6597
7000
  success: true,
6598
7001
  data: {
6599
- reportId,
6600
- message: `Report '${reportId}' deleted successfully`
7002
+ id: numericId,
7003
+ reportId: fileStorageId,
7004
+ message: `Report '${fileStorageId}' deleted successfully (File)`
6601
7005
  }
6602
7006
  }, sendMessage, clientId);
6603
7007
  }
6604
- async function handleGetAll3(id, reportManager2, sendMessage, clientId) {
7008
+ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage, clientId) {
7009
+ try {
7010
+ const result = await executeCollection("reports", "getAll", {});
7011
+ if (result && result.success) {
7012
+ logger.info(`[DB] Retrieved ${result.count} reports`);
7013
+ sendResponse5(id, {
7014
+ success: true,
7015
+ data: {
7016
+ reports: result.data,
7017
+ count: result.count,
7018
+ message: `Retrieved ${result.count} reports (DB)`
7019
+ }
7020
+ }, sendMessage, clientId);
7021
+ return;
7022
+ }
7023
+ } catch (dbError) {
7024
+ logger.warn(`[DB] Failed to get all reports, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7025
+ }
6605
7026
  const reports = reportManager2.getAllReports();
6606
- logger.info(`Admin retrieved all reports (count: ${reports.length})`);
7027
+ logger.info(`[FILE] Retrieved ${reports.length} reports`);
6607
7028
  sendResponse5(id, {
6608
7029
  success: true,
6609
7030
  data: {
6610
7031
  reports,
6611
7032
  count: reports.length,
6612
- message: `Retrieved ${reports.length} reports`
7033
+ message: `Retrieved ${reports.length} reports (File)`
6613
7034
  }
6614
7035
  }, sendMessage, clientId);
6615
7036
  }
6616
- async function handleGetOne3(id, reportId, reportManager2, sendMessage, clientId) {
6617
- if (!reportId || reportId.trim().length === 0) {
7037
+ async function handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
7038
+ if (!numericId) {
6618
7039
  sendResponse5(id, {
6619
7040
  success: false,
6620
- error: "Report ID is required and cannot be empty"
7041
+ error: "Report ID is required"
6621
7042
  }, sendMessage, clientId);
6622
7043
  return;
6623
7044
  }
6624
- const report = reportManager2.getReport(reportId);
7045
+ try {
7046
+ const result = await executeCollection("reports", "getOne", { id: numericId });
7047
+ if (result && result.success) {
7048
+ logger.info(`[DB] Retrieved report ID: ${numericId}`);
7049
+ sendResponse5(id, {
7050
+ success: true,
7051
+ data: {
7052
+ id: numericId,
7053
+ reportId: result.data?.reportId,
7054
+ report: result.data?.report || result.data,
7055
+ message: `Retrieved report (DB)`
7056
+ }
7057
+ }, sendMessage, clientId);
7058
+ return;
7059
+ }
7060
+ } catch (dbError) {
7061
+ logger.warn(`[DB] Failed to get report, falling back to file storage: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7062
+ }
7063
+ const fileStorageId = reportId || String(numericId);
7064
+ const report = reportManager2.getReport(fileStorageId);
6625
7065
  if (!report) {
6626
7066
  sendResponse5(id, {
6627
7067
  success: false,
6628
- error: `Report '${reportId}' not found`
7068
+ error: `Report '${fileStorageId}' not found`
6629
7069
  }, sendMessage, clientId);
6630
7070
  return;
6631
7071
  }
6632
- logger.info(`Admin retrieved report: ${reportId}`);
7072
+ logger.info(`[FILE] Retrieved report: ${fileStorageId}`);
6633
7073
  sendResponse5(id, {
6634
7074
  success: true,
6635
7075
  data: {
6636
- reportId,
7076
+ id: numericId,
7077
+ reportId: fileStorageId,
6637
7078
  report,
6638
- message: `Retrieved report '${reportId}'`
7079
+ message: `Retrieved report '${fileStorageId}' (File)`
7080
+ }
7081
+ }, sendMessage, clientId);
7082
+ }
7083
+ async function handleQuery2(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, clientId) {
7084
+ try {
7085
+ const result = await executeCollection("reports", "query", {
7086
+ filters: filters || {},
7087
+ limit,
7088
+ sort
7089
+ });
7090
+ if (result && result.success) {
7091
+ logger.info(`[DB] Query returned ${result.count} reports`);
7092
+ sendResponse5(id, {
7093
+ success: true,
7094
+ data: {
7095
+ reports: result.data,
7096
+ count: result.count,
7097
+ message: `Query returned ${result.count} reports (DB)`
7098
+ }
7099
+ }, sendMessage, clientId);
7100
+ return;
7101
+ }
7102
+ } catch (dbError) {
7103
+ logger.warn(`[DB] Failed to query reports: ${dbError instanceof Error ? dbError.message : "Unknown error"}`);
7104
+ }
7105
+ const reports = reportManager2.getAllReports();
7106
+ logger.info(`[FILE] Retrieved ${reports.length} reports (all - no query filter)`);
7107
+ sendResponse5(id, {
7108
+ success: true,
7109
+ data: {
7110
+ reports,
7111
+ count: reports.length,
7112
+ message: `Retrieved ${reports.length} reports (File - no query filter)`
6639
7113
  }
6640
7114
  }, sendMessage, clientId);
6641
7115
  }
@@ -6655,6 +7129,297 @@ function sendResponse5(id, res, sendMessage, clientId) {
6655
7129
  sendMessage(response);
6656
7130
  }
6657
7131
 
7132
+ // src/handlers/uis.ts
7133
+ async function handleUIsRequest(data, collections, sendMessage) {
7134
+ const executeCollection = async (collection, op, params) => {
7135
+ const handler = collections[collection]?.[op];
7136
+ if (!handler) {
7137
+ throw new Error(`Collection handler not found: ${collection}.${op}`);
7138
+ }
7139
+ return await handler(params);
7140
+ };
7141
+ try {
7142
+ const request = UIsRequestMessageSchema.parse(data);
7143
+ const { id, payload, from } = request;
7144
+ const { operation, data: requestData } = payload;
7145
+ const uiId = requestData?.uiId;
7146
+ const ui = requestData?.ui;
7147
+ const projectId = requestData?.projectId;
7148
+ const name = requestData?.name;
7149
+ const description = requestData?.description;
7150
+ const createdBy = requestData?.createdBy;
7151
+ const updatedBy = requestData?.updatedBy;
7152
+ const numericId = requestData?.id;
7153
+ const filters = requestData?.filters;
7154
+ const limit = requestData?.limit;
7155
+ const sort = requestData?.sort;
7156
+ if (from.type !== "admin") {
7157
+ sendResponse6(id, {
7158
+ success: false,
7159
+ error: "Unauthorized: Only admin can manage UIs"
7160
+ }, sendMessage, from.id);
7161
+ logger.warn(`Unauthorized UI management attempt from: ${from.type}`);
7162
+ return;
7163
+ }
7164
+ switch (operation) {
7165
+ case "create":
7166
+ await handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, from.id);
7167
+ break;
7168
+ case "update":
7169
+ await handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, from.id);
7170
+ break;
7171
+ case "delete":
7172
+ await handleDelete4(id, numericId, executeCollection, sendMessage, from.id);
7173
+ break;
7174
+ case "getAll":
7175
+ await handleGetAll4(id, executeCollection, sendMessage, from.id);
7176
+ break;
7177
+ case "getOne":
7178
+ await handleGetOne4(id, numericId, executeCollection, sendMessage, from.id);
7179
+ break;
7180
+ case "query":
7181
+ await handleQuery3(id, filters, limit, sort, executeCollection, sendMessage, from.id);
7182
+ break;
7183
+ default:
7184
+ sendResponse6(id, {
7185
+ success: false,
7186
+ error: `Unknown operation: ${operation}`
7187
+ }, sendMessage, from.id);
7188
+ }
7189
+ } catch (error) {
7190
+ logger.error("Failed to handle UIs request:", error);
7191
+ sendResponse6(null, {
7192
+ success: false,
7193
+ error: error instanceof Error ? error.message : "Unknown error occurred"
7194
+ }, sendMessage);
7195
+ }
7196
+ }
7197
+ async function handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, clientId) {
7198
+ if (!uiId || uiId.trim().length === 0) {
7199
+ sendResponse6(id, {
7200
+ success: false,
7201
+ error: "UI ID is required and cannot be empty"
7202
+ }, sendMessage, clientId);
7203
+ return;
7204
+ }
7205
+ if (!projectId || projectId.trim().length === 0) {
7206
+ sendResponse6(id, {
7207
+ success: false,
7208
+ error: "Project ID is required and cannot be empty"
7209
+ }, sendMessage, clientId);
7210
+ return;
7211
+ }
7212
+ try {
7213
+ const result = await executeCollection("uis", "create", {
7214
+ uiId,
7215
+ projectId,
7216
+ name: name || uiId,
7217
+ description,
7218
+ ui,
7219
+ createdBy
7220
+ });
7221
+ if (result && result.success) {
7222
+ logger.info(`UI created successfully, ID: ${result.data?.id}`);
7223
+ sendResponse6(id, {
7224
+ success: true,
7225
+ data: {
7226
+ id: result.data?.id,
7227
+ uiId: result.data?.uiId || uiId,
7228
+ ui: result.data?.ui || ui,
7229
+ message: `UI created successfully`
7230
+ }
7231
+ }, sendMessage, clientId);
7232
+ } else {
7233
+ sendResponse6(id, {
7234
+ success: false,
7235
+ error: "Failed to create UI"
7236
+ }, sendMessage, clientId);
7237
+ }
7238
+ } catch (error) {
7239
+ sendResponse6(id, {
7240
+ success: false,
7241
+ error: error instanceof Error ? error.message : "Failed to create UI"
7242
+ }, sendMessage, clientId);
7243
+ }
7244
+ }
7245
+ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, clientId) {
7246
+ if (!numericId) {
7247
+ sendResponse6(id, {
7248
+ success: false,
7249
+ error: "UI ID is required"
7250
+ }, sendMessage, clientId);
7251
+ return;
7252
+ }
7253
+ try {
7254
+ const result = await executeCollection("uis", "update", {
7255
+ id: numericId,
7256
+ name,
7257
+ description,
7258
+ ui,
7259
+ updatedBy
7260
+ });
7261
+ if (result && result.success) {
7262
+ logger.info(`UI updated successfully, ID: ${numericId}`);
7263
+ sendResponse6(id, {
7264
+ success: true,
7265
+ data: {
7266
+ id: numericId,
7267
+ uiId: result.data?.uiId,
7268
+ ui: result.data?.ui || ui,
7269
+ message: `UI updated successfully`
7270
+ }
7271
+ }, sendMessage, clientId);
7272
+ } else {
7273
+ sendResponse6(id, {
7274
+ success: false,
7275
+ error: "Failed to update UI"
7276
+ }, sendMessage, clientId);
7277
+ }
7278
+ } catch (error) {
7279
+ sendResponse6(id, {
7280
+ success: false,
7281
+ error: error instanceof Error ? error.message : "Failed to update UI"
7282
+ }, sendMessage, clientId);
7283
+ }
7284
+ }
7285
+ async function handleDelete4(id, numericId, executeCollection, sendMessage, clientId) {
7286
+ if (!numericId) {
7287
+ sendResponse6(id, {
7288
+ success: false,
7289
+ error: "UI ID is required"
7290
+ }, sendMessage, clientId);
7291
+ return;
7292
+ }
7293
+ try {
7294
+ const result = await executeCollection("uis", "delete", { id: numericId });
7295
+ if (result && result.success) {
7296
+ logger.info(`UI deleted successfully, ID: ${numericId}`);
7297
+ sendResponse6(id, {
7298
+ success: true,
7299
+ data: {
7300
+ id: numericId,
7301
+ message: `UI deleted successfully`
7302
+ }
7303
+ }, sendMessage, clientId);
7304
+ } else {
7305
+ sendResponse6(id, {
7306
+ success: false,
7307
+ error: "Failed to delete UI"
7308
+ }, sendMessage, clientId);
7309
+ }
7310
+ } catch (error) {
7311
+ sendResponse6(id, {
7312
+ success: false,
7313
+ error: error instanceof Error ? error.message : "Failed to delete UI"
7314
+ }, sendMessage, clientId);
7315
+ }
7316
+ }
7317
+ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
7318
+ try {
7319
+ const result = await executeCollection("uis", "getAll", {});
7320
+ if (result && result.success) {
7321
+ logger.info(`Retrieved ${result.count} UIs`);
7322
+ sendResponse6(id, {
7323
+ success: true,
7324
+ data: {
7325
+ uis: result.data,
7326
+ count: result.count,
7327
+ message: `Retrieved ${result.count} UIs`
7328
+ }
7329
+ }, sendMessage, clientId);
7330
+ } else {
7331
+ sendResponse6(id, {
7332
+ success: false,
7333
+ error: "Failed to get UIs"
7334
+ }, sendMessage, clientId);
7335
+ }
7336
+ } catch (error) {
7337
+ sendResponse6(id, {
7338
+ success: false,
7339
+ error: error instanceof Error ? error.message : "Failed to get UIs"
7340
+ }, sendMessage, clientId);
7341
+ }
7342
+ }
7343
+ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clientId) {
7344
+ if (!numericId) {
7345
+ sendResponse6(id, {
7346
+ success: false,
7347
+ error: "UI ID is required"
7348
+ }, sendMessage, clientId);
7349
+ return;
7350
+ }
7351
+ try {
7352
+ const result = await executeCollection("uis", "getOne", { id: numericId });
7353
+ if (result && result.success) {
7354
+ logger.info(`Retrieved UI ID: ${numericId}`);
7355
+ sendResponse6(id, {
7356
+ success: true,
7357
+ data: {
7358
+ id: numericId,
7359
+ uiId: result.data?.uiId,
7360
+ ui: result.data?.ui || result.data,
7361
+ message: `Retrieved UI`
7362
+ }
7363
+ }, sendMessage, clientId);
7364
+ } else {
7365
+ sendResponse6(id, {
7366
+ success: false,
7367
+ error: `UI not found`
7368
+ }, sendMessage, clientId);
7369
+ }
7370
+ } catch (error) {
7371
+ sendResponse6(id, {
7372
+ success: false,
7373
+ error: error instanceof Error ? error.message : "Failed to get UI"
7374
+ }, sendMessage, clientId);
7375
+ }
7376
+ }
7377
+ async function handleQuery3(id, filters, limit, sort, executeCollection, sendMessage, clientId) {
7378
+ try {
7379
+ const result = await executeCollection("uis", "query", {
7380
+ filters: filters || {},
7381
+ limit,
7382
+ sort
7383
+ });
7384
+ if (result && result.success) {
7385
+ logger.info(`Query returned ${result.count} UIs`);
7386
+ sendResponse6(id, {
7387
+ success: true,
7388
+ data: {
7389
+ uis: result.data,
7390
+ count: result.count,
7391
+ message: `Query returned ${result.count} UIs`
7392
+ }
7393
+ }, sendMessage, clientId);
7394
+ } else {
7395
+ sendResponse6(id, {
7396
+ success: false,
7397
+ error: "Failed to query UIs"
7398
+ }, sendMessage, clientId);
7399
+ }
7400
+ } catch (error) {
7401
+ sendResponse6(id, {
7402
+ success: false,
7403
+ error: error instanceof Error ? error.message : "Failed to query UIs"
7404
+ }, sendMessage, clientId);
7405
+ }
7406
+ }
7407
+ function sendResponse6(id, res, sendMessage, clientId) {
7408
+ const response = {
7409
+ id: id || "unknown",
7410
+ type: "UIS_RES",
7411
+ from: { type: "data-agent" },
7412
+ to: {
7413
+ type: "admin",
7414
+ id: clientId
7415
+ },
7416
+ payload: {
7417
+ ...res
7418
+ }
7419
+ };
7420
+ sendMessage(response);
7421
+ }
7422
+
6658
7423
  // src/handlers/bookmarks.ts
6659
7424
  async function handleBookmarksRequest(data, collections, sendMessage) {
6660
7425
  const executeCollection = async (collection, op, params) => {
@@ -6671,22 +7436,24 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
6671
7436
  const bookmarkId = requestData?.id;
6672
7437
  const userId = requestData?.userId;
6673
7438
  const threadId = requestData?.threadId;
7439
+ const name = requestData?.name;
7440
+ const description = requestData?.description;
6674
7441
  const uiblock = requestData?.uiblock;
6675
7442
  switch (operation) {
6676
7443
  case "create":
6677
- await handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, from.id);
7444
+ await handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, from.id);
6678
7445
  break;
6679
7446
  case "update":
6680
- await handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, from.id);
7447
+ await handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, from.id);
6681
7448
  break;
6682
7449
  case "delete":
6683
- await handleDelete4(id, bookmarkId, executeCollection, sendMessage, from.id);
7450
+ await handleDelete5(id, bookmarkId, executeCollection, sendMessage, from.id);
6684
7451
  break;
6685
7452
  case "getAll":
6686
- await handleGetAll4(id, executeCollection, sendMessage, from.id);
7453
+ await handleGetAll5(id, executeCollection, sendMessage, from.id);
6687
7454
  break;
6688
7455
  case "getOne":
6689
- await handleGetOne4(id, bookmarkId, executeCollection, sendMessage, from.id);
7456
+ await handleGetOne5(id, bookmarkId, executeCollection, sendMessage, from.id);
6690
7457
  break;
6691
7458
  case "getByUser":
6692
7459
  await handleGetByUser(id, userId, threadId, executeCollection, sendMessage, from.id);
@@ -6695,82 +7462,75 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
6695
7462
  await handleGetByThread(id, threadId, executeCollection, sendMessage, from.id);
6696
7463
  break;
6697
7464
  default:
6698
- sendResponse6(id, {
7465
+ sendResponse7(id, {
6699
7466
  success: false,
6700
7467
  error: `Unknown operation: ${operation}`
6701
7468
  }, sendMessage, from.id);
6702
7469
  }
6703
7470
  } catch (error) {
6704
7471
  logger.error("Failed to handle bookmarks request:", error);
6705
- sendResponse6(null, {
7472
+ sendResponse7(null, {
6706
7473
  success: false,
6707
7474
  error: error instanceof Error ? error.message : "Unknown error occurred"
6708
7475
  }, sendMessage);
6709
7476
  }
6710
7477
  }
6711
- async function handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, clientId) {
7478
+ async function handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
6712
7479
  if (!userId) {
6713
- sendResponse6(id, {
7480
+ sendResponse7(id, {
6714
7481
  success: false,
6715
7482
  error: "userId is required"
6716
7483
  }, sendMessage, clientId);
6717
7484
  return;
6718
7485
  }
6719
7486
  if (!uiblock) {
6720
- sendResponse6(id, {
7487
+ sendResponse7(id, {
6721
7488
  success: false,
6722
7489
  error: "UIBlock data is required"
6723
7490
  }, sendMessage, clientId);
6724
7491
  return;
6725
7492
  }
6726
7493
  try {
6727
- const result = await executeCollection("bookmarks", "create", { userId, threadId, uiblock });
6728
- sendResponse6(id, {
7494
+ const result = await executeCollection("bookmarks", "create", { userId, threadId, name, description, uiblock });
7495
+ sendResponse7(id, {
6729
7496
  success: true,
6730
7497
  data: result.data,
6731
7498
  message: "Bookmark created successfully"
6732
7499
  }, sendMessage, clientId);
6733
7500
  logger.info(`Bookmark created: ID ${result.data.id}`);
6734
7501
  } catch (error) {
6735
- sendResponse6(id, {
7502
+ sendResponse7(id, {
6736
7503
  success: false,
6737
7504
  error: error instanceof Error ? error.message : "Failed to create bookmark"
6738
7505
  }, sendMessage, clientId);
6739
7506
  }
6740
7507
  }
6741
- async function handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, clientId) {
7508
+ async function handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
6742
7509
  if (!bookmarkId) {
6743
- sendResponse6(id, {
7510
+ sendResponse7(id, {
6744
7511
  success: false,
6745
7512
  error: "Bookmark ID is required"
6746
7513
  }, sendMessage, clientId);
6747
7514
  return;
6748
7515
  }
6749
- if (!uiblock) {
6750
- sendResponse6(id, {
6751
- success: false,
6752
- error: "UIBlock data is required"
6753
- }, sendMessage, clientId);
6754
- return;
6755
- }
6756
7516
  try {
6757
- const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, uiblock });
6758
- sendResponse6(id, {
7517
+ const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, name, description, uiblock });
7518
+ sendResponse7(id, {
6759
7519
  success: true,
6760
7520
  data: result.data,
6761
7521
  message: "Bookmark updated successfully"
6762
7522
  }, sendMessage, clientId);
6763
7523
  logger.info(`Bookmark updated: ID ${bookmarkId}`);
6764
7524
  } catch (error) {
6765
- sendResponse6(id, {
7525
+ sendResponse7(id, {
6766
7526
  success: false,
6767
7527
  error: error instanceof Error ? error.message : "Failed to update bookmark"
6768
7528
  }, sendMessage, clientId);
6769
7529
  }
6770
7530
  }
6771
- async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, clientId) {
7531
+ async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, clientId) {
6772
7532
  if (!bookmarkId) {
6773
- sendResponse6(id, {
7533
+ sendResponse7(id, {
6774
7534
  success: false,
6775
7535
  error: "Bookmark ID is required"
6776
7536
  }, sendMessage, clientId);
@@ -6778,23 +7538,23 @@ async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, cli
6778
7538
  }
6779
7539
  try {
6780
7540
  const result = await executeCollection("bookmarks", "delete", { id: bookmarkId });
6781
- sendResponse6(id, {
7541
+ sendResponse7(id, {
6782
7542
  success: true,
6783
7543
  data: result.data,
6784
7544
  message: "Bookmark deleted successfully"
6785
7545
  }, sendMessage, clientId);
6786
7546
  logger.info(`Bookmark deleted: ID ${bookmarkId}`);
6787
7547
  } catch (error) {
6788
- sendResponse6(id, {
7548
+ sendResponse7(id, {
6789
7549
  success: false,
6790
7550
  error: error instanceof Error ? error.message : "Failed to delete bookmark"
6791
7551
  }, sendMessage, clientId);
6792
7552
  }
6793
7553
  }
6794
- async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
7554
+ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
6795
7555
  try {
6796
7556
  const result = await executeCollection("bookmarks", "getAll", {});
6797
- sendResponse6(id, {
7557
+ sendResponse7(id, {
6798
7558
  success: true,
6799
7559
  data: result.data,
6800
7560
  count: result.count,
@@ -6802,15 +7562,15 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
6802
7562
  }, sendMessage, clientId);
6803
7563
  logger.info(`Retrieved all bookmarks (count: ${result.count})`);
6804
7564
  } catch (error) {
6805
- sendResponse6(id, {
7565
+ sendResponse7(id, {
6806
7566
  success: false,
6807
7567
  error: error instanceof Error ? error.message : "Failed to get bookmarks"
6808
7568
  }, sendMessage, clientId);
6809
7569
  }
6810
7570
  }
6811
- async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, clientId) {
7571
+ async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, clientId) {
6812
7572
  if (!bookmarkId) {
6813
- sendResponse6(id, {
7573
+ sendResponse7(id, {
6814
7574
  success: false,
6815
7575
  error: "Bookmark ID is required"
6816
7576
  }, sendMessage, clientId);
@@ -6818,14 +7578,14 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
6818
7578
  }
6819
7579
  try {
6820
7580
  const result = await executeCollection("bookmarks", "getOne", { id: bookmarkId });
6821
- sendResponse6(id, {
7581
+ sendResponse7(id, {
6822
7582
  success: true,
6823
7583
  data: result.data,
6824
7584
  message: `Retrieved bookmark ID ${bookmarkId}`
6825
7585
  }, sendMessage, clientId);
6826
7586
  logger.info(`Retrieved bookmark: ID ${bookmarkId}`);
6827
7587
  } catch (error) {
6828
- sendResponse6(id, {
7588
+ sendResponse7(id, {
6829
7589
  success: false,
6830
7590
  error: error instanceof Error ? error.message : "Failed to get bookmark"
6831
7591
  }, sendMessage, clientId);
@@ -6833,7 +7593,7 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
6833
7593
  }
6834
7594
  async function handleGetByUser(id, userId, threadId, executeCollection, sendMessage, clientId) {
6835
7595
  if (!userId) {
6836
- sendResponse6(id, {
7596
+ sendResponse7(id, {
6837
7597
  success: false,
6838
7598
  error: "userId is required"
6839
7599
  }, sendMessage, clientId);
@@ -6841,7 +7601,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6841
7601
  }
6842
7602
  try {
6843
7603
  const result = await executeCollection("bookmarks", "getByUser", { userId, threadId });
6844
- sendResponse6(id, {
7604
+ sendResponse7(id, {
6845
7605
  success: true,
6846
7606
  data: result.data,
6847
7607
  count: result.count,
@@ -6849,7 +7609,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6849
7609
  }, sendMessage, clientId);
6850
7610
  logger.info(`Retrieved bookmarks for user ${userId} (count: ${result.count})`);
6851
7611
  } catch (error) {
6852
- sendResponse6(id, {
7612
+ sendResponse7(id, {
6853
7613
  success: false,
6854
7614
  error: error instanceof Error ? error.message : "Failed to get bookmarks by user"
6855
7615
  }, sendMessage, clientId);
@@ -6857,7 +7617,7 @@ async function handleGetByUser(id, userId, threadId, executeCollection, sendMess
6857
7617
  }
6858
7618
  async function handleGetByThread(id, threadId, executeCollection, sendMessage, clientId) {
6859
7619
  if (!threadId) {
6860
- sendResponse6(id, {
7620
+ sendResponse7(id, {
6861
7621
  success: false,
6862
7622
  error: "threadId is required"
6863
7623
  }, sendMessage, clientId);
@@ -6865,7 +7625,7 @@ async function handleGetByThread(id, threadId, executeCollection, sendMessage, c
6865
7625
  }
6866
7626
  try {
6867
7627
  const result = await executeCollection("bookmarks", "getByThread", { threadId });
6868
- sendResponse6(id, {
7628
+ sendResponse7(id, {
6869
7629
  success: true,
6870
7630
  data: result.data,
6871
7631
  count: result.count,
@@ -6873,13 +7633,13 @@ async function handleGetByThread(id, threadId, executeCollection, sendMessage, c
6873
7633
  }, sendMessage, clientId);
6874
7634
  logger.info(`Retrieved bookmarks for thread ${threadId} (count: ${result.count})`);
6875
7635
  } catch (error) {
6876
- sendResponse6(id, {
7636
+ sendResponse7(id, {
6877
7637
  success: false,
6878
7638
  error: error instanceof Error ? error.message : "Failed to get bookmarks by thread"
6879
7639
  }, sendMessage, clientId);
6880
7640
  }
6881
7641
  }
6882
- function sendResponse6(id, res, sendMessage, clientId) {
7642
+ function sendResponse7(id, res, sendMessage, clientId) {
6883
7643
  const response = {
6884
7644
  id: id || "unknown",
6885
7645
  type: "BOOKMARKS_RES",
@@ -7890,12 +8650,12 @@ var SuperatomSDK = class {
7890
8650
  });
7891
8651
  break;
7892
8652
  case "USER_PROMPT_SUGGESTIONS_REQ":
7893
- handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg)).catch((error) => {
8653
+ handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg), this.collections, this.userId).catch((error) => {
7894
8654
  logger.error("Failed to handle user prompt suggestions request:", error);
7895
8655
  });
7896
8656
  break;
7897
8657
  case "COMPONENT_LIST_RES":
7898
- handleComponentListResponse(parsed, (com) => this.storeComponents(com)).catch((error) => {
8658
+ handleComponentListResponse(parsed, (com) => this.storeComponents(com), this.collections).catch((error) => {
7899
8659
  logger.error("Failed to handle component list request:", error);
7900
8660
  });
7901
8661
  break;
@@ -7905,15 +8665,20 @@ var SuperatomSDK = class {
7905
8665
  });
7906
8666
  break;
7907
8667
  case "DASHBOARDS":
7908
- handleDashboardsRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8668
+ handleDashboardsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7909
8669
  logger.error("Failed to handle dashboards request:", error);
7910
8670
  });
7911
8671
  break;
7912
8672
  case "REPORTS":
7913
- handleReportsRequest(parsed, (msg) => this.send(msg)).catch((error) => {
8673
+ handleReportsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7914
8674
  logger.error("Failed to handle reports request:", error);
7915
8675
  });
7916
8676
  break;
8677
+ case "UIS":
8678
+ handleUIsRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
8679
+ logger.error("Failed to handle UIs request:", error);
8680
+ });
8681
+ break;
7917
8682
  case "BOOKMARKS":
7918
8683
  handleBookmarksRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
7919
8684
  logger.error("Failed to handle bookmarks request:", error);