@trops/dash-core 0.1.92 → 0.1.94

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.
@@ -606,6 +606,24 @@ var dashboardConfigEvents$1 = {
606
606
  DASHBOARD_CONFIG_PROVIDER_SETUP: DASHBOARD_CONFIG_PROVIDER_SETUP$1,
607
607
  };
608
608
 
609
+ /**
610
+ * Dashboard Ratings Events
611
+ *
612
+ * IPC event constants for dashboard ratings CRUD.
613
+ */
614
+
615
+ const DASHBOARD_RATING_SAVE$1 = "dashboard-rating-save";
616
+ const DASHBOARD_RATING_GET$1 = "dashboard-rating-get";
617
+ const DASHBOARD_RATING_LIST$1 = "dashboard-rating-list";
618
+ const DASHBOARD_RATING_DELETE$1 = "dashboard-rating-delete";
619
+
620
+ var dashboardRatingsEvents$1 = {
621
+ DASHBOARD_RATING_SAVE: DASHBOARD_RATING_SAVE$1,
622
+ DASHBOARD_RATING_GET: DASHBOARD_RATING_GET$1,
623
+ DASHBOARD_RATING_LIST: DASHBOARD_RATING_LIST$1,
624
+ DASHBOARD_RATING_DELETE: DASHBOARD_RATING_DELETE$1,
625
+ };
626
+
609
627
  /**
610
628
  * Events
611
629
  *
@@ -628,6 +646,7 @@ const openaiEvents = openaiEvents$1;
628
646
  const llmEvents = llmEvents$1;
629
647
  const clientCacheEvents = clientCacheEvents$1;
630
648
  const dashboardConfigEvents = dashboardConfigEvents$1;
649
+ const dashboardRatingsEvents = dashboardRatingsEvents$1;
631
650
 
632
651
  const publicEvents = {
633
652
  ...dataEvents,
@@ -651,6 +670,7 @@ var events$8 = {
651
670
  ...llmEvents,
652
671
  ...clientCacheEvents,
653
672
  ...dashboardConfigEvents,
673
+ ...dashboardRatingsEvents,
654
674
  };
655
675
 
656
676
  /**
@@ -744,7 +764,7 @@ var secureStoreController$1 = {
744
764
  getData: getData$1,
745
765
  };
746
766
 
747
- const path$e = require$$1$1;
767
+ const path$f = require$$1$1;
748
768
  const {
749
769
  readFileSync,
750
770
  writeFileSync: writeFileSync$4,
@@ -762,7 +782,7 @@ const {
762
782
  function ensureDirectoryExistence$2(filePath) {
763
783
  try {
764
784
  // isDirectory
765
- var dirname = path$e.dirname(filePath);
785
+ var dirname = path$f.dirname(filePath);
766
786
  // check if the directory exists...return true
767
787
  // if not, we can pass in the dirname as the filepath
768
788
  // and check each directory recursively.
@@ -813,7 +833,7 @@ function checkDirectory$1(dir) {
813
833
  * @param {string} filepath path to the file
814
834
  * @returns
815
835
  */
816
- function getFileContents$7(filepath, defaultReturn = []) {
836
+ function getFileContents$8(filepath, defaultReturn = []) {
817
837
  try {
818
838
  // lets first make sure all is there...
819
839
  ensureDirectoryExistence$2(filepath);
@@ -854,7 +874,7 @@ function getFileContents$7(filepath, defaultReturn = []) {
854
874
  }
855
875
  }
856
876
 
857
- function writeToFile$2(filename, data) {
877
+ function writeToFile$3(filename, data) {
858
878
  try {
859
879
  // write the new pages configuration back to the file
860
880
  return writeFileSync$4(filename, data);
@@ -877,7 +897,7 @@ function removeFilesFromDirectory(directory, excludeFiles = []) {
877
897
 
878
898
  for (const file of files) {
879
899
  if (!excludeFiles.includes(file)) {
880
- unlinkSync(path$e.join(directory, file), (err) => {
900
+ unlinkSync(path$f.join(directory, file), (err) => {
881
901
  if (err) throw err;
882
902
  });
883
903
  }
@@ -888,19 +908,19 @@ function removeFilesFromDirectory(directory, excludeFiles = []) {
888
908
 
889
909
  var file = {
890
910
  ensureDirectoryExistence: ensureDirectoryExistence$2,
891
- getFileContents: getFileContents$7,
892
- writeToFile: writeToFile$2,
911
+ getFileContents: getFileContents$8,
912
+ writeToFile: writeToFile$3,
893
913
  removeFilesFromDirectory,
894
914
  checkDirectory: checkDirectory$1,
895
915
  };
896
916
 
897
- const { app: app$8 } = require$$0$1;
898
- const path$d = require$$1$1;
917
+ const { app: app$9 } = require$$0$1;
918
+ const path$e = require$$1$1;
899
919
  const { writeFileSync: writeFileSync$3 } = require$$2;
900
- const { getFileContents: getFileContents$6 } = file;
920
+ const { getFileContents: getFileContents$7 } = file;
901
921
 
902
922
  const configFilename$5 = "workspaces.json";
903
- const appName$6 = "Dashboard";
923
+ const appName$7 = "Dashboard";
904
924
 
905
925
  const workspaceController$1 = {
906
926
  /**
@@ -942,13 +962,13 @@ const workspaceController$1 = {
942
962
  saveWorkspaceForApplication: (win, appId, workspaceObject) => {
943
963
  try {
944
964
  // filename to the pages file (live pages)
945
- const filename = path$d.join(
946
- app$8.getPath("userData"),
947
- appName$6,
965
+ const filename = path$e.join(
966
+ app$9.getPath("userData"),
967
+ appName$7,
948
968
  appId,
949
969
  configFilename$5,
950
970
  );
951
- const workspacesArray = getFileContents$6(filename);
971
+ const workspacesArray = getFileContents$7(filename);
952
972
 
953
973
  // lets check to see if we already have this one!
954
974
  let indexOfExistingItem = null;
@@ -991,13 +1011,13 @@ const workspaceController$1 = {
991
1011
  saveMenuItemsForApplication: (win, appId, menuItems) => {
992
1012
  try {
993
1013
  // filename to the workspaces file
994
- const filename = path$d.join(
995
- app$8.getPath("userData"),
996
- appName$6,
1014
+ const filename = path$e.join(
1015
+ app$9.getPath("userData"),
1016
+ appName$7,
997
1017
  appId,
998
1018
  configFilename$5,
999
1019
  );
1000
- const workspacesArray = getFileContents$6(filename);
1020
+ const workspacesArray = getFileContents$7(filename);
1001
1021
 
1002
1022
  // Update menu items for workspaces
1003
1023
  // This assumes menuItems is an object with workspace IDs as keys
@@ -1040,13 +1060,13 @@ const workspaceController$1 = {
1040
1060
  */
1041
1061
  deleteWorkspaceForApplication: (win, appId, workspaceId) => {
1042
1062
  try {
1043
- const filename = path$d.join(
1044
- app$8.getPath("userData"),
1045
- appName$6,
1063
+ const filename = path$e.join(
1064
+ app$9.getPath("userData"),
1065
+ appName$7,
1046
1066
  appId,
1047
1067
  configFilename$5,
1048
1068
  );
1049
- const workspacesArray = getFileContents$6(filename);
1069
+ const workspacesArray = getFileContents$7(filename);
1050
1070
 
1051
1071
  const filtered = workspacesArray.filter(
1052
1072
  (workspace) => workspace.id !== workspaceId,
@@ -1074,14 +1094,14 @@ const workspaceController$1 = {
1074
1094
 
1075
1095
  listWorkspacesForApplication: (win, appId) => {
1076
1096
  try {
1077
- const filename = path$d.join(
1078
- app$8.getPath("userData"),
1079
- appName$6,
1097
+ const filename = path$e.join(
1098
+ app$9.getPath("userData"),
1099
+ appName$7,
1080
1100
  appId,
1081
1101
  configFilename$5,
1082
1102
  );
1083
1103
 
1084
- const workspacesArray = getFileContents$6(filename);
1104
+ const workspacesArray = getFileContents$7(filename);
1085
1105
  console.log(
1086
1106
  `[workspaceController] Loaded ${workspacesArray.length} workspaces for appId: ${appId}`,
1087
1107
  );
@@ -1102,13 +1122,13 @@ const workspaceController$1 = {
1102
1122
 
1103
1123
  listMenuItemsForApplication: (win, appId) => {
1104
1124
  try {
1105
- const filename = path$d.join(
1106
- app$8.getPath("userData"),
1107
- appName$6,
1125
+ const filename = path$e.join(
1126
+ app$9.getPath("userData"),
1127
+ appName$7,
1108
1128
  appId,
1109
1129
  configFilename$5,
1110
1130
  );
1111
- const workspacesArray = getFileContents$6(filename);
1131
+ const workspacesArray = getFileContents$7(filename);
1112
1132
 
1113
1133
  // Extract unique menu items from workspaces
1114
1134
  // Each workspace can have a menuId, we need to build the menu items list
@@ -1146,13 +1166,13 @@ const workspaceController$1 = {
1146
1166
 
1147
1167
  var workspaceController_1 = workspaceController$1;
1148
1168
 
1149
- const { app: app$7 } = require$$0$1;
1150
- const path$c = require$$1$1;
1169
+ const { app: app$8 } = require$$0$1;
1170
+ const path$d = require$$1$1;
1151
1171
  const { writeFileSync: writeFileSync$2 } = require$$2;
1152
- const { getFileContents: getFileContents$5 } = file;
1172
+ const { getFileContents: getFileContents$6 } = file;
1153
1173
 
1154
1174
  const configFilename$4 = "themes.json";
1155
- const appName$5 = "Dashboard";
1175
+ const appName$6 = "Dashboard";
1156
1176
 
1157
1177
  const themeController$1 = {
1158
1178
  /**
@@ -1167,13 +1187,13 @@ const themeController$1 = {
1167
1187
  saveThemeForApplication: (win, appId, name, obj) => {
1168
1188
  try {
1169
1189
  // filename to the pages file (live pages)
1170
- const filename = path$c.join(
1171
- app$7.getPath("userData"),
1172
- appName$5,
1190
+ const filename = path$d.join(
1191
+ app$8.getPath("userData"),
1192
+ appName$6,
1173
1193
  appId,
1174
1194
  configFilename$4,
1175
1195
  );
1176
- const data = getFileContents$5(filename, {});
1196
+ const data = getFileContents$6(filename, {});
1177
1197
 
1178
1198
  // Add/update the theme based on the name
1179
1199
  if (name in data === false) {
@@ -1213,14 +1233,14 @@ const themeController$1 = {
1213
1233
  */
1214
1234
  listThemesForApplication: (win, appId) => {
1215
1235
  try {
1216
- const filename = path$c.join(
1217
- app$7.getPath("userData"),
1218
- appName$5,
1236
+ const filename = path$d.join(
1237
+ app$8.getPath("userData"),
1238
+ appName$6,
1219
1239
  appId,
1220
1240
  configFilename$4,
1221
1241
  );
1222
1242
 
1223
- const data = getFileContents$5(filename, {});
1243
+ const data = getFileContents$6(filename, {});
1224
1244
 
1225
1245
  console.log(
1226
1246
  "[themeController] Loading themes from:",
@@ -1255,13 +1275,13 @@ const themeController$1 = {
1255
1275
  */
1256
1276
  deleteThemeForApplication: (win, appId, themeKey) => {
1257
1277
  try {
1258
- const filename = path$c.join(
1259
- app$7.getPath("userData"),
1260
- appName$5,
1278
+ const filename = path$d.join(
1279
+ app$8.getPath("userData"),
1280
+ appName$6,
1261
1281
  appId,
1262
1282
  configFilename$4,
1263
1283
  );
1264
- const data = getFileContents$5(filename, {});
1284
+ const data = getFileContents$6(filename, {});
1265
1285
 
1266
1286
  if (themeKey in data) {
1267
1287
  delete data[themeKey];
@@ -1302,8 +1322,8 @@ var xmlParser = require$$3;
1302
1322
  var JSONStream$1 = require$$4;
1303
1323
  const stream = require$$5;
1304
1324
  var csv = require$$6;
1305
- const path$b = require$$1$1;
1306
- const { app: app$6 } = require$$0$1;
1325
+ const path$c = require$$1$1;
1326
+ const { app: app$7 } = require$$0$1;
1307
1327
  const { ensureDirectoryExistence: ensureDirectoryExistence$1 } = file;
1308
1328
 
1309
1329
  const TRANSFORM_APP_NAME = "Dashboard";
@@ -1591,18 +1611,18 @@ let Transform$1 = class Transform {
1591
1611
  }
1592
1612
 
1593
1613
  // Validate file paths are within app data directory
1594
- const appDataDir = path$b.join(app$6.getPath("userData"), TRANSFORM_APP_NAME);
1595
- const resolvedFilepath = path$b.resolve(filepath);
1596
- const resolvedOutFilepath = path$b.resolve(outFilepath);
1614
+ const appDataDir = path$c.join(app$7.getPath("userData"), TRANSFORM_APP_NAME);
1615
+ const resolvedFilepath = path$c.resolve(filepath);
1616
+ const resolvedOutFilepath = path$c.resolve(outFilepath);
1597
1617
 
1598
- if (!resolvedFilepath.startsWith(appDataDir + path$b.sep)) {
1618
+ if (!resolvedFilepath.startsWith(appDataDir + path$c.sep)) {
1599
1619
  return reject(
1600
1620
  new Error(
1601
1621
  "Input file path must be within the application data directory",
1602
1622
  ),
1603
1623
  );
1604
1624
  }
1605
- if (!resolvedOutFilepath.startsWith(appDataDir + path$b.sep)) {
1625
+ if (!resolvedOutFilepath.startsWith(appDataDir + path$c.sep)) {
1606
1626
  return reject(
1607
1627
  new Error(
1608
1628
  "Output file path must be within the application data directory",
@@ -3460,18 +3480,18 @@ async function extractColorsFromImageURL$2(url, toDirectory) {
3460
3480
 
3461
3481
  var color = { extractColorsFromImageURL: extractColorsFromImageURL$2 };
3462
3482
 
3463
- const { app: app$5 } = require$$0$1;
3483
+ const { app: app$6 } = require$$0$1;
3464
3484
  var fs$7 = require$$2;
3465
- const path$a = require$$1$1;
3485
+ const path$b = require$$1$1;
3466
3486
  const events$5 = events$8;
3467
- const { getFileContents: getFileContents$4, writeToFile: writeToFile$1 } = file;
3487
+ const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
3468
3488
 
3469
3489
  // Convert Json to Csv
3470
3490
  const ObjectsToCsv = require$$5$1;
3471
3491
  const Transform = transform;
3472
3492
  const { extractColorsFromImageURL: extractColorsFromImageURL$1 } = color;
3473
3493
  const https = require$$8;
3474
- const appName$4 = "Dashboard";
3494
+ const appName$5 = "Dashboard";
3475
3495
 
3476
3496
  const dataController$1 = {
3477
3497
  /**
@@ -3485,16 +3505,16 @@ const dataController$1 = {
3485
3505
  convertJsonToCsvFile: (win, appId, jsonObject, toFilename = "test.csv") => {
3486
3506
  try {
3487
3507
  // filename to the pages file (live pages)
3488
- const filename = path$a.join(
3489
- app$5.getPath("userData"),
3490
- appName$4,
3508
+ const filename = path$b.join(
3509
+ app$6.getPath("userData"),
3510
+ appName$5,
3491
3511
  appId,
3492
3512
  "data",
3493
3513
  toFilename,
3494
3514
  );
3495
3515
 
3496
3516
  // make sure the file exists...
3497
- const fileContents = getFileContents$4(filename, "");
3517
+ const fileContents = getFileContents$5(filename, "");
3498
3518
 
3499
3519
  const csv = new ObjectsToCsv(jsonObject);
3500
3520
 
@@ -3613,9 +3633,9 @@ const dataController$1 = {
3613
3633
  }
3614
3634
 
3615
3635
  // Validate toFilepath is within the app data directory
3616
- const appDataDir = path$a.join(app$5.getPath("userData"), appName$4);
3617
- const resolvedFilepath = path$a.resolve(toFilepath);
3618
- if (!resolvedFilepath.startsWith(appDataDir + path$a.sep)) {
3636
+ const appDataDir = path$b.join(app$6.getPath("userData"), appName$5);
3637
+ const resolvedFilepath = path$b.resolve(toFilepath);
3638
+ if (!resolvedFilepath.startsWith(appDataDir + path$b.sep)) {
3619
3639
  throw new Error(
3620
3640
  "File path must be within the application data directory",
3621
3641
  );
@@ -3762,9 +3782,9 @@ const dataController$1 = {
3762
3782
  try {
3763
3783
  if (data) {
3764
3784
  // filename to the pages file (live pages)
3765
- const toFilename = path$a.join(
3766
- app$5.getPath("userData"),
3767
- appName$4,
3785
+ const toFilename = path$b.join(
3786
+ app$6.getPath("userData"),
3787
+ appName$5,
3768
3788
  "data",
3769
3789
  filename,
3770
3790
  );
@@ -3772,7 +3792,7 @@ const dataController$1 = {
3772
3792
  //console.log("saving to file ", toFilename);
3773
3793
 
3774
3794
  // // call this to make sure the directory structure exists
3775
- let fileContents = getFileContents$4(toFilename, returnEmpty);
3795
+ let fileContents = getFileContents$5(toFilename, returnEmpty);
3776
3796
  if (fileContents === null || fileContents === "") {
3777
3797
  fileContents = JSON.stringify(returnEmpty);
3778
3798
  }
@@ -3788,7 +3808,7 @@ const dataController$1 = {
3788
3808
  const tempWriteContents = JSON.parse(fileContents);
3789
3809
  tempWriteContents[stamp] = data;
3790
3810
  writeContents = JSON.stringify(tempWriteContents);
3791
- writeToFile$1(toFilename, writeContents);
3811
+ writeToFile$2(toFilename, writeContents);
3792
3812
  }
3793
3813
 
3794
3814
  if (JSON.stringify(returnEmpty) === "[]") {
@@ -3797,20 +3817,20 @@ const dataController$1 = {
3797
3817
  writeContents = JSON.stringify(tempWriteContents);
3798
3818
  // writeContents = JSON.parse(fileContents);
3799
3819
  // writeContents.push({ [stamp]: data });
3800
- writeToFile$1(toFilename, writeContents);
3820
+ writeToFile$2(toFilename, writeContents);
3801
3821
  }
3802
3822
  } else {
3803
3823
  // overwrite existing
3804
3824
  writeContents = JSON.stringify(data);
3805
3825
  if (JSON.stringify(returnEmpty) === "{}") {
3806
- writeToFile$1(
3826
+ writeToFile$2(
3807
3827
  toFilename,
3808
3828
  writeContents,
3809
3829
  // JSON.stringify({ [stamp]: data })
3810
3830
  );
3811
3831
  }
3812
3832
  if (JSON.stringify(returnEmpty) === "[]") {
3813
- writeToFile$1(
3833
+ writeToFile$2(
3814
3834
  toFilename,
3815
3835
  writeContents,
3816
3836
  // JSON.stringify([{ [stamp]: data }])
@@ -3844,15 +3864,15 @@ const dataController$1 = {
3844
3864
  try {
3845
3865
  if (filename) {
3846
3866
  // filename to the pages file (live pages)
3847
- const fromFilename = path$a.join(
3848
- app$5.getPath("userData"),
3849
- appName$4,
3867
+ const fromFilename = path$b.join(
3868
+ app$6.getPath("userData"),
3869
+ appName$5,
3850
3870
  "data",
3851
3871
  filename,
3852
3872
  );
3853
3873
  console.log("reading from file ", fromFilename, returnIfEmpty);
3854
3874
  // make sure the file exists...
3855
- const fileContents = getFileContents$4(fromFilename, returnIfEmpty);
3875
+ const fileContents = getFileContents$5(fromFilename, returnIfEmpty);
3856
3876
 
3857
3877
  console.log("file contents ", fileContents, fromFilename);
3858
3878
 
@@ -3922,9 +3942,9 @@ const dataController$1 = {
3922
3942
  try {
3923
3943
  console.log(url);
3924
3944
  const fileExtension = ".jpg";
3925
- const filename = path$a.join(
3926
- app$5.getPath("userData"),
3927
- appName$4,
3945
+ const filename = path$b.join(
3946
+ app$6.getPath("userData"),
3947
+ appName$5,
3928
3948
  "@algolia/dash-electron",
3929
3949
  "data",
3930
3950
  "imageExtract" + fileExtension,
@@ -3947,13 +3967,13 @@ var dataController_1 = dataController$1;
3947
3967
  * settingsController
3948
3968
  */
3949
3969
 
3950
- const { app: app$4 } = require$$0$1;
3951
- const path$9 = require$$1$1;
3970
+ const { app: app$5 } = require$$0$1;
3971
+ const path$a = require$$1$1;
3952
3972
  const fs$6 = require$$2;
3953
- const { getFileContents: getFileContents$3, writeToFile } = file;
3973
+ const { getFileContents: getFileContents$4, writeToFile: writeToFile$1 } = file;
3954
3974
 
3955
3975
  const configFilename$3 = "settings.json";
3956
- const appName$3 = "Dashboard";
3976
+ const appName$4 = "Dashboard";
3957
3977
 
3958
3978
  // Helper function to recursively copy directory
3959
3979
  function copyDirectory(source, destination) {
@@ -3963,8 +3983,8 @@ function copyDirectory(source, destination) {
3963
3983
 
3964
3984
  const files = fs$6.readdirSync(source);
3965
3985
  for (const file of files) {
3966
- const srcPath = path$9.join(source, file);
3967
- const destPath = path$9.join(destination, file);
3986
+ const srcPath = path$a.join(source, file);
3987
+ const destPath = path$a.join(destination, file);
3968
3988
  const stat = fs$6.lstatSync(srcPath);
3969
3989
 
3970
3990
  // Skip symlinks to prevent following links to sensitive files
@@ -3992,12 +4012,12 @@ const settingsController$1 = {
3992
4012
  try {
3993
4013
  if (data) {
3994
4014
  // <appId>/settings.json
3995
- const filename = path$9.join(
3996
- app$4.getPath("userData"),
3997
- appName$3,
4015
+ const filename = path$a.join(
4016
+ app$5.getPath("userData"),
4017
+ appName$4,
3998
4018
  configFilename$3,
3999
4019
  );
4000
- writeToFile(filename, JSON.stringify(data, null, 2));
4020
+ writeToFile$1(filename, JSON.stringify(data, null, 2));
4001
4021
  console.log("[settingsController] Settings saved successfully");
4002
4022
  // Return the data for ipcMain.handle() - modern promise-based approach
4003
4023
  return {
@@ -4028,13 +4048,13 @@ const settingsController$1 = {
4028
4048
  getSettingsForApplication: (win) => {
4029
4049
  try {
4030
4050
  // <appId>/settings.json
4031
- const filename = path$9.join(
4032
- app$4.getPath("userData"),
4033
- appName$3,
4051
+ const filename = path$a.join(
4052
+ app$5.getPath("userData"),
4053
+ appName$4,
4034
4054
  configFilename$3,
4035
4055
  );
4036
4056
  // make sure the file exists...
4037
- const fileContents = getFileContents$3(filename, {});
4057
+ const fileContents = getFileContents$4(filename, {});
4038
4058
  console.log("[settingsController] Settings loaded successfully");
4039
4059
  // Return the data for ipcMain.handle() - modern promise-based approach
4040
4060
  return {
@@ -4059,15 +4079,15 @@ const settingsController$1 = {
4059
4079
  */
4060
4080
  getDataDirectory: (win) => {
4061
4081
  try {
4062
- const settingsPath = path$9.join(
4063
- app$4.getPath("userData"),
4064
- appName$3,
4082
+ const settingsPath = path$a.join(
4083
+ app$5.getPath("userData"),
4084
+ appName$4,
4065
4085
  configFilename$3,
4066
4086
  );
4067
- const settings = getFileContents$3(settingsPath, {});
4087
+ const settings = getFileContents$4(settingsPath, {});
4068
4088
  const userDataDir =
4069
4089
  settings.userDataDirectory ||
4070
- path$9.join(app$4.getPath("userData"), appName$3);
4090
+ path$a.join(app$5.getPath("userData"), appName$4);
4071
4091
 
4072
4092
  console.log("[settingsController] Data directory retrieved successfully");
4073
4093
  // Return the data for ipcMain.handle() - modern promise-based approach
@@ -4104,14 +4124,14 @@ const settingsController$1 = {
4104
4124
  }
4105
4125
 
4106
4126
  // Update settings
4107
- const settingsPath = path$9.join(
4108
- app$4.getPath("userData"),
4109
- appName$3,
4127
+ const settingsPath = path$a.join(
4128
+ app$5.getPath("userData"),
4129
+ appName$4,
4110
4130
  configFilename$3,
4111
4131
  );
4112
- const settings = getFileContents$3(settingsPath, {});
4132
+ const settings = getFileContents$4(settingsPath, {});
4113
4133
  settings.userDataDirectory = newPath;
4114
- writeToFile(settingsPath, JSON.stringify(settings, null, 2));
4134
+ writeToFile$1(settingsPath, JSON.stringify(settings, null, 2));
4115
4135
 
4116
4136
  console.log("[settingsController] Data directory set successfully");
4117
4137
  // Return the data for ipcMain.handle() - modern promise-based approach
@@ -4138,20 +4158,20 @@ const settingsController$1 = {
4138
4158
  migrateDataDirectory: (win, oldPath, newPath) => {
4139
4159
  try {
4140
4160
  // Resolve paths to prevent traversal
4141
- const resolvedOldPath = path$9.resolve(oldPath);
4142
- const resolvedNewPath = path$9.resolve(newPath);
4161
+ const resolvedOldPath = path$a.resolve(oldPath);
4162
+ const resolvedNewPath = path$a.resolve(newPath);
4143
4163
 
4144
4164
  // Validate oldPath is the current configured data directory
4145
- const settingsCheckPath = path$9.join(
4146
- app$4.getPath("userData"),
4147
- appName$3,
4165
+ const settingsCheckPath = path$a.join(
4166
+ app$5.getPath("userData"),
4167
+ appName$4,
4148
4168
  configFilename$3,
4149
4169
  );
4150
- const currentSettings = getFileContents$3(settingsCheckPath, {});
4170
+ const currentSettings = getFileContents$4(settingsCheckPath, {});
4151
4171
  const currentDataDir =
4152
4172
  currentSettings.userDataDirectory ||
4153
- path$9.join(app$4.getPath("userData"), appName$3);
4154
- if (resolvedOldPath !== path$9.resolve(currentDataDir)) {
4173
+ path$a.join(app$5.getPath("userData"), appName$4);
4174
+ if (resolvedOldPath !== path$a.resolve(currentDataDir)) {
4155
4175
  throw new Error("Source path must be the current data directory");
4156
4176
  }
4157
4177
 
@@ -4187,14 +4207,14 @@ const settingsController$1 = {
4187
4207
  copyDirectory(resolvedOldPath, resolvedNewPath);
4188
4208
 
4189
4209
  // Update settings to use new path
4190
- const settingsPath = path$9.join(
4191
- app$4.getPath("userData"),
4192
- appName$3,
4210
+ const settingsPath = path$a.join(
4211
+ app$5.getPath("userData"),
4212
+ appName$4,
4193
4213
  configFilename$3,
4194
4214
  );
4195
- const settings = getFileContents$3(settingsPath, {});
4215
+ const settings = getFileContents$4(settingsPath, {});
4196
4216
  settings.userDataDirectory = resolvedNewPath;
4197
- writeToFile(settingsPath, JSON.stringify(settings, null, 2));
4217
+ writeToFile$1(settingsPath, JSON.stringify(settings, null, 2));
4198
4218
 
4199
4219
  console.log("[settingsController] Data directory migrated successfully");
4200
4220
  // Return the data for ipcMain.handle() - modern promise-based approach
@@ -4801,14 +4821,14 @@ function requireProviderController () {
4801
4821
  return providerController_1;
4802
4822
  }
4803
4823
 
4804
- const { app: app$3 } = require$$0$1;
4805
- const path$8 = require$$1$1;
4824
+ const { app: app$4 } = require$$0$1;
4825
+ const path$9 = require$$1$1;
4806
4826
  const { writeFileSync: writeFileSync$1 } = require$$2;
4807
4827
  const events$4 = events$8;
4808
- const { getFileContents: getFileContents$2 } = file;
4828
+ const { getFileContents: getFileContents$3 } = file;
4809
4829
 
4810
4830
  const configFilename$2 = "layouts.json";
4811
- const appName$2 = "Dashboard";
4831
+ const appName$3 = "Dashboard";
4812
4832
 
4813
4833
  const layoutController$1 = {
4814
4834
  /**
@@ -4822,13 +4842,13 @@ const layoutController$1 = {
4822
4842
  saveLayoutForApplication: (win, appId, layoutObject) => {
4823
4843
  try {
4824
4844
  // filename to the pages file (live pages)
4825
- const filename = path$8.join(
4826
- app$3.getPath("userData"),
4827
- appName$2,
4845
+ const filename = path$9.join(
4846
+ app$4.getPath("userData"),
4847
+ appName$3,
4828
4848
  appId,
4829
4849
  configFilename$2,
4830
4850
  );
4831
- const layoutsArray = getFileContents$2(filename);
4851
+ const layoutsArray = getFileContents$3(filename);
4832
4852
 
4833
4853
  // add the pageObject to the pages file
4834
4854
  layoutsArray.push(layoutObject);
@@ -4855,13 +4875,13 @@ const layoutController$1 = {
4855
4875
  */
4856
4876
  listLayoutsForApplication: (win, appId) => {
4857
4877
  try {
4858
- const filename = path$8.join(
4859
- app$3.getPath("userData"),
4860
- appName$2,
4878
+ const filename = path$9.join(
4879
+ app$4.getPath("userData"),
4880
+ appName$3,
4861
4881
  appId,
4862
4882
  configFilename$2,
4863
4883
  );
4864
- const layoutsArray = getFileContents$2(filename);
4884
+ const layoutsArray = getFileContents$3(filename);
4865
4885
  win.webContents.send(events$4.LAYOUT_LIST_COMPLETE, {
4866
4886
  layouts: layoutsArray,
4867
4887
  });
@@ -4898,7 +4918,7 @@ const {
4898
4918
  const {
4899
4919
  StreamableHTTPClientTransport,
4900
4920
  } = require$$2$3;
4901
- const path$7 = require$$1$1;
4921
+ const path$8 = require$$1$1;
4902
4922
  const fs$5 = require$$2;
4903
4923
 
4904
4924
  /**
@@ -5315,7 +5335,7 @@ const mcpController$2 = {
5315
5335
  }
5316
5336
 
5317
5337
  // Interpolate {{MCP_DIR}} in args to resolve local MCP server scripts
5318
- const mcpDir = path$7.join(__dirname, "..", "mcp");
5338
+ const mcpDir = path$8.join(__dirname, "..", "mcp");
5319
5339
  for (let i = 0; i < args.length; i++) {
5320
5340
  if (
5321
5341
  typeof args[i] === "string" &&
@@ -5690,7 +5710,7 @@ const mcpController$2 = {
5690
5710
  */
5691
5711
  getCatalog: (win) => {
5692
5712
  try {
5693
- const catalogPath = path$7.join(
5713
+ const catalogPath = path$8.join(
5694
5714
  __dirname,
5695
5715
  "..",
5696
5716
  "mcp",
@@ -5802,7 +5822,7 @@ const mcpController$2 = {
5802
5822
  }
5803
5823
 
5804
5824
  // Interpolate {{MCP_DIR}} in authCommand args (same as startServer)
5805
- const mcpDir = path$7.join(__dirname, "..", "mcp");
5825
+ const mcpDir = path$8.join(__dirname, "..", "mcp");
5806
5826
  const resolvedArgs = (authCommand.args || []).map((arg) =>
5807
5827
  typeof arg === "string" && arg.includes("{{MCP_DIR}}")
5808
5828
  ? arg.replace(/\{\{MCP_DIR\}\}/g, mcpDir)
@@ -5898,7 +5918,7 @@ var mcpControllerExports = mcpController$3.exports;
5898
5918
  * - Support two-level browsing: packages (bundles) and widgets within packages
5899
5919
  */
5900
5920
 
5901
- const path$6 = require$$1$1;
5921
+ const path$7 = require$$1$1;
5902
5922
  const fs$4 = require$$2;
5903
5923
 
5904
5924
  // Default registry URL (GitHub Pages)
@@ -5915,7 +5935,7 @@ let cacheTimestamp = 0;
5915
5935
  * Get the local test registry path for dev mode
5916
5936
  */
5917
5937
  function getTestRegistryPath() {
5918
- return path$6.join(__dirname, "..", "registry", "test-registry-index.json");
5938
+ return path$7.join(__dirname, "..", "registry", "test-registry-index.json");
5919
5939
  }
5920
5940
 
5921
5941
  /**
@@ -6175,7 +6195,7 @@ var registryController$1 = {
6175
6195
  var fs$3 = require$$2;
6176
6196
  var JSONStream = require$$4;
6177
6197
  const algoliasearch$1 = require$$2$4;
6178
- const path$5 = require$$3$2;
6198
+ const path$6 = require$$3$2;
6179
6199
  const { ensureDirectoryExistence, checkDirectory } = file;
6180
6200
 
6181
6201
  let AlgoliaIndex$1 = class AlgoliaIndex {
@@ -6282,7 +6302,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6282
6302
  if (err) reject(err);
6283
6303
  if (files) {
6284
6304
  files.forEach((file) => {
6285
- fs$3.unlinkSync(path$5.join(directoryPath, file));
6305
+ fs$3.unlinkSync(path$6.join(directoryPath, file));
6286
6306
  });
6287
6307
  resolve();
6288
6308
  }
@@ -6305,7 +6325,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6305
6325
  let results = [];
6306
6326
  for (const fileIndex in files) {
6307
6327
  // for each file lets read the file and then push to algolia
6308
- const pathToBatch = path$5.join(batchFilepath, files[fileIndex]);
6328
+ const pathToBatch = path$6.join(batchFilepath, files[fileIndex]);
6309
6329
  const fileContents = await this.readFile(pathToBatch);
6310
6330
  if (fileContents) {
6311
6331
  if ("data" in fileContents && "filepath" in fileContents) {
@@ -6759,25 +6779,25 @@ const openaiController$1 = {
6759
6779
 
6760
6780
  var openaiController_1 = openaiController$1;
6761
6781
 
6762
- const { app: app$2 } = require$$0$1;
6763
- const path$4 = require$$1$1;
6782
+ const { app: app$3 } = require$$0$1;
6783
+ const path$5 = require$$1$1;
6764
6784
  const { writeFileSync } = require$$2;
6765
- const { getFileContents: getFileContents$1 } = file;
6785
+ const { getFileContents: getFileContents$2 } = file;
6766
6786
 
6767
6787
  const configFilename$1 = "menuItems.json";
6768
- const appName$1 = "Dashboard";
6788
+ const appName$2 = "Dashboard";
6769
6789
 
6770
6790
  const menuItemsController$1 = {
6771
6791
  saveMenuItemForApplication: (win, appId, menuItem) => {
6772
6792
  try {
6773
6793
  // filename to the pages file (live pages)
6774
- const filename = path$4.join(
6775
- app$2.getPath("userData"),
6776
- appName$1,
6794
+ const filename = path$5.join(
6795
+ app$3.getPath("userData"),
6796
+ appName$2,
6777
6797
  appId,
6778
6798
  configFilename$1,
6779
6799
  );
6780
- const menuItemsArray = getFileContents$1(filename);
6800
+ const menuItemsArray = getFileContents$2(filename);
6781
6801
 
6782
6802
  menuItemsArray.filter((mi) => mi !== null);
6783
6803
 
@@ -6807,13 +6827,13 @@ const menuItemsController$1 = {
6807
6827
 
6808
6828
  listMenuItemsForApplication: (win, appId) => {
6809
6829
  try {
6810
- const filename = path$4.join(
6811
- app$2.getPath("userData"),
6812
- appName$1,
6830
+ const filename = path$5.join(
6831
+ app$3.getPath("userData"),
6832
+ appName$2,
6813
6833
  appId,
6814
6834
  configFilename$1,
6815
6835
  );
6816
- const menuItemsArray = getFileContents$1(filename);
6836
+ const menuItemsArray = getFileContents$2(filename);
6817
6837
  const filtered = menuItemsArray.filter((mi) => mi !== null);
6818
6838
  // Return the data for ipcMain.handle() - modern promise-based approach
6819
6839
  return {
@@ -6833,14 +6853,14 @@ const menuItemsController$1 = {
6833
6853
 
6834
6854
  var menuItemsController_1 = menuItemsController$1;
6835
6855
 
6836
- const path$3 = require$$1$1;
6837
- const { app: app$1 } = require$$0$1;
6856
+ const path$4 = require$$1$1;
6857
+ const { app: app$2 } = require$$0$1;
6838
6858
 
6839
6859
  const pluginController$1 = {
6840
6860
  install: (win, packageName, filepath) => {
6841
6861
  try {
6842
- const rootPath = path$3.join(
6843
- app$1.getPath("userData"),
6862
+ const rootPath = path$4.join(
6863
+ app$2.getPath("userData"),
6844
6864
  "plugins",
6845
6865
  packageName,
6846
6866
  );
@@ -8681,7 +8701,7 @@ var dynamicWidgetLoader$2 = {exports: {}};
8681
8701
  */
8682
8702
 
8683
8703
  const fs$1 = require$$2;
8684
- const path$2 = require$$1$1;
8704
+ const path$3 = require$$1$1;
8685
8705
 
8686
8706
  /**
8687
8707
  * Find the widgets/ directory, handling nested ZIP extraction.
@@ -8696,13 +8716,13 @@ const path$2 = require$$1$1;
8696
8716
  * @returns {string|null} Path to the widgets/ directory, or null
8697
8717
  */
8698
8718
  function findWidgetsDir$1(widgetPath) {
8699
- const direct = path$2.join(widgetPath, "widgets");
8719
+ const direct = path$3.join(widgetPath, "widgets");
8700
8720
  if (fs$1.existsSync(direct)) {
8701
8721
  return direct;
8702
8722
  }
8703
8723
 
8704
8724
  // Check configs/ directory (used by packageZip.js for distributed widgets)
8705
- const configs = path$2.join(widgetPath, "configs");
8725
+ const configs = path$3.join(widgetPath, "configs");
8706
8726
  if (fs$1.existsSync(configs)) {
8707
8727
  return configs;
8708
8728
  }
@@ -8719,7 +8739,7 @@ function findWidgetsDir$1(widgetPath) {
8719
8739
  );
8720
8740
 
8721
8741
  for (const subdir of subdirs) {
8722
- const nested = path$2.join(widgetPath, subdir.name, "widgets");
8742
+ const nested = path$3.join(widgetPath, subdir.name, "widgets");
8723
8743
  if (fs$1.existsSync(nested)) {
8724
8744
  console.log(`[WidgetCompiler] Found nested widgets/ at ${nested}`);
8725
8745
  return nested;
@@ -8768,14 +8788,14 @@ async function compileWidget(widgetPath) {
8768
8788
  // Compute relative path from the entry file (in widgetPath) to widgetsDir,
8769
8789
  // since widgetsDir may be nested (e.g., ./weather-widget/widgets/).
8770
8790
  const relWidgetsDir =
8771
- "./" + path$2.relative(widgetPath, widgetsDir).split(path$2.sep).join("/");
8791
+ "./" + path$3.relative(widgetPath, widgetsDir).split(path$3.sep).join("/");
8772
8792
  const imports = [];
8773
8793
  const exportParts = [];
8774
8794
 
8775
8795
  for (const dashFile of dashFiles) {
8776
8796
  const componentName = dashFile.replace(".dash.js", "");
8777
8797
  const componentFile = `${componentName}.js`;
8778
- const componentFilePath = path$2.join(widgetsDir, componentFile);
8798
+ const componentFilePath = path$3.join(widgetsDir, componentFile);
8779
8799
  const hasComponent = fs$1.existsSync(componentFilePath);
8780
8800
 
8781
8801
  // Import the config (always)
@@ -8802,9 +8822,9 @@ async function compileWidget(widgetPath) {
8802
8822
  const entryContent = [...imports, "", ...exportParts, ""].join("\n");
8803
8823
 
8804
8824
  // Write temporary entry file in the widget root
8805
- const entryPath = path$2.join(widgetPath, "__compile_entry.js");
8806
- const distDir = path$2.join(widgetPath, "dist");
8807
- const outPath = path$2.join(distDir, "index.cjs.js");
8825
+ const entryPath = path$3.join(widgetPath, "__compile_entry.js");
8826
+ const distDir = path$3.join(widgetPath, "dist");
8827
+ const outPath = path$3.join(distDir, "index.cjs.js");
8808
8828
 
8809
8829
  try {
8810
8830
  // Ensure dist/ directory exists
@@ -8881,7 +8901,7 @@ var widgetCompiler$1 = { compileWidget, findWidgetsDir: findWidgetsDir$1 };
8881
8901
  */
8882
8902
 
8883
8903
  const fs = require$$2;
8884
- const path$1 = require$$1$1;
8904
+ const path$2 = require$$1$1;
8885
8905
  const vm = require$$2$5;
8886
8906
  const { findWidgetsDir } = widgetCompiler$1;
8887
8907
 
@@ -8922,9 +8942,9 @@ class DynamicWidgetLoader {
8922
8942
  );
8923
8943
 
8924
8944
  const widgetsDir =
8925
- findWidgetsDir(widgetPath) || path$1.join(widgetPath, "widgets");
8926
- const componentPath = path$1.join(widgetsDir, `${componentName}.js`);
8927
- const configPath = path$1.join(widgetsDir, `${componentName}.dash.js`);
8945
+ findWidgetsDir(widgetPath) || path$2.join(widgetPath, "widgets");
8946
+ const componentPath = path$2.join(widgetsDir, `${componentName}.js`);
8947
+ const configPath = path$2.join(widgetsDir, `${componentName}.dash.js`);
8928
8948
 
8929
8949
  if (!fs.existsSync(componentPath)) {
8930
8950
  throw new Error(`Component file not found: ${componentPath}`);
@@ -10053,10 +10073,10 @@ var widgetRegistryExports = widgetRegistry$1.exports;
10053
10073
  * applies event wiring. (Import is implemented in DASH-13.)
10054
10074
  */
10055
10075
 
10056
- const { app, dialog } = require$$0$1;
10057
- const path = require$$1$1;
10076
+ const { app: app$1, dialog } = require$$0$1;
10077
+ const path$1 = require$$1$1;
10058
10078
  const AdmZip = require$$3$3;
10059
- const { getFileContents } = file;
10079
+ const { getFileContents: getFileContents$1 } = file;
10060
10080
  const {
10061
10081
  validateDashboardConfig,
10062
10082
  applyDefaults,
@@ -10072,7 +10092,7 @@ const {
10072
10092
  const { searchRegistry, getPackage } = registryController$1;
10073
10093
 
10074
10094
  const configFilename = "workspaces.json";
10075
- const appName = "Dashboard";
10095
+ const appName$1 = "Dashboard";
10076
10096
 
10077
10097
  /**
10078
10098
  * Export a workspace as a .dashboard.json config inside a ZIP file.
@@ -10095,13 +10115,13 @@ async function exportDashboardConfig$1(
10095
10115
  ) {
10096
10116
  try {
10097
10117
  // 1. Read workspace from workspaces.json
10098
- const filename = path.join(
10099
- app.getPath("userData"),
10100
- appName,
10118
+ const filename = path$1.join(
10119
+ app$1.getPath("userData"),
10120
+ appName$1,
10101
10121
  appId,
10102
10122
  configFilename,
10103
10123
  );
10104
- const workspacesArray = getFileContents(filename);
10124
+ const workspacesArray = getFileContents$1(filename);
10105
10125
  const workspace = workspacesArray.find(
10106
10126
  (w) => w.id === workspaceId || w.id === Number(workspaceId),
10107
10127
  );
@@ -10164,7 +10184,7 @@ async function exportDashboardConfig$1(
10164
10184
 
10165
10185
  const { canceled, filePath } = await dialog.showSaveDialog(win, {
10166
10186
  title: "Export Dashboard as ZIP",
10167
- defaultPath: path.join(app.getPath("desktop"), `${sanitizedName}.zip`),
10187
+ defaultPath: path$1.join(app$1.getPath("desktop"), `${sanitizedName}.zip`),
10168
10188
  filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
10169
10189
  });
10170
10190
 
@@ -10238,7 +10258,7 @@ async function importDashboardConfig$1(win, appId, widgetRegistry = null) {
10238
10258
  const zip = new AdmZip(zipPath);
10239
10259
 
10240
10260
  // Validate ZIP entries for path traversal
10241
- const tempDir = path.join(app.getPath("temp"), "dash-import");
10261
+ const tempDir = path$1.join(app$1.getPath("temp"), "dash-import");
10242
10262
  const { validateZipEntries } = widgetRegistryExports;
10243
10263
  validateZipEntries(zip, tempDir);
10244
10264
 
@@ -10514,7 +10534,7 @@ async function installDashboardFromRegistry$1(
10514
10534
  const zip = new AdmZip(Buffer.from(buffer));
10515
10535
 
10516
10536
  // 3. Validate ZIP entries
10517
- const tempDir = path.join(app.getPath("temp"), "dash-registry-import");
10537
+ const tempDir = path$1.join(app$1.getPath("temp"), "dash-registry-import");
10518
10538
  const { validateZipEntries } = widgetRegistryExports;
10519
10539
  validateZipEntries(zip, tempDir);
10520
10540
 
@@ -10642,13 +10662,13 @@ async function prepareDashboardForPublish$1(
10642
10662
  const { generateRegistryManifest } = dashboardConfigUtils$1;
10643
10663
 
10644
10664
  // 1. Read workspace
10645
- const filename = path.join(
10646
- app.getPath("userData"),
10647
- appName,
10665
+ const filename = path$1.join(
10666
+ app$1.getPath("userData"),
10667
+ appName$1,
10648
10668
  appId,
10649
10669
  configFilename,
10650
10670
  );
10651
- const workspacesArray = getFileContents(filename);
10671
+ const workspacesArray = getFileContents$1(filename);
10652
10672
  const workspace = workspacesArray.find(
10653
10673
  (w) => w.id === workspaceId || w.id === Number(workspaceId),
10654
10674
  );
@@ -10746,8 +10766,8 @@ async function prepareDashboardForPublish$1(
10746
10766
  const sanitizedName = manifest.name;
10747
10767
  const { canceled, filePath } = await dialog.showSaveDialog(win, {
10748
10768
  title: "Save Dashboard Package for Registry",
10749
- defaultPath: path.join(
10750
- app.getPath("desktop"),
10769
+ defaultPath: path$1.join(
10770
+ app$1.getPath("desktop"),
10751
10771
  `${sanitizedName}-v${manifest.version}.zip`,
10752
10772
  ),
10753
10773
  filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
@@ -10847,13 +10867,13 @@ async function checkDashboardUpdatesForApp$1(appId) {
10847
10867
  const { fetchRegistryIndex } = registryController$1;
10848
10868
 
10849
10869
  try {
10850
- const filename = path.join(
10851
- app.getPath("userData"),
10852
- appName,
10870
+ const filename = path$1.join(
10871
+ app$1.getPath("userData"),
10872
+ appName$1,
10853
10873
  appId,
10854
10874
  configFilename,
10855
10875
  );
10856
- const workspaces = getFileContents(filename) || [];
10876
+ const workspaces = getFileContents$1(filename) || [];
10857
10877
 
10858
10878
  const index = await fetchRegistryIndex();
10859
10879
  const registryPackages = index.packages || [];
@@ -10941,6 +10961,164 @@ clientCache$1.registerFactory("openai", (credentials) => {
10941
10961
  return new OpenAI({ apiKey: credentials.apiKey });
10942
10962
  });
10943
10963
 
10964
+ /**
10965
+ * dashboardRatingsUtils.js
10966
+ *
10967
+ * Pure utility functions for dashboard ratings logic.
10968
+ * No Electron or file I/O dependencies — safe to test anywhere.
10969
+ */
10970
+
10971
+ /**
10972
+ * Validate and build a rating entry.
10973
+ *
10974
+ * @param {string} packageName - Dashboard package name
10975
+ * @param {Object} rating - Rating input
10976
+ * @param {number} rating.stars - 1-5 star rating
10977
+ * @param {string} [rating.review] - Optional text review
10978
+ * @returns {Object} { success, rating, error }
10979
+ */
10980
+ function validateAndBuildRating$1(packageName, rating = {}) {
10981
+ if (!packageName) {
10982
+ return { success: false, error: "Package name is required" };
10983
+ }
10984
+
10985
+ const stars = Number(rating.stars);
10986
+ if (!stars || stars < 1 || stars > 5 || !Number.isInteger(stars)) {
10987
+ return {
10988
+ success: false,
10989
+ error: "Stars must be an integer between 1 and 5",
10990
+ };
10991
+ }
10992
+
10993
+ const entry = {
10994
+ stars,
10995
+ review:
10996
+ typeof rating.review === "string" ? rating.review.slice(0, 1000) : "",
10997
+ ratedAt: new Date().toISOString(),
10998
+ };
10999
+
11000
+ return { success: true, rating: entry };
11001
+ }
11002
+
11003
+ /**
11004
+ * Enrich packages with user rating data (pure function).
11005
+ *
11006
+ * @param {Array} packages - Registry packages
11007
+ * @param {Object} ratings - Map of packageName → rating data
11008
+ * @returns {Array} Packages with userRating field added
11009
+ */
11010
+ function enrichWithRatings$1(packages, ratings) {
11011
+ return packages.map((pkg) => ({
11012
+ ...pkg,
11013
+ userRating: ratings[pkg.name] || null,
11014
+ }));
11015
+ }
11016
+
11017
+ var dashboardRatingsUtils = {
11018
+ validateAndBuildRating: validateAndBuildRating$1,
11019
+ enrichWithRatings: enrichWithRatings$1,
11020
+ };
11021
+
11022
+ /**
11023
+ * dashboardRatingsController.js
11024
+ *
11025
+ * Local storage for dashboard ratings and reviews.
11026
+ * Stores user ratings per dashboard package in a JSON file.
11027
+ * Runs in the Electron main process.
11028
+ */
11029
+
11030
+ const { app } = require$$0$1;
11031
+ const path = require$$1$1;
11032
+ const { getFileContents, writeToFile } = file;
11033
+ const {
11034
+ validateAndBuildRating,
11035
+ enrichWithRatings,
11036
+ } = dashboardRatingsUtils;
11037
+
11038
+ const ratingsFilename = "dashboard-ratings.json";
11039
+ const appName = "Dashboard";
11040
+
11041
+ /**
11042
+ * Get the ratings file path for an app.
11043
+ */
11044
+ function getRatingsPath(appId) {
11045
+ return path.join(app.getPath("userData"), appName, appId, ratingsFilename);
11046
+ }
11047
+
11048
+ /**
11049
+ * Read all ratings from disk.
11050
+ */
11051
+ function readRatings(appId) {
11052
+ const filepath = getRatingsPath(appId);
11053
+ return getFileContents(filepath, {});
11054
+ }
11055
+
11056
+ /**
11057
+ * Write ratings to disk.
11058
+ */
11059
+ function writeRatings(appId, ratings) {
11060
+ const filepath = getRatingsPath(appId);
11061
+ writeToFile(filepath, JSON.stringify(ratings, null, 2));
11062
+ }
11063
+
11064
+ /**
11065
+ * Save or update a rating for a dashboard package.
11066
+ */
11067
+ function saveDashboardRating$1(appId, packageName, rating = {}) {
11068
+ const result = validateAndBuildRating(packageName, rating);
11069
+ if (!result.success) return result;
11070
+
11071
+ const ratings = readRatings(appId);
11072
+ ratings[packageName] = result.rating;
11073
+ writeRatings(appId, ratings);
11074
+
11075
+ return { success: true, rating: ratings[packageName] };
11076
+ }
11077
+
11078
+ /**
11079
+ * Get the user's rating for a specific dashboard package.
11080
+ */
11081
+ function getDashboardRating$1(appId, packageName) {
11082
+ const ratings = readRatings(appId);
11083
+ return ratings[packageName] || null;
11084
+ }
11085
+
11086
+ /**
11087
+ * Get all dashboard ratings.
11088
+ */
11089
+ function listDashboardRatings$1(appId) {
11090
+ return readRatings(appId);
11091
+ }
11092
+
11093
+ /**
11094
+ * Delete a rating for a dashboard package.
11095
+ */
11096
+ function deleteDashboardRating$1(appId, packageName) {
11097
+ const ratings = readRatings(appId);
11098
+ if (!ratings[packageName]) {
11099
+ return { success: false, error: "No rating found for this package" };
11100
+ }
11101
+ delete ratings[packageName];
11102
+ writeRatings(appId, ratings);
11103
+ return { success: true };
11104
+ }
11105
+
11106
+ /**
11107
+ * Enrich registry packages with local rating data.
11108
+ */
11109
+ function enrichPackagesWithRatings$1(packages, appId) {
11110
+ const ratings = readRatings(appId);
11111
+ return enrichWithRatings(packages, ratings);
11112
+ }
11113
+
11114
+ var dashboardRatingsController = {
11115
+ saveDashboardRating: saveDashboardRating$1,
11116
+ getDashboardRating: getDashboardRating$1,
11117
+ listDashboardRatings: listDashboardRatings$1,
11118
+ deleteDashboardRating: deleteDashboardRating$1,
11119
+ enrichPackagesWithRatings: enrichPackagesWithRatings$1,
11120
+ };
11121
+
10944
11122
  /**
10945
11123
  * Controller exports.
10946
11124
  */
@@ -11010,6 +11188,13 @@ const {
11010
11188
  checkDashboardUpdatesForApp,
11011
11189
  getProviderSetupManifest,
11012
11190
  } = dashboardConfigController$1;
11191
+ const {
11192
+ saveDashboardRating,
11193
+ getDashboardRating,
11194
+ listDashboardRatings,
11195
+ deleteDashboardRating,
11196
+ enrichPackagesWithRatings,
11197
+ } = dashboardRatingsController;
11013
11198
 
11014
11199
  var controller = {
11015
11200
  showDialog,
@@ -11060,9 +11245,14 @@ var controller = {
11060
11245
  getDashboardPreview,
11061
11246
  checkDashboardUpdatesForApp,
11062
11247
  getProviderSetupManifest,
11248
+ saveDashboardRating,
11249
+ getDashboardRating,
11250
+ listDashboardRatings,
11251
+ deleteDashboardRating,
11252
+ enrichPackagesWithRatings,
11063
11253
  };
11064
11254
 
11065
- const { ipcRenderer: ipcRenderer$i } = require$$0$1;
11255
+ const { ipcRenderer: ipcRenderer$j } = require$$0$1;
11066
11256
  const {
11067
11257
  SECURE_STORE_ENCRYPTION_CHECK,
11068
11258
  SECURE_STORE_SET_DATA,
@@ -11074,10 +11264,10 @@ const {
11074
11264
  */
11075
11265
  const secureStoreApi$2 = {
11076
11266
  isEncryptionAvailable: () =>
11077
- ipcRenderer$i.invoke(SECURE_STORE_ENCRYPTION_CHECK, {}),
11267
+ ipcRenderer$j.invoke(SECURE_STORE_ENCRYPTION_CHECK, {}),
11078
11268
  saveData: (key, value) =>
11079
- ipcRenderer$i.invoke(SECURE_STORE_SET_DATA, { key, value }),
11080
- getData: (key) => ipcRenderer$i.invoke(SECURE_STORE_GET_DATA, { key }),
11269
+ ipcRenderer$j.invoke(SECURE_STORE_SET_DATA, { key, value }),
11270
+ getData: (key) => ipcRenderer$j.invoke(SECURE_STORE_GET_DATA, { key }),
11081
11271
  };
11082
11272
 
11083
11273
  var secureStoreApi_1 = secureStoreApi$2;
@@ -11088,7 +11278,7 @@ var secureStoreApi_1 = secureStoreApi$2;
11088
11278
  * Handle the workspace configuration file
11089
11279
  */
11090
11280
 
11091
- const { ipcRenderer: ipcRenderer$h } = require$$0$1;
11281
+ const { ipcRenderer: ipcRenderer$i } = require$$0$1;
11092
11282
  const {
11093
11283
  WORKSPACE_LIST,
11094
11284
  WORKSPACE_SAVE,
@@ -11105,7 +11295,7 @@ const workspaceApi$2 = {
11105
11295
  */
11106
11296
  listWorkspacesForApplication: (appId) => {
11107
11297
  console.log("listWorkspacesForApplication called with appId:", appId);
11108
- return ipcRenderer$h.invoke(WORKSPACE_LIST, { appId });
11298
+ return ipcRenderer$i.invoke(WORKSPACE_LIST, { appId });
11109
11299
  },
11110
11300
 
11111
11301
  /**
@@ -11116,7 +11306,7 @@ const workspaceApi$2 = {
11116
11306
  * @returns
11117
11307
  */
11118
11308
  saveWorkspaceForApplication: (appId, data) =>
11119
- ipcRenderer$h.invoke(WORKSPACE_SAVE, { appId, data }),
11309
+ ipcRenderer$i.invoke(WORKSPACE_SAVE, { appId, data }),
11120
11310
 
11121
11311
  /**
11122
11312
  * deleteWorkspaceForApplication
@@ -11126,7 +11316,7 @@ const workspaceApi$2 = {
11126
11316
  * @returns
11127
11317
  */
11128
11318
  deleteWorkspaceForApplication: (appId, workspaceId) =>
11129
- ipcRenderer$h.invoke(WORKSPACE_DELETE, { appId, workspaceId }),
11319
+ ipcRenderer$i.invoke(WORKSPACE_DELETE, { appId, workspaceId }),
11130
11320
  };
11131
11321
 
11132
11322
  var workspaceApi_1 = workspaceApi$2;
@@ -11138,15 +11328,15 @@ var workspaceApi_1 = workspaceApi$2;
11138
11328
  */
11139
11329
 
11140
11330
  // ipcRenderer that must be used to invoke the events
11141
- const { ipcRenderer: ipcRenderer$g } = require$$0$1;
11331
+ const { ipcRenderer: ipcRenderer$h } = require$$0$1;
11142
11332
 
11143
11333
  const { LAYOUT_LIST, LAYOUT_SAVE } = events$8;
11144
11334
 
11145
11335
  const layoutApi$2 = {
11146
11336
  listLayoutsForApplication: (appId) =>
11147
- ipcRenderer$g.invoke(LAYOUT_LIST, { appId }),
11337
+ ipcRenderer$h.invoke(LAYOUT_LIST, { appId }),
11148
11338
  saveLayoutForApplication: (appId, data) =>
11149
- ipcRenderer$g.invoke(LAYOUT_SAVE, { appId, data }),
11339
+ ipcRenderer$h.invoke(LAYOUT_SAVE, { appId, data }),
11150
11340
  };
11151
11341
 
11152
11342
  var layoutApi_1 = layoutApi$2;
@@ -11158,7 +11348,7 @@ var layoutApi_1 = layoutApi$2;
11158
11348
  */
11159
11349
 
11160
11350
  // ipcRenderer that must be used to invoke the events
11161
- const { ipcRenderer: ipcRenderer$f } = require$$0$1;
11351
+ const { ipcRenderer: ipcRenderer$g } = require$$0$1;
11162
11352
 
11163
11353
  const {
11164
11354
  DATA_JSON_TO_CSV_FILE,
@@ -11177,7 +11367,7 @@ const {
11177
11367
  const dataApi$2 = {
11178
11368
  // convert a json array of objects to a csv string and save to file
11179
11369
  convertJsonToCsvFile: (appId, jsonObject, filename) =>
11180
- ipcRenderer$f.invoke(DATA_JSON_TO_CSV_FILE, {
11370
+ ipcRenderer$g.invoke(DATA_JSON_TO_CSV_FILE, {
11181
11371
  appId,
11182
11372
  jsonObject,
11183
11373
  filename,
@@ -11185,10 +11375,10 @@ const dataApi$2 = {
11185
11375
 
11186
11376
  // convert a json array of objects to a csv string and return a string
11187
11377
  convertJsonToCsvString: (appId, jsonObject) =>
11188
- ipcRenderer$f.invoke(DATA_JSON_TO_CSV_STRING, { appId, jsonObject }),
11378
+ ipcRenderer$g.invoke(DATA_JSON_TO_CSV_STRING, { appId, jsonObject }),
11189
11379
 
11190
11380
  parseXMLStream: (filepath, outpath, start) =>
11191
- ipcRenderer$f.invoke(PARSE_XML_STREAM, {
11381
+ ipcRenderer$g.invoke(PARSE_XML_STREAM, {
11192
11382
  filepath,
11193
11383
  outpath,
11194
11384
  start,
@@ -11202,7 +11392,7 @@ const dataApi$2 = {
11202
11392
  headers = null,
11203
11393
  limit = null,
11204
11394
  ) => {
11205
- ipcRenderer$f.invoke(PARSE_CSV_STREAM, {
11395
+ ipcRenderer$g.invoke(PARSE_CSV_STREAM, {
11206
11396
  filepath,
11207
11397
  outpath,
11208
11398
  delimiter,
@@ -11213,15 +11403,15 @@ const dataApi$2 = {
11213
11403
  },
11214
11404
 
11215
11405
  readLinesFromFile: (filepath, lineCount) => {
11216
- ipcRenderer$f.invoke(READ_LINES, { filepath, lineCount });
11406
+ ipcRenderer$g.invoke(READ_LINES, { filepath, lineCount });
11217
11407
  },
11218
11408
 
11219
11409
  readJSONFromFile: (filepath, objectCount = null) => {
11220
- ipcRenderer$f.invoke(READ_JSON, { filepath, objectCount });
11410
+ ipcRenderer$g.invoke(READ_JSON, { filepath, objectCount });
11221
11411
  },
11222
11412
 
11223
11413
  readDataFromURL: (url, toFilepath) => {
11224
- ipcRenderer$f.invoke(READ_DATA_URL, { url, toFilepath });
11414
+ ipcRenderer$g.invoke(READ_DATA_URL, { url, toFilepath });
11225
11415
  },
11226
11416
 
11227
11417
  /*
@@ -11230,7 +11420,7 @@ const dataApi$2 = {
11230
11420
  * @param {object} returnEmpty the return empty object
11231
11421
  */
11232
11422
  saveData: (data, filename, append, returnEmpty, uuid) =>
11233
- ipcRenderer$f.invoke(DATA_SAVE_TO_FILE, {
11423
+ ipcRenderer$g.invoke(DATA_SAVE_TO_FILE, {
11234
11424
  data,
11235
11425
  filename,
11236
11426
  append,
@@ -11242,14 +11432,14 @@ const dataApi$2 = {
11242
11432
  * @param {string} filename the filename to read (not path)
11243
11433
  */
11244
11434
  readData: (filename, returnEmpty = []) =>
11245
- ipcRenderer$f.invoke(DATA_READ_FROM_FILE, { filename, returnEmpty }),
11435
+ ipcRenderer$g.invoke(DATA_READ_FROM_FILE, { filename, returnEmpty }),
11246
11436
 
11247
11437
  /**
11248
11438
  * transformFile
11249
11439
  * @returns
11250
11440
  */
11251
11441
  transformFile: (filepath, outFilepath, mappingFunctionBody, args) => {
11252
- ipcRenderer$f.invoke(TRANSFORM_FILE, {
11442
+ ipcRenderer$g.invoke(TRANSFORM_FILE, {
11253
11443
  filepath,
11254
11444
  outFilepath,
11255
11445
  mappingFunctionBody,
@@ -11258,7 +11448,7 @@ const dataApi$2 = {
11258
11448
  },
11259
11449
 
11260
11450
  extractColorsFromImageURL: (url) => {
11261
- ipcRenderer$f.invoke(EXTRACT_COLORS_FROM_IMAGE, {
11451
+ ipcRenderer$g.invoke(EXTRACT_COLORS_FROM_IMAGE, {
11262
11452
  url,
11263
11453
  });
11264
11454
  },
@@ -11273,7 +11463,7 @@ var dataApi_1 = dataApi$2;
11273
11463
  */
11274
11464
 
11275
11465
  // ipcRenderer that must be used to invoke the events
11276
- const { ipcRenderer: ipcRenderer$e } = require$$0$1;
11466
+ const { ipcRenderer: ipcRenderer$f } = require$$0$1;
11277
11467
 
11278
11468
  const {
11279
11469
  SETTINGS_GET,
@@ -11284,14 +11474,14 @@ const {
11284
11474
  } = events$8;
11285
11475
 
11286
11476
  const settingsApi$2 = {
11287
- getSettingsForApplication: () => ipcRenderer$e.invoke(SETTINGS_GET, {}),
11477
+ getSettingsForApplication: () => ipcRenderer$f.invoke(SETTINGS_GET, {}),
11288
11478
  saveSettingsForApplication: (data) =>
11289
- ipcRenderer$e.invoke(SETTINGS_SAVE, { data }),
11290
- getDataDirectory: () => ipcRenderer$e.invoke(SETTINGS_GET_DATA_DIR, {}),
11479
+ ipcRenderer$f.invoke(SETTINGS_SAVE, { data }),
11480
+ getDataDirectory: () => ipcRenderer$f.invoke(SETTINGS_GET_DATA_DIR, {}),
11291
11481
  setDataDirectory: (dataDirectory) =>
11292
- ipcRenderer$e.invoke(SETTINGS_SET_DATA_DIR, { dataDirectory }),
11482
+ ipcRenderer$f.invoke(SETTINGS_SET_DATA_DIR, { dataDirectory }),
11293
11483
  migrateDataDirectory: (oldDirectory, newDirectory) =>
11294
- ipcRenderer$e.invoke(SETTINGS_MIGRATE_DATA_DIR, {
11484
+ ipcRenderer$f.invoke(SETTINGS_MIGRATE_DATA_DIR, {
11295
11485
  oldDirectory,
11296
11486
  newDirectory,
11297
11487
  }),
@@ -11306,7 +11496,7 @@ var settingsApi_1 = settingsApi$2;
11306
11496
  */
11307
11497
 
11308
11498
  // ipcRenderer that must be used to invoke the events
11309
- const { ipcRenderer: ipcRenderer$d } = require$$0$1;
11499
+ const { ipcRenderer: ipcRenderer$e } = require$$0$1;
11310
11500
 
11311
11501
  const { CHOOSE_FILE } = events$8;
11312
11502
 
@@ -11318,7 +11508,7 @@ const dialogApi$2 = {
11318
11508
  */
11319
11509
  chooseFile: (allowFile = true, extensions = ["*"]) => {
11320
11510
  console.log("dialog api choose file");
11321
- return ipcRenderer$d.invoke(CHOOSE_FILE, { allowFile, extensions });
11511
+ return ipcRenderer$e.invoke(CHOOSE_FILE, { allowFile, extensions });
11322
11512
  },
11323
11513
  };
11324
11514
 
@@ -11337,7 +11527,7 @@ var dialogApi_1 = dialogApi$2;
11337
11527
  * mainApi.widgets.uninstall('Weather')
11338
11528
  */
11339
11529
 
11340
- const { ipcRenderer: ipcRenderer$c } = require$$0$1;
11530
+ const { ipcRenderer: ipcRenderer$d } = require$$0$1;
11341
11531
 
11342
11532
  const widgetApi$2 = {
11343
11533
  /**
@@ -11346,7 +11536,7 @@ const widgetApi$2 = {
11346
11536
  */
11347
11537
  list: async () => {
11348
11538
  try {
11349
- return await ipcRenderer$c.invoke("widget:list");
11539
+ return await ipcRenderer$d.invoke("widget:list");
11350
11540
  } catch (error) {
11351
11541
  console.error("[WidgetApi] Error listing widgets:", error);
11352
11542
  throw error;
@@ -11360,7 +11550,7 @@ const widgetApi$2 = {
11360
11550
  */
11361
11551
  get: async (widgetName) => {
11362
11552
  try {
11363
- return await ipcRenderer$c.invoke("widget:get", widgetName);
11553
+ return await ipcRenderer$d.invoke("widget:get", widgetName);
11364
11554
  } catch (error) {
11365
11555
  console.error(`[WidgetApi] Error getting widget ${widgetName}:`, error);
11366
11556
  throw error;
@@ -11391,7 +11581,7 @@ const widgetApi$2 = {
11391
11581
  console.log(
11392
11582
  `[WidgetApi] Installing widget: ${widgetName} from ${downloadUrl}`,
11393
11583
  );
11394
- const config = await ipcRenderer$c.invoke(
11584
+ const config = await ipcRenderer$d.invoke(
11395
11585
  "widget:install",
11396
11586
  widgetName,
11397
11587
  downloadUrl,
@@ -11431,7 +11621,7 @@ const widgetApi$2 = {
11431
11621
  console.log(
11432
11622
  `[WidgetApi] Installing local widget: ${widgetName} from ${localPath}`,
11433
11623
  );
11434
- const config = await ipcRenderer$c.invoke(
11624
+ const config = await ipcRenderer$d.invoke(
11435
11625
  "widget:install-local",
11436
11626
  widgetName,
11437
11627
  localPath,
@@ -11462,7 +11652,7 @@ const widgetApi$2 = {
11462
11652
  loadFolder: async (folderPath) => {
11463
11653
  try {
11464
11654
  console.log(`[WidgetApi] Loading widgets from folder: ${folderPath}`);
11465
- const results = await ipcRenderer$c.invoke(
11655
+ const results = await ipcRenderer$d.invoke(
11466
11656
  "widget:load-folder",
11467
11657
  folderPath,
11468
11658
  );
@@ -11486,7 +11676,7 @@ const widgetApi$2 = {
11486
11676
  uninstall: async (widgetName) => {
11487
11677
  try {
11488
11678
  console.log(`[WidgetApi] Uninstalling widget: ${widgetName}`);
11489
- const success = await ipcRenderer$c.invoke("widget:uninstall", widgetName);
11679
+ const success = await ipcRenderer$d.invoke("widget:uninstall", widgetName);
11490
11680
  if (success) {
11491
11681
  console.log(`[WidgetApi] ✓ Widget ${widgetName} uninstalled`);
11492
11682
  } else {
@@ -11509,7 +11699,7 @@ const widgetApi$2 = {
11509
11699
  */
11510
11700
  getCachePath: async () => {
11511
11701
  try {
11512
- return await ipcRenderer$c.invoke("widget:cache-path");
11702
+ return await ipcRenderer$d.invoke("widget:cache-path");
11513
11703
  } catch (error) {
11514
11704
  console.error("[WidgetApi] Error getting cache path:", error);
11515
11705
  throw error;
@@ -11523,7 +11713,7 @@ const widgetApi$2 = {
11523
11713
  */
11524
11714
  getStoragePath: async () => {
11525
11715
  try {
11526
- return await ipcRenderer$c.invoke("widget:storage-path");
11716
+ return await ipcRenderer$d.invoke("widget:storage-path");
11527
11717
  } catch (error) {
11528
11718
  console.error("[WidgetApi] Error getting storage path:", error);
11529
11719
  throw error;
@@ -11540,7 +11730,7 @@ const widgetApi$2 = {
11540
11730
  setStoragePath: async (customPath) => {
11541
11731
  try {
11542
11732
  console.log(`[WidgetApi] Setting storage path to: ${customPath}`);
11543
- const result = await ipcRenderer$c.invoke(
11733
+ const result = await ipcRenderer$d.invoke(
11544
11734
  "widget:set-storage-path",
11545
11735
  customPath,
11546
11736
  );
@@ -11562,7 +11752,7 @@ const widgetApi$2 = {
11562
11752
  */
11563
11753
  getComponentConfigs: async () => {
11564
11754
  try {
11565
- return await ipcRenderer$c.invoke("widget:get-component-configs");
11755
+ return await ipcRenderer$d.invoke("widget:get-component-configs");
11566
11756
  } catch (error) {
11567
11757
  console.error("[WidgetApi] Error getting component configs:", error);
11568
11758
  return [];
@@ -11577,7 +11767,7 @@ const widgetApi$2 = {
11577
11767
  */
11578
11768
  readBundle: async (widgetName) => {
11579
11769
  try {
11580
- return await ipcRenderer$c.invoke("widget:read-bundle", widgetName);
11770
+ return await ipcRenderer$d.invoke("widget:read-bundle", widgetName);
11581
11771
  } catch (error) {
11582
11772
  console.error(
11583
11773
  `[WidgetApi] Error reading bundle for ${widgetName}:`,
@@ -11594,7 +11784,7 @@ const widgetApi$2 = {
11594
11784
  */
11595
11785
  readAllBundles: async () => {
11596
11786
  try {
11597
- return await ipcRenderer$c.invoke("widget:read-all-bundles");
11787
+ return await ipcRenderer$d.invoke("widget:read-all-bundles");
11598
11788
  } catch (error) {
11599
11789
  console.error("[WidgetApi] Error reading all bundles:", error);
11600
11790
  return [];
@@ -11614,7 +11804,7 @@ const widgetApi$2 = {
11614
11804
  * });
11615
11805
  */
11616
11806
  onInstalled: (callback) => {
11617
- ipcRenderer$c.on("widget:installed", (event, data) => {
11807
+ ipcRenderer$d.on("widget:installed", (event, data) => {
11618
11808
  callback(data);
11619
11809
  });
11620
11810
  },
@@ -11632,7 +11822,7 @@ const widgetApi$2 = {
11632
11822
  * });
11633
11823
  */
11634
11824
  onLoaded: (callback) => {
11635
- ipcRenderer$c.on("widgets:loaded", (event, data) => {
11825
+ ipcRenderer$d.on("widgets:loaded", (event, data) => {
11636
11826
  callback(data);
11637
11827
  });
11638
11828
  },
@@ -11643,7 +11833,7 @@ const widgetApi$2 = {
11643
11833
  * @param {Function} callback - The callback to remove
11644
11834
  */
11645
11835
  removeInstalledListener: (callback) => {
11646
- ipcRenderer$c.removeListener("widget:installed", callback);
11836
+ ipcRenderer$d.removeListener("widget:installed", callback);
11647
11837
  },
11648
11838
 
11649
11839
  /**
@@ -11652,7 +11842,7 @@ const widgetApi$2 = {
11652
11842
  * @param {Function} callback - The callback to remove
11653
11843
  */
11654
11844
  removeLoadedListener: (callback) => {
11655
- ipcRenderer$c.removeListener("widgets:loaded", callback);
11845
+ ipcRenderer$d.removeListener("widgets:loaded", callback);
11656
11846
  },
11657
11847
  };
11658
11848
 
@@ -11665,7 +11855,7 @@ var widgetApi_1 = widgetApi$2;
11665
11855
  * Communicates with main process via IPC to handle encryption and file storage
11666
11856
  */
11667
11857
 
11668
- const { ipcRenderer: ipcRenderer$b } = require$$0$1;
11858
+ const { ipcRenderer: ipcRenderer$c } = require$$0$1;
11669
11859
  const {
11670
11860
  PROVIDER_SAVE,
11671
11861
  PROVIDER_LIST,
@@ -11697,7 +11887,7 @@ const providerApi$2 = {
11697
11887
  mcpConfig = null,
11698
11888
  allowedTools = null,
11699
11889
  ) =>
11700
- ipcRenderer$b.invoke(PROVIDER_SAVE, {
11890
+ ipcRenderer$c.invoke(PROVIDER_SAVE, {
11701
11891
  appId,
11702
11892
  providerName,
11703
11893
  providerType,
@@ -11715,7 +11905,7 @@ const providerApi$2 = {
11715
11905
  * @param {String} appId - the appId specified in the dash initialization
11716
11906
  * @returns {Promise<Array>} Array of provider objects with name, type, credentials
11717
11907
  */
11718
- listProviders: (appId) => ipcRenderer$b.invoke(PROVIDER_LIST, { appId }),
11908
+ listProviders: (appId) => ipcRenderer$c.invoke(PROVIDER_LIST, { appId }),
11719
11909
 
11720
11910
  /**
11721
11911
  * getProvider
@@ -11727,7 +11917,7 @@ const providerApi$2 = {
11727
11917
  * @returns {Promise<Object>} Provider object with name, type, credentials
11728
11918
  */
11729
11919
  getProvider: (appId, providerName) =>
11730
- ipcRenderer$b.invoke(PROVIDER_GET, { appId, providerName }),
11920
+ ipcRenderer$c.invoke(PROVIDER_GET, { appId, providerName }),
11731
11921
 
11732
11922
  /**
11733
11923
  * deleteProvider
@@ -11739,7 +11929,7 @@ const providerApi$2 = {
11739
11929
  * @returns {Promise}
11740
11930
  */
11741
11931
  deleteProvider: (appId, providerName) =>
11742
- ipcRenderer$b.invoke(PROVIDER_DELETE, { appId, providerName }),
11932
+ ipcRenderer$c.invoke(PROVIDER_DELETE, { appId, providerName }),
11743
11933
 
11744
11934
  /**
11745
11935
  * listProvidersForApplication
@@ -11749,14 +11939,14 @@ const providerApi$2 = {
11749
11939
  * @param {String} appId - the appId specified in the dash initialization
11750
11940
  */
11751
11941
  listProvidersForApplication: (appId) => {
11752
- ipcRenderer$b
11942
+ ipcRenderer$c
11753
11943
  .invoke(PROVIDER_LIST, { appId })
11754
11944
  .then((result) => {
11755
11945
  // Emit the event for ElectronDashboardApi to listen to
11756
- ipcRenderer$b.send("PROVIDER_LIST_COMPLETE", result);
11946
+ ipcRenderer$c.send("PROVIDER_LIST_COMPLETE", result);
11757
11947
  })
11758
11948
  .catch((error) => {
11759
- ipcRenderer$b.send("PROVIDER_LIST_ERROR", {
11949
+ ipcRenderer$c.send("PROVIDER_LIST_ERROR", {
11760
11950
  error: error.message,
11761
11951
  });
11762
11952
  });
@@ -11773,7 +11963,7 @@ const providerApi$2 = {
11773
11963
  providerType,
11774
11964
  credentials,
11775
11965
  ) => {
11776
- ipcRenderer$b
11966
+ ipcRenderer$c
11777
11967
  .invoke(PROVIDER_SAVE, {
11778
11968
  appId,
11779
11969
  providerName,
@@ -11781,10 +11971,10 @@ const providerApi$2 = {
11781
11971
  credentials,
11782
11972
  })
11783
11973
  .then((result) => {
11784
- ipcRenderer$b.send("PROVIDER_SAVE_COMPLETE", result);
11974
+ ipcRenderer$c.send("PROVIDER_SAVE_COMPLETE", result);
11785
11975
  })
11786
11976
  .catch((error) => {
11787
- ipcRenderer$b.send("PROVIDER_SAVE_ERROR", {
11977
+ ipcRenderer$c.send("PROVIDER_SAVE_ERROR", {
11788
11978
  error: error.message,
11789
11979
  });
11790
11980
  });
@@ -11796,13 +11986,13 @@ const providerApi$2 = {
11796
11986
  * Event-listener-based version for use with ElectronDashboardApi
11797
11987
  */
11798
11988
  getProviderForApplication: (appId, providerName) => {
11799
- ipcRenderer$b
11989
+ ipcRenderer$c
11800
11990
  .invoke(PROVIDER_GET, { appId, providerName })
11801
11991
  .then((result) => {
11802
- ipcRenderer$b.send("PROVIDER_GET_COMPLETE", result);
11992
+ ipcRenderer$c.send("PROVIDER_GET_COMPLETE", result);
11803
11993
  })
11804
11994
  .catch((error) => {
11805
- ipcRenderer$b.send("PROVIDER_GET_ERROR", {
11995
+ ipcRenderer$c.send("PROVIDER_GET_ERROR", {
11806
11996
  error: error.message,
11807
11997
  });
11808
11998
  });
@@ -11814,13 +12004,13 @@ const providerApi$2 = {
11814
12004
  * Event-listener-based version for use with ElectronDashboardApi
11815
12005
  */
11816
12006
  deleteProviderForApplication: (appId, providerName) => {
11817
- ipcRenderer$b
12007
+ ipcRenderer$c
11818
12008
  .invoke(PROVIDER_DELETE, { appId, providerName })
11819
12009
  .then((result) => {
11820
- ipcRenderer$b.send("PROVIDER_DELETE_COMPLETE", result);
12010
+ ipcRenderer$c.send("PROVIDER_DELETE_COMPLETE", result);
11821
12011
  })
11822
12012
  .catch((error) => {
11823
- ipcRenderer$b.send("PROVIDER_DELETE_ERROR", {
12013
+ ipcRenderer$c.send("PROVIDER_DELETE_ERROR", {
11824
12014
  error: error.message,
11825
12015
  });
11826
12016
  });
@@ -11836,7 +12026,7 @@ var providerApi_1 = providerApi$2;
11836
12026
  * Communicates with main process via IPC to manage MCP server lifecycle.
11837
12027
  */
11838
12028
 
11839
- const { ipcRenderer: ipcRenderer$a } = require$$0$1;
12029
+ const { ipcRenderer: ipcRenderer$b } = require$$0$1;
11840
12030
  const {
11841
12031
  MCP_START_SERVER,
11842
12032
  MCP_STOP_SERVER,
@@ -11860,7 +12050,7 @@ const mcpApi$2 = {
11860
12050
  * @returns {Promise<{ success, serverName, tools, status } | { error, message }>}
11861
12051
  */
11862
12052
  startServer: (serverName, mcpConfig, credentials) =>
11863
- ipcRenderer$a.invoke(MCP_START_SERVER, {
12053
+ ipcRenderer$b.invoke(MCP_START_SERVER, {
11864
12054
  serverName,
11865
12055
  mcpConfig,
11866
12056
  credentials,
@@ -11874,7 +12064,7 @@ const mcpApi$2 = {
11874
12064
  * @returns {Promise<{ success, serverName } | { error, message }>}
11875
12065
  */
11876
12066
  stopServer: (serverName) =>
11877
- ipcRenderer$a.invoke(MCP_STOP_SERVER, { serverName }),
12067
+ ipcRenderer$b.invoke(MCP_STOP_SERVER, { serverName }),
11878
12068
 
11879
12069
  /**
11880
12070
  * listTools
@@ -11883,7 +12073,7 @@ const mcpApi$2 = {
11883
12073
  * @param {string} serverName the server name
11884
12074
  * @returns {Promise<{ tools } | { error, message }>}
11885
12075
  */
11886
- listTools: (serverName) => ipcRenderer$a.invoke(MCP_LIST_TOOLS, { serverName }),
12076
+ listTools: (serverName) => ipcRenderer$b.invoke(MCP_LIST_TOOLS, { serverName }),
11887
12077
 
11888
12078
  /**
11889
12079
  * callTool
@@ -11896,7 +12086,7 @@ const mcpApi$2 = {
11896
12086
  * @returns {Promise<{ result } | { error, message }>}
11897
12087
  */
11898
12088
  callTool: (serverName, toolName, args, allowedTools = null) =>
11899
- ipcRenderer$a.invoke(MCP_CALL_TOOL, {
12089
+ ipcRenderer$b.invoke(MCP_CALL_TOOL, {
11900
12090
  serverName,
11901
12091
  toolName,
11902
12092
  args,
@@ -11911,7 +12101,7 @@ const mcpApi$2 = {
11911
12101
  * @returns {Promise<{ resources } | { error, message }>}
11912
12102
  */
11913
12103
  listResources: (serverName) =>
11914
- ipcRenderer$a.invoke(MCP_LIST_RESOURCES, { serverName }),
12104
+ ipcRenderer$b.invoke(MCP_LIST_RESOURCES, { serverName }),
11915
12105
 
11916
12106
  /**
11917
12107
  * readResource
@@ -11922,7 +12112,7 @@ const mcpApi$2 = {
11922
12112
  * @returns {Promise<{ resource } | { error, message }>}
11923
12113
  */
11924
12114
  readResource: (serverName, uri) =>
11925
- ipcRenderer$a.invoke(MCP_READ_RESOURCE, { serverName, uri }),
12115
+ ipcRenderer$b.invoke(MCP_READ_RESOURCE, { serverName, uri }),
11926
12116
 
11927
12117
  /**
11928
12118
  * getServerStatus
@@ -11932,7 +12122,7 @@ const mcpApi$2 = {
11932
12122
  * @returns {Promise<{ status, tools, error }>}
11933
12123
  */
11934
12124
  getServerStatus: (serverName) =>
11935
- ipcRenderer$a.invoke(MCP_SERVER_STATUS, { serverName }),
12125
+ ipcRenderer$b.invoke(MCP_SERVER_STATUS, { serverName }),
11936
12126
 
11937
12127
  /**
11938
12128
  * getCatalog
@@ -11940,7 +12130,7 @@ const mcpApi$2 = {
11940
12130
  *
11941
12131
  * @returns {Promise<{ catalog } | { error, message }>}
11942
12132
  */
11943
- getCatalog: () => ipcRenderer$a.invoke(MCP_GET_CATALOG),
12133
+ getCatalog: () => ipcRenderer$b.invoke(MCP_GET_CATALOG),
11944
12134
 
11945
12135
  /**
11946
12136
  * runAuth
@@ -11952,7 +12142,7 @@ const mcpApi$2 = {
11952
12142
  * @returns {Promise<{ success } | { error, message }>}
11953
12143
  */
11954
12144
  runAuth: (mcpConfig, credentials, authCommand) =>
11955
- ipcRenderer$a.invoke(MCP_RUN_AUTH, { mcpConfig, credentials, authCommand }),
12145
+ ipcRenderer$b.invoke(MCP_RUN_AUTH, { mcpConfig, credentials, authCommand }),
11956
12146
  };
11957
12147
 
11958
12148
  var mcpApi_1 = mcpApi$2;
@@ -11970,7 +12160,7 @@ var mcpApi_1 = mcpApi$2;
11970
12160
  * mainApi.registry.checkUpdates([{ name: "weather-widgets", version: "1.0.0" }])
11971
12161
  */
11972
12162
 
11973
- const { ipcRenderer: ipcRenderer$9 } = require$$0$1;
12163
+ const { ipcRenderer: ipcRenderer$a } = require$$0$1;
11974
12164
 
11975
12165
  const registryApi$2 = {
11976
12166
  /**
@@ -11980,7 +12170,7 @@ const registryApi$2 = {
11980
12170
  */
11981
12171
  fetchIndex: async (forceRefresh = false) => {
11982
12172
  try {
11983
- return await ipcRenderer$9.invoke("registry:fetch-index", forceRefresh);
12173
+ return await ipcRenderer$a.invoke("registry:fetch-index", forceRefresh);
11984
12174
  } catch (error) {
11985
12175
  console.error("[RegistryApi] Error fetching index:", error);
11986
12176
  throw error;
@@ -11995,7 +12185,7 @@ const registryApi$2 = {
11995
12185
  */
11996
12186
  search: async (query = "", filters = {}) => {
11997
12187
  try {
11998
- return await ipcRenderer$9.invoke("registry:search", query, filters);
12188
+ return await ipcRenderer$a.invoke("registry:search", query, filters);
11999
12189
  } catch (error) {
12000
12190
  console.error("[RegistryApi] Error searching registry:", error);
12001
12191
  throw error;
@@ -12009,7 +12199,7 @@ const registryApi$2 = {
12009
12199
  */
12010
12200
  getPackage: async (packageName) => {
12011
12201
  try {
12012
- return await ipcRenderer$9.invoke("registry:get-package", packageName);
12202
+ return await ipcRenderer$a.invoke("registry:get-package", packageName);
12013
12203
  } catch (error) {
12014
12204
  console.error(
12015
12205
  `[RegistryApi] Error getting package ${packageName}:`,
@@ -12026,7 +12216,7 @@ const registryApi$2 = {
12026
12216
  */
12027
12217
  checkUpdates: async (installedWidgets = []) => {
12028
12218
  try {
12029
- return await ipcRenderer$9.invoke(
12219
+ return await ipcRenderer$a.invoke(
12030
12220
  "registry:check-updates",
12031
12221
  installedWidgets,
12032
12222
  );
@@ -12044,7 +12234,7 @@ const registryApi$2 = {
12044
12234
  */
12045
12235
  searchDashboards: async (query = "", filters = {}) => {
12046
12236
  try {
12047
- return await ipcRenderer$9.invoke(
12237
+ return await ipcRenderer$a.invoke(
12048
12238
  "registry:search-dashboards",
12049
12239
  query,
12050
12240
  filters,
@@ -12064,17 +12254,17 @@ var registryApi_1 = registryApi$2;
12064
12254
  * Handle the theme configuration file
12065
12255
  */
12066
12256
 
12067
- const { ipcRenderer: ipcRenderer$8 } = require$$0$1;
12257
+ const { ipcRenderer: ipcRenderer$9 } = require$$0$1;
12068
12258
 
12069
12259
  const { THEME_LIST, THEME_SAVE, THEME_DELETE } = events$8;
12070
12260
 
12071
12261
  const themeApi$2 = {
12072
12262
  listThemesForApplication: (appId) =>
12073
- ipcRenderer$8.invoke(THEME_LIST, { appId }),
12263
+ ipcRenderer$9.invoke(THEME_LIST, { appId }),
12074
12264
  saveThemeForApplication: (appId, themeName, themeObject) =>
12075
- ipcRenderer$8.invoke(THEME_SAVE, { appId, themeName, themeObject }),
12265
+ ipcRenderer$9.invoke(THEME_SAVE, { appId, themeName, themeObject }),
12076
12266
  deleteThemeForApplication: (appId, themeKey) =>
12077
- ipcRenderer$8.invoke(THEME_DELETE, { appId, themeKey }),
12267
+ ipcRenderer$9.invoke(THEME_DELETE, { appId, themeKey }),
12078
12268
  };
12079
12269
 
12080
12270
  var themeApi_1 = themeApi$2;
@@ -12086,7 +12276,7 @@ var themeApi_1 = themeApi$2;
12086
12276
  */
12087
12277
 
12088
12278
  // ipcRenderer that must be used to invoke the events
12089
- const { ipcRenderer: ipcRenderer$7 } = require$$0$1;
12279
+ const { ipcRenderer: ipcRenderer$8 } = require$$0$1;
12090
12280
 
12091
12281
  const {
12092
12282
  ALGOLIA_LIST_INDICES,
@@ -12100,10 +12290,10 @@ const {
12100
12290
 
12101
12291
  const algoliaApi$2 = {
12102
12292
  listIndices: (application) =>
12103
- ipcRenderer$7.invoke(ALGOLIA_LIST_INDICES, application),
12293
+ ipcRenderer$8.invoke(ALGOLIA_LIST_INDICES, application),
12104
12294
 
12105
12295
  browseObjects: (appId, apiKey, indexName) => {
12106
- ipcRenderer$7.invoke(ALGOLIA_BROWSE_OBJECTS, {
12296
+ ipcRenderer$8.invoke(ALGOLIA_BROWSE_OBJECTS, {
12107
12297
  appId,
12108
12298
  apiKey,
12109
12299
  indexName,
@@ -12111,10 +12301,10 @@ const algoliaApi$2 = {
12111
12301
  });
12112
12302
  },
12113
12303
 
12114
- saveSynonyms: () => ipcRenderer$7.invoke(ALGOLIA_SAVE_SYNONYMS, {}),
12304
+ saveSynonyms: () => ipcRenderer$8.invoke(ALGOLIA_SAVE_SYNONYMS, {}),
12115
12305
 
12116
12306
  getAnalyticsForQuery: (application, indexName, query) =>
12117
- ipcRenderer$7.invoke(ALGOLIA_ANALYTICS_FOR_QUERY, {
12307
+ ipcRenderer$8.invoke(ALGOLIA_ANALYTICS_FOR_QUERY, {
12118
12308
  application,
12119
12309
  indexName,
12120
12310
  query,
@@ -12127,7 +12317,7 @@ const algoliaApi$2 = {
12127
12317
  dir,
12128
12318
  createIfNotExists = false,
12129
12319
  ) =>
12130
- ipcRenderer$7.invoke(ALGOLIA_PARTIAL_UPDATE_OBJECTS, {
12320
+ ipcRenderer$8.invoke(ALGOLIA_PARTIAL_UPDATE_OBJECTS, {
12131
12321
  appId,
12132
12322
  apiKey,
12133
12323
  indexName,
@@ -12136,7 +12326,7 @@ const algoliaApi$2 = {
12136
12326
  }),
12137
12327
 
12138
12328
  createBatchesFromFile: (filepath, batchFilepath, batchSize) => {
12139
- ipcRenderer$7.invoke(ALGOLIA_CREATE_BATCH, {
12329
+ ipcRenderer$8.invoke(ALGOLIA_CREATE_BATCH, {
12140
12330
  filepath,
12141
12331
  batchFilepath,
12142
12332
  batchSize,
@@ -12144,7 +12334,7 @@ const algoliaApi$2 = {
12144
12334
  },
12145
12335
 
12146
12336
  browseObjectsToFile: (appId, apiKey, indexName, toFilename, query = "") => {
12147
- ipcRenderer$7.invoke(ALGOLIA_BROWSE_OBJECTS, {
12337
+ ipcRenderer$8.invoke(ALGOLIA_BROWSE_OBJECTS, {
12148
12338
  appId,
12149
12339
  apiKey,
12150
12340
  indexName,
@@ -12154,7 +12344,7 @@ const algoliaApi$2 = {
12154
12344
  },
12155
12345
 
12156
12346
  search: (appId, apiKey, indexName, query = "", options = {}) =>
12157
- ipcRenderer$7.invoke(ALGOLIA_SEARCH, {
12347
+ ipcRenderer$8.invoke(ALGOLIA_SEARCH, {
12158
12348
  appId,
12159
12349
  apiKey,
12160
12350
  indexName,
@@ -12169,14 +12359,14 @@ var algoliaApi_1 = algoliaApi$2;
12169
12359
  * openAI
12170
12360
  */
12171
12361
 
12172
- const { ipcRenderer: ipcRenderer$6 } = require$$0$1;
12362
+ const { ipcRenderer: ipcRenderer$7 } = require$$0$1;
12173
12363
 
12174
12364
  const { OPENAI_DESCRIBE_IMAGE } = openaiEvents$1;
12175
12365
 
12176
12366
  const openaiApi$2 = {
12177
12367
  // convert a json array of objects to a csv string and save to file
12178
12368
  describeImage: (imageUrl, apiKey, prompt = "What's in this image?") =>
12179
- ipcRenderer$6.invoke(OPENAI_DESCRIBE_IMAGE, { imageUrl, apiKey, prompt }),
12369
+ ipcRenderer$7.invoke(OPENAI_DESCRIBE_IMAGE, { imageUrl, apiKey, prompt }),
12180
12370
  };
12181
12371
 
12182
12372
  var openaiApi_1 = openaiApi$2;
@@ -12187,14 +12377,14 @@ var openaiApi_1 = openaiApi$2;
12187
12377
  */
12188
12378
 
12189
12379
  // ipcRenderer that must be used to invoke the events
12190
- const { ipcRenderer: ipcRenderer$5 } = require$$0$1;
12380
+ const { ipcRenderer: ipcRenderer$6 } = require$$0$1;
12191
12381
 
12192
12382
  const { MENU_ITEMS_SAVE, MENU_ITEMS_LIST } = events$8;
12193
12383
 
12194
12384
  const menuItemsApi$2 = {
12195
12385
  saveMenuItem: (appId, menuItem) =>
12196
- ipcRenderer$5.invoke(MENU_ITEMS_SAVE, { appId, menuItem }),
12197
- listMenuItems: (appId) => ipcRenderer$5.invoke(MENU_ITEMS_LIST, { appId }),
12386
+ ipcRenderer$6.invoke(MENU_ITEMS_SAVE, { appId, menuItem }),
12387
+ listMenuItems: (appId) => ipcRenderer$6.invoke(MENU_ITEMS_LIST, { appId }),
12198
12388
  };
12199
12389
 
12200
12390
  var menuItemsApi_1 = menuItemsApi$2;
@@ -12206,12 +12396,12 @@ var menuItemsApi_1 = menuItemsApi$2;
12206
12396
  */
12207
12397
 
12208
12398
  // ipcRenderer that must be used to invoke the events
12209
- const { ipcRenderer: ipcRenderer$4 } = require$$0$1;
12399
+ const { ipcRenderer: ipcRenderer$5 } = require$$0$1;
12210
12400
 
12211
12401
  const pluginApi$2 = {
12212
12402
  install: (packageName, filepath) =>
12213
- ipcRenderer$4.invoke("plugin-install", { packageName, filepath }),
12214
- uninstall: (filepath) => ipcRenderer$4.invoke("plugin-uninstall", filepath),
12403
+ ipcRenderer$5.invoke("plugin-install", { packageName, filepath }),
12404
+ uninstall: (filepath) => ipcRenderer$5.invoke("plugin-uninstall", filepath),
12215
12405
  };
12216
12406
 
12217
12407
  var pluginApi_1 = pluginApi$2;
@@ -12224,7 +12414,7 @@ var pluginApi_1 = pluginApi$2;
12224
12414
  * tool-use events, and request cancellation.
12225
12415
  */
12226
12416
 
12227
- const { ipcRenderer: ipcRenderer$3 } = require$$0$1;
12417
+ const { ipcRenderer: ipcRenderer$4 } = require$$0$1;
12228
12418
  const {
12229
12419
  LLM_SEND_MESSAGE,
12230
12420
  LLM_ABORT_REQUEST,
@@ -12246,7 +12436,7 @@ const _listenerMap = new Map();
12246
12436
  function _addListener(channel, callback) {
12247
12437
  const id = String(++_nextListenerId);
12248
12438
  const wrapped = (_event, data) => callback(data);
12249
- ipcRenderer$3.on(channel, wrapped);
12439
+ ipcRenderer$4.on(channel, wrapped);
12250
12440
  _listenerMap.set(id, { channel, wrapped });
12251
12441
  return id;
12252
12442
  }
@@ -12261,7 +12451,7 @@ const llmApi$2 = {
12261
12451
  * @returns {Promise<void>}
12262
12452
  */
12263
12453
  sendMessage: (requestId, params) =>
12264
- ipcRenderer$3.invoke(LLM_SEND_MESSAGE, { requestId, ...params }),
12454
+ ipcRenderer$4.invoke(LLM_SEND_MESSAGE, { requestId, ...params }),
12265
12455
 
12266
12456
  /**
12267
12457
  * abortRequest
@@ -12271,7 +12461,7 @@ const llmApi$2 = {
12271
12461
  * @returns {Promise<{ success: boolean }>}
12272
12462
  */
12273
12463
  abortRequest: (requestId) =>
12274
- ipcRenderer$3.invoke(LLM_ABORT_REQUEST, { requestId }),
12464
+ ipcRenderer$4.invoke(LLM_ABORT_REQUEST, { requestId }),
12275
12465
 
12276
12466
  /**
12277
12467
  * listConnectedTools
@@ -12279,7 +12469,7 @@ const llmApi$2 = {
12279
12469
  *
12280
12470
  * @returns {Promise<Array<{ serverName, tools, resources, status }>>}
12281
12471
  */
12282
- listConnectedTools: () => ipcRenderer$3.invoke(LLM_LIST_CONNECTED_TOOLS),
12472
+ listConnectedTools: () => ipcRenderer$4.invoke(LLM_LIST_CONNECTED_TOOLS),
12283
12473
 
12284
12474
  /**
12285
12475
  * checkCliAvailable
@@ -12287,7 +12477,7 @@ const llmApi$2 = {
12287
12477
  *
12288
12478
  * @returns {Promise<{ available: boolean, path?: string }>}
12289
12479
  */
12290
- checkCliAvailable: () => ipcRenderer$3.invoke(LLM_CHECK_CLI_AVAILABLE),
12480
+ checkCliAvailable: () => ipcRenderer$4.invoke(LLM_CHECK_CLI_AVAILABLE),
12291
12481
 
12292
12482
  /**
12293
12483
  * clearCliSession
@@ -12297,7 +12487,7 @@ const llmApi$2 = {
12297
12487
  * @returns {Promise<{ success: boolean }>}
12298
12488
  */
12299
12489
  clearCliSession: (widgetUuid) =>
12300
- ipcRenderer$3.invoke(LLM_CLEAR_CLI_SESSION, { widgetUuid }),
12490
+ ipcRenderer$4.invoke(LLM_CLEAR_CLI_SESSION, { widgetUuid }),
12301
12491
 
12302
12492
  /**
12303
12493
  * getCliSessionStatus
@@ -12307,7 +12497,7 @@ const llmApi$2 = {
12307
12497
  * @returns {Promise<{ hasSession: boolean, sessionId?: string, isProcessActive: boolean }>}
12308
12498
  */
12309
12499
  getCliSessionStatus: (widgetUuid) =>
12310
- ipcRenderer$3.invoke(LLM_CLI_SESSION_STATUS, { widgetUuid }),
12500
+ ipcRenderer$4.invoke(LLM_CLI_SESSION_STATUS, { widgetUuid }),
12311
12501
 
12312
12502
  /**
12313
12503
  * endCliSession
@@ -12317,7 +12507,7 @@ const llmApi$2 = {
12317
12507
  * @returns {Promise<{ success: boolean }>}
12318
12508
  */
12319
12509
  endCliSession: (widgetUuid) =>
12320
- ipcRenderer$3.invoke(LLM_CLI_END_SESSION, { widgetUuid }),
12510
+ ipcRenderer$4.invoke(LLM_CLI_END_SESSION, { widgetUuid }),
12321
12511
 
12322
12512
  // --- Stream event listeners ---
12323
12513
  // Each on* method returns an opaque string ID. Strings cross the
@@ -12351,7 +12541,7 @@ const llmApi$2 = {
12351
12541
  const listenerId = id !== undefined ? String(id) : String(idOrChannel);
12352
12542
  const entry = _listenerMap.get(listenerId);
12353
12543
  if (entry) {
12354
- ipcRenderer$3.removeListener(entry.channel, entry.wrapped);
12544
+ ipcRenderer$4.removeListener(entry.channel, entry.wrapped);
12355
12545
  _listenerMap.delete(listenerId);
12356
12546
  }
12357
12547
  },
@@ -12363,14 +12553,14 @@ const llmApi$2 = {
12363
12553
  */
12364
12554
  removeAllStreamListeners: () => {
12365
12555
  for (const [, entry] of _listenerMap) {
12366
- ipcRenderer$3.removeListener(entry.channel, entry.wrapped);
12556
+ ipcRenderer$4.removeListener(entry.channel, entry.wrapped);
12367
12557
  }
12368
12558
  _listenerMap.clear();
12369
- ipcRenderer$3.removeAllListeners(LLM_STREAM_DELTA);
12370
- ipcRenderer$3.removeAllListeners(LLM_STREAM_TOOL_CALL);
12371
- ipcRenderer$3.removeAllListeners(LLM_STREAM_TOOL_RESULT);
12372
- ipcRenderer$3.removeAllListeners(LLM_STREAM_COMPLETE);
12373
- ipcRenderer$3.removeAllListeners(LLM_STREAM_ERROR);
12559
+ ipcRenderer$4.removeAllListeners(LLM_STREAM_DELTA);
12560
+ ipcRenderer$4.removeAllListeners(LLM_STREAM_TOOL_CALL);
12561
+ ipcRenderer$4.removeAllListeners(LLM_STREAM_TOOL_RESULT);
12562
+ ipcRenderer$4.removeAllListeners(LLM_STREAM_COMPLETE);
12563
+ ipcRenderer$4.removeAllListeners(LLM_STREAM_ERROR);
12374
12564
  },
12375
12565
  };
12376
12566
 
@@ -12384,7 +12574,7 @@ var llmApi_1 = llmApi$2;
12384
12574
  * and manage the response cache.
12385
12575
  */
12386
12576
 
12387
- const { ipcRenderer: ipcRenderer$2 } = require$$0$1;
12577
+ const { ipcRenderer: ipcRenderer$3 } = require$$0$1;
12388
12578
  const {
12389
12579
  CLIENT_CACHE_INVALIDATE,
12390
12580
  CLIENT_CACHE_INVALIDATE_ALL,
@@ -12401,28 +12591,28 @@ const clientCacheApi$2 = {
12401
12591
  * @returns {Promise<{success: boolean}>}
12402
12592
  */
12403
12593
  invalidate: (appId, providerName) =>
12404
- ipcRenderer$2.invoke(CLIENT_CACHE_INVALIDATE, { appId, providerName }),
12594
+ ipcRenderer$3.invoke(CLIENT_CACHE_INVALIDATE, { appId, providerName }),
12405
12595
 
12406
12596
  /**
12407
12597
  * Invalidate all cached clients.
12408
12598
  *
12409
12599
  * @returns {Promise<{success: boolean}>}
12410
12600
  */
12411
- invalidateAll: () => ipcRenderer$2.invoke(CLIENT_CACHE_INVALIDATE_ALL),
12601
+ invalidateAll: () => ipcRenderer$3.invoke(CLIENT_CACHE_INVALIDATE_ALL),
12412
12602
 
12413
12603
  /**
12414
12604
  * Clear the response cache.
12415
12605
  *
12416
12606
  * @returns {Promise<{success: boolean}>}
12417
12607
  */
12418
- clearResponseCache: () => ipcRenderer$2.invoke(RESPONSE_CACHE_CLEAR),
12608
+ clearResponseCache: () => ipcRenderer$3.invoke(RESPONSE_CACHE_CLEAR),
12419
12609
 
12420
12610
  /**
12421
12611
  * Get response cache statistics.
12422
12612
  *
12423
12613
  * @returns {Promise<{entries: number, inflight: number, keys: string[]}>}
12424
12614
  */
12425
- responseCacheStats: () => ipcRenderer$2.invoke(RESPONSE_CACHE_STATS),
12615
+ responseCacheStats: () => ipcRenderer$3.invoke(RESPONSE_CACHE_STATS),
12426
12616
  };
12427
12617
 
12428
12618
  var clientCacheApi_1 = clientCacheApi$2;
@@ -12434,7 +12624,7 @@ var clientCacheApi_1 = clientCacheApi$2;
12434
12624
  * Exposed via contextBridge through mainApi.
12435
12625
  */
12436
12626
 
12437
- const { ipcRenderer: ipcRenderer$1 } = require$$0$1;
12627
+ const { ipcRenderer: ipcRenderer$2 } = require$$0$1;
12438
12628
  const {
12439
12629
  DASHBOARD_CONFIG_EXPORT,
12440
12630
  DASHBOARD_CONFIG_IMPORT,
@@ -12456,7 +12646,7 @@ const dashboardConfigApi$2 = {
12456
12646
  * @returns {Promise<Object>} Result with success, filePath, and config
12457
12647
  */
12458
12648
  exportDashboardConfig: (appId, workspaceId, options = {}) =>
12459
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_EXPORT, {
12649
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_EXPORT, {
12460
12650
  appId,
12461
12651
  workspaceId,
12462
12652
  options,
@@ -12471,7 +12661,7 @@ const dashboardConfigApi$2 = {
12471
12661
  * @returns {Promise<Object>} Result with success, workspace, and summary
12472
12662
  */
12473
12663
  importDashboardConfig: (appId) =>
12474
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_IMPORT, { appId }),
12664
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_IMPORT, { appId }),
12475
12665
 
12476
12666
  /**
12477
12667
  * Install a dashboard from the registry by package name.
@@ -12483,7 +12673,7 @@ const dashboardConfigApi$2 = {
12483
12673
  * @returns {Promise<Object>} Result with success, workspace, and summary
12484
12674
  */
12485
12675
  installDashboardFromRegistry: (appId, packageName) =>
12486
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_INSTALL, {
12676
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_INSTALL, {
12487
12677
  appId,
12488
12678
  packageName,
12489
12679
  }),
@@ -12496,7 +12686,7 @@ const dashboardConfigApi$2 = {
12496
12686
  * @returns {Promise<Object>} Compatibility report with per-widget status
12497
12687
  */
12498
12688
  checkDashboardCompatibility: (appId, dashboardWidgets) =>
12499
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_COMPATIBILITY, {
12689
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_COMPATIBILITY, {
12500
12690
  appId,
12501
12691
  dashboardWidgets,
12502
12692
  }),
@@ -12512,7 +12702,7 @@ const dashboardConfigApi$2 = {
12512
12702
  * @returns {Promise<Object>} Result with success, manifest, filePath
12513
12703
  */
12514
12704
  prepareDashboardForPublish: (appId, workspaceId, options = {}) =>
12515
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_PUBLISH, {
12705
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_PUBLISH, {
12516
12706
  appId,
12517
12707
  workspaceId,
12518
12708
  options,
@@ -12526,7 +12716,7 @@ const dashboardConfigApi$2 = {
12526
12716
  * @returns {Promise<Object>} Preview with metadata, widgets, wiring, compatibility
12527
12717
  */
12528
12718
  getDashboardPreview: (packageName) =>
12529
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_PREVIEW, { packageName }),
12719
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_PREVIEW, { packageName }),
12530
12720
 
12531
12721
  /**
12532
12722
  * Check installed dashboards for available updates.
@@ -12535,7 +12725,7 @@ const dashboardConfigApi$2 = {
12535
12725
  * @returns {Promise<Object>} Result with updates array
12536
12726
  */
12537
12727
  checkDashboardUpdates: (appId) =>
12538
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_CHECK_UPDATES, { appId }),
12728
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_CHECK_UPDATES, { appId }),
12539
12729
 
12540
12730
  /**
12541
12731
  * Get provider setup manifest for a dashboard's requirements.
@@ -12545,7 +12735,7 @@ const dashboardConfigApi$2 = {
12545
12735
  * @returns {Promise<Object>} Setup manifest with per-provider status
12546
12736
  */
12547
12737
  getProviderSetupManifest: (appId, requiredProviders) =>
12548
- ipcRenderer$1.invoke(DASHBOARD_CONFIG_PROVIDER_SETUP, {
12738
+ ipcRenderer$2.invoke(DASHBOARD_CONFIG_PROVIDER_SETUP, {
12549
12739
  appId,
12550
12740
  requiredProviders,
12551
12741
  }),
@@ -12553,6 +12743,40 @@ const dashboardConfigApi$2 = {
12553
12743
 
12554
12744
  var dashboardConfigApi_1 = dashboardConfigApi$2;
12555
12745
 
12746
+ /**
12747
+ * dashboardRatingsApi.js
12748
+ *
12749
+ * IPC bridge for dashboard ratings (renderer side).
12750
+ */
12751
+
12752
+ const { ipcRenderer: ipcRenderer$1 } = require$$0$1;
12753
+ const {
12754
+ DASHBOARD_RATING_SAVE,
12755
+ DASHBOARD_RATING_GET,
12756
+ DASHBOARD_RATING_LIST,
12757
+ DASHBOARD_RATING_DELETE,
12758
+ } = events$8;
12759
+
12760
+ const dashboardRatingsApi$1 = {
12761
+ saveDashboardRating: (appId, packageName, rating) =>
12762
+ ipcRenderer$1.invoke(DASHBOARD_RATING_SAVE, {
12763
+ appId,
12764
+ packageName,
12765
+ rating,
12766
+ }),
12767
+
12768
+ getDashboardRating: (appId, packageName) =>
12769
+ ipcRenderer$1.invoke(DASHBOARD_RATING_GET, { appId, packageName }),
12770
+
12771
+ listDashboardRatings: (appId) =>
12772
+ ipcRenderer$1.invoke(DASHBOARD_RATING_LIST, { appId }),
12773
+
12774
+ deleteDashboardRating: (appId, packageName) =>
12775
+ ipcRenderer$1.invoke(DASHBOARD_RATING_DELETE, { appId, packageName }),
12776
+ };
12777
+
12778
+ var dashboardRatingsApi_1 = dashboardRatingsApi$1;
12779
+
12556
12780
  /**
12557
12781
  * mainApi.js
12558
12782
  *
@@ -12585,6 +12809,7 @@ const pluginApi$1 = pluginApi_1;
12585
12809
  const llmApi$1 = llmApi_1;
12586
12810
  const clientCacheApi$1 = clientCacheApi_1;
12587
12811
  const dashboardConfigApi$1 = dashboardConfigApi_1;
12812
+ const dashboardRatingsApi = dashboardRatingsApi_1;
12588
12813
 
12589
12814
  // Events constants
12590
12815
  const events$1 = events$8;
@@ -12657,6 +12882,7 @@ function createMainApi$1(extensions = {}) {
12657
12882
  plugins: pluginApi$1,
12658
12883
  clientCache: clientCacheApi$1,
12659
12884
  dashboardConfig: dashboardConfigApi$1,
12885
+ dashboardRatings: dashboardRatingsApi,
12660
12886
 
12661
12887
  widgetEvent: {
12662
12888
  publish: (eventType, content) => {