@trops/dash-core 0.1.94 → 0.1.97

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.
@@ -624,6 +624,28 @@ var dashboardRatingsEvents$1 = {
624
624
  DASHBOARD_RATING_DELETE: DASHBOARD_RATING_DELETE$1,
625
625
  };
626
626
 
627
+ /**
628
+ * Event Constants — Registry Auth Events
629
+ *
630
+ * IPC event constants for registry authentication (device code flow).
631
+ */
632
+
633
+ const REGISTRY_AUTH_INITIATE_LOGIN$1 = "registry-auth:initiate-login";
634
+ const REGISTRY_AUTH_POLL_TOKEN$1 = "registry-auth:poll-token";
635
+ const REGISTRY_AUTH_GET_STATUS$1 = "registry-auth:get-status";
636
+ const REGISTRY_AUTH_GET_PROFILE$1 = "registry-auth:get-profile";
637
+ const REGISTRY_AUTH_LOGOUT$1 = "registry-auth:logout";
638
+ const REGISTRY_AUTH_PUBLISH$1 = "registry-auth:publish";
639
+
640
+ var registryAuthEvents$1 = {
641
+ REGISTRY_AUTH_INITIATE_LOGIN: REGISTRY_AUTH_INITIATE_LOGIN$1,
642
+ REGISTRY_AUTH_POLL_TOKEN: REGISTRY_AUTH_POLL_TOKEN$1,
643
+ REGISTRY_AUTH_GET_STATUS: REGISTRY_AUTH_GET_STATUS$1,
644
+ REGISTRY_AUTH_GET_PROFILE: REGISTRY_AUTH_GET_PROFILE$1,
645
+ REGISTRY_AUTH_LOGOUT: REGISTRY_AUTH_LOGOUT$1,
646
+ REGISTRY_AUTH_PUBLISH: REGISTRY_AUTH_PUBLISH$1,
647
+ };
648
+
627
649
  /**
628
650
  * Events
629
651
  *
@@ -647,6 +669,7 @@ const llmEvents = llmEvents$1;
647
669
  const clientCacheEvents = clientCacheEvents$1;
648
670
  const dashboardConfigEvents = dashboardConfigEvents$1;
649
671
  const dashboardRatingsEvents = dashboardRatingsEvents$1;
672
+ const registryAuthEvents = registryAuthEvents$1;
650
673
 
651
674
  const publicEvents = {
652
675
  ...dataEvents,
@@ -671,6 +694,7 @@ var events$8 = {
671
694
  ...clientCacheEvents,
672
695
  ...dashboardConfigEvents,
673
696
  ...dashboardRatingsEvents,
697
+ ...registryAuthEvents,
674
698
  };
675
699
 
676
700
  /**
@@ -764,7 +788,7 @@ var secureStoreController$1 = {
764
788
  getData: getData$1,
765
789
  };
766
790
 
767
- const path$f = require$$1$1;
791
+ const path$g = require$$1$1;
768
792
  const {
769
793
  readFileSync,
770
794
  writeFileSync: writeFileSync$4,
@@ -782,7 +806,7 @@ const {
782
806
  function ensureDirectoryExistence$2(filePath) {
783
807
  try {
784
808
  // isDirectory
785
- var dirname = path$f.dirname(filePath);
809
+ var dirname = path$g.dirname(filePath);
786
810
  // check if the directory exists...return true
787
811
  // if not, we can pass in the dirname as the filepath
788
812
  // and check each directory recursively.
@@ -897,7 +921,7 @@ function removeFilesFromDirectory(directory, excludeFiles = []) {
897
921
 
898
922
  for (const file of files) {
899
923
  if (!excludeFiles.includes(file)) {
900
- unlinkSync(path$f.join(directory, file), (err) => {
924
+ unlinkSync(path$g.join(directory, file), (err) => {
901
925
  if (err) throw err;
902
926
  });
903
927
  }
@@ -915,7 +939,7 @@ var file = {
915
939
  };
916
940
 
917
941
  const { app: app$9 } = require$$0$1;
918
- const path$e = require$$1$1;
942
+ const path$f = require$$1$1;
919
943
  const { writeFileSync: writeFileSync$3 } = require$$2;
920
944
  const { getFileContents: getFileContents$7 } = file;
921
945
 
@@ -962,7 +986,7 @@ const workspaceController$1 = {
962
986
  saveWorkspaceForApplication: (win, appId, workspaceObject) => {
963
987
  try {
964
988
  // filename to the pages file (live pages)
965
- const filename = path$e.join(
989
+ const filename = path$f.join(
966
990
  app$9.getPath("userData"),
967
991
  appName$7,
968
992
  appId,
@@ -1011,7 +1035,7 @@ const workspaceController$1 = {
1011
1035
  saveMenuItemsForApplication: (win, appId, menuItems) => {
1012
1036
  try {
1013
1037
  // filename to the workspaces file
1014
- const filename = path$e.join(
1038
+ const filename = path$f.join(
1015
1039
  app$9.getPath("userData"),
1016
1040
  appName$7,
1017
1041
  appId,
@@ -1060,7 +1084,7 @@ const workspaceController$1 = {
1060
1084
  */
1061
1085
  deleteWorkspaceForApplication: (win, appId, workspaceId) => {
1062
1086
  try {
1063
- const filename = path$e.join(
1087
+ const filename = path$f.join(
1064
1088
  app$9.getPath("userData"),
1065
1089
  appName$7,
1066
1090
  appId,
@@ -1094,7 +1118,7 @@ const workspaceController$1 = {
1094
1118
 
1095
1119
  listWorkspacesForApplication: (win, appId) => {
1096
1120
  try {
1097
- const filename = path$e.join(
1121
+ const filename = path$f.join(
1098
1122
  app$9.getPath("userData"),
1099
1123
  appName$7,
1100
1124
  appId,
@@ -1122,7 +1146,7 @@ const workspaceController$1 = {
1122
1146
 
1123
1147
  listMenuItemsForApplication: (win, appId) => {
1124
1148
  try {
1125
- const filename = path$e.join(
1149
+ const filename = path$f.join(
1126
1150
  app$9.getPath("userData"),
1127
1151
  appName$7,
1128
1152
  appId,
@@ -1167,7 +1191,7 @@ const workspaceController$1 = {
1167
1191
  var workspaceController_1 = workspaceController$1;
1168
1192
 
1169
1193
  const { app: app$8 } = require$$0$1;
1170
- const path$d = require$$1$1;
1194
+ const path$e = require$$1$1;
1171
1195
  const { writeFileSync: writeFileSync$2 } = require$$2;
1172
1196
  const { getFileContents: getFileContents$6 } = file;
1173
1197
 
@@ -1187,7 +1211,7 @@ const themeController$1 = {
1187
1211
  saveThemeForApplication: (win, appId, name, obj) => {
1188
1212
  try {
1189
1213
  // filename to the pages file (live pages)
1190
- const filename = path$d.join(
1214
+ const filename = path$e.join(
1191
1215
  app$8.getPath("userData"),
1192
1216
  appName$6,
1193
1217
  appId,
@@ -1233,7 +1257,7 @@ const themeController$1 = {
1233
1257
  */
1234
1258
  listThemesForApplication: (win, appId) => {
1235
1259
  try {
1236
- const filename = path$d.join(
1260
+ const filename = path$e.join(
1237
1261
  app$8.getPath("userData"),
1238
1262
  appName$6,
1239
1263
  appId,
@@ -1275,7 +1299,7 @@ const themeController$1 = {
1275
1299
  */
1276
1300
  deleteThemeForApplication: (win, appId, themeKey) => {
1277
1301
  try {
1278
- const filename = path$d.join(
1302
+ const filename = path$e.join(
1279
1303
  app$8.getPath("userData"),
1280
1304
  appName$6,
1281
1305
  appId,
@@ -1315,14 +1339,14 @@ var themeController_1 = themeController$1;
1315
1339
  * - CSV -> JSON
1316
1340
  */
1317
1341
 
1318
- var fs$8 = require$$2;
1342
+ var fs$9 = require$$2;
1319
1343
  var readline = require$$1$2;
1320
1344
  const xtreamer = require$$2$1;
1321
1345
  var xmlParser = require$$3;
1322
1346
  var JSONStream$1 = require$$4;
1323
1347
  const stream = require$$5;
1324
1348
  var csv = require$$6;
1325
- const path$c = require$$1$1;
1349
+ const path$d = require$$1$1;
1326
1350
  const { app: app$7 } = require$$0$1;
1327
1351
  const { ensureDirectoryExistence: ensureDirectoryExistence$1 } = file;
1328
1352
 
@@ -1371,7 +1395,7 @@ let Transform$1 = class Transform {
1371
1395
  let lineObject = [];
1372
1396
 
1373
1397
  const readInterface = readline.createInterface({
1374
- input: fs$8.createReadStream(filepath),
1398
+ input: fs$9.createReadStream(filepath),
1375
1399
  output: process.stdout,
1376
1400
  console: false,
1377
1401
  });
@@ -1406,7 +1430,7 @@ let Transform$1 = class Transform {
1406
1430
  return new Promise((resolve, reject) => {
1407
1431
  try {
1408
1432
  const parser = JSONStream$1.parse("*");
1409
- const readStream = fs$8.createReadStream(file).pipe(parser);
1433
+ const readStream = fs$9.createReadStream(file).pipe(parser);
1410
1434
 
1411
1435
  let count = 0;
1412
1436
 
@@ -1459,7 +1483,7 @@ let Transform$1 = class Transform {
1459
1483
  parseXMLStream = (filepath, outpath, start) => {
1460
1484
  return new Promise((resolve, reject) => {
1461
1485
  try {
1462
- const xmlFileReadStream = fs$8.createReadStream(filepath);
1486
+ const xmlFileReadStream = fs$9.createReadStream(filepath);
1463
1487
 
1464
1488
  xmlFileReadStream.on("end", () => {
1465
1489
  writeStream.write("\n]");
@@ -1470,7 +1494,7 @@ let Transform$1 = class Transform {
1470
1494
  resolve("Read Finish");
1471
1495
  });
1472
1496
 
1473
- const writeStream = fs$8.createWriteStream(outpath);
1497
+ const writeStream = fs$9.createWriteStream(outpath);
1474
1498
  writeStream.write("[\n");
1475
1499
 
1476
1500
  const options = {
@@ -1522,10 +1546,10 @@ let Transform$1 = class Transform {
1522
1546
  ) => {
1523
1547
  return new Promise((resolve, reject) => {
1524
1548
  try {
1525
- const readStream = fs$8
1549
+ const readStream = fs$9
1526
1550
  .createReadStream(filepath)
1527
1551
  .pipe(csv({ separator: delimiter }));
1528
- const writeStream = fs$8.createWriteStream(outpath);
1552
+ const writeStream = fs$9.createWriteStream(outpath);
1529
1553
 
1530
1554
  let canParse = true;
1531
1555
 
@@ -1611,18 +1635,18 @@ let Transform$1 = class Transform {
1611
1635
  }
1612
1636
 
1613
1637
  // Validate file paths are within app data directory
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);
1638
+ const appDataDir = path$d.join(app$7.getPath("userData"), TRANSFORM_APP_NAME);
1639
+ const resolvedFilepath = path$d.resolve(filepath);
1640
+ const resolvedOutFilepath = path$d.resolve(outFilepath);
1617
1641
 
1618
- if (!resolvedFilepath.startsWith(appDataDir + path$c.sep)) {
1642
+ if (!resolvedFilepath.startsWith(appDataDir + path$d.sep)) {
1619
1643
  return reject(
1620
1644
  new Error(
1621
1645
  "Input file path must be within the application data directory",
1622
1646
  ),
1623
1647
  );
1624
1648
  }
1625
- if (!resolvedOutFilepath.startsWith(appDataDir + path$c.sep)) {
1649
+ if (!resolvedOutFilepath.startsWith(appDataDir + path$d.sep)) {
1626
1650
  return reject(
1627
1651
  new Error(
1628
1652
  "Output file path must be within the application data directory",
@@ -1633,14 +1657,14 @@ let Transform$1 = class Transform {
1633
1657
  // JSON parser
1634
1658
  var parser = JSONStream$1.parse("*");
1635
1659
 
1636
- if (fs$8.existsSync(resolvedFilepath)) {
1660
+ if (fs$9.existsSync(resolvedFilepath)) {
1637
1661
  console.log("file exists ", resolvedFilepath);
1638
1662
  // create the readStream to parse the large file (json)
1639
- var readStream = fs$8.createReadStream(resolvedFilepath).pipe(parser);
1663
+ var readStream = fs$9.createReadStream(resolvedFilepath).pipe(parser);
1640
1664
 
1641
1665
  ensureDirectoryExistence$1(resolvedOutFilepath);
1642
1666
 
1643
- var writeStream = fs$8.createWriteStream(resolvedOutFilepath);
1667
+ var writeStream = fs$9.createWriteStream(resolvedOutFilepath);
1644
1668
 
1645
1669
  let sep = "";
1646
1670
  let count = 0;
@@ -3481,8 +3505,8 @@ async function extractColorsFromImageURL$2(url, toDirectory) {
3481
3505
  var color = { extractColorsFromImageURL: extractColorsFromImageURL$2 };
3482
3506
 
3483
3507
  const { app: app$6 } = require$$0$1;
3484
- var fs$7 = require$$2;
3485
- const path$b = require$$1$1;
3508
+ var fs$8 = require$$2;
3509
+ const path$c = require$$1$1;
3486
3510
  const events$5 = events$8;
3487
3511
  const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
3488
3512
 
@@ -3505,7 +3529,7 @@ const dataController$1 = {
3505
3529
  convertJsonToCsvFile: (win, appId, jsonObject, toFilename = "test.csv") => {
3506
3530
  try {
3507
3531
  // filename to the pages file (live pages)
3508
- const filename = path$b.join(
3532
+ const filename = path$c.join(
3509
3533
  app$6.getPath("userData"),
3510
3534
  appName$5,
3511
3535
  appId,
@@ -3633,15 +3657,15 @@ const dataController$1 = {
3633
3657
  }
3634
3658
 
3635
3659
  // Validate toFilepath is within the app data directory
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)) {
3660
+ const appDataDir = path$c.join(app$6.getPath("userData"), appName$5);
3661
+ const resolvedFilepath = path$c.resolve(toFilepath);
3662
+ if (!resolvedFilepath.startsWith(appDataDir + path$c.sep)) {
3639
3663
  throw new Error(
3640
3664
  "File path must be within the application data directory",
3641
3665
  );
3642
3666
  }
3643
3667
 
3644
- const writeStream = fs$7.createWriteStream(resolvedFilepath);
3668
+ const writeStream = fs$8.createWriteStream(resolvedFilepath);
3645
3669
 
3646
3670
  https
3647
3671
  .get(url, (resp) => {
@@ -3782,7 +3806,7 @@ const dataController$1 = {
3782
3806
  try {
3783
3807
  if (data) {
3784
3808
  // filename to the pages file (live pages)
3785
- const toFilename = path$b.join(
3809
+ const toFilename = path$c.join(
3786
3810
  app$6.getPath("userData"),
3787
3811
  appName$5,
3788
3812
  "data",
@@ -3864,7 +3888,7 @@ const dataController$1 = {
3864
3888
  try {
3865
3889
  if (filename) {
3866
3890
  // filename to the pages file (live pages)
3867
- const fromFilename = path$b.join(
3891
+ const fromFilename = path$c.join(
3868
3892
  app$6.getPath("userData"),
3869
3893
  appName$5,
3870
3894
  "data",
@@ -3942,7 +3966,7 @@ const dataController$1 = {
3942
3966
  try {
3943
3967
  console.log(url);
3944
3968
  const fileExtension = ".jpg";
3945
- const filename = path$b.join(
3969
+ const filename = path$c.join(
3946
3970
  app$6.getPath("userData"),
3947
3971
  appName$5,
3948
3972
  "@algolia/dash-electron",
@@ -3968,8 +3992,8 @@ var dataController_1 = dataController$1;
3968
3992
  */
3969
3993
 
3970
3994
  const { app: app$5 } = require$$0$1;
3971
- const path$a = require$$1$1;
3972
- const fs$6 = require$$2;
3995
+ const path$b = require$$1$1;
3996
+ const fs$7 = require$$2;
3973
3997
  const { getFileContents: getFileContents$4, writeToFile: writeToFile$1 } = file;
3974
3998
 
3975
3999
  const configFilename$3 = "settings.json";
@@ -3977,15 +4001,15 @@ const appName$4 = "Dashboard";
3977
4001
 
3978
4002
  // Helper function to recursively copy directory
3979
4003
  function copyDirectory(source, destination) {
3980
- if (!fs$6.existsSync(destination)) {
3981
- fs$6.mkdirSync(destination, { recursive: true });
4004
+ if (!fs$7.existsSync(destination)) {
4005
+ fs$7.mkdirSync(destination, { recursive: true });
3982
4006
  }
3983
4007
 
3984
- const files = fs$6.readdirSync(source);
4008
+ const files = fs$7.readdirSync(source);
3985
4009
  for (const file of files) {
3986
- const srcPath = path$a.join(source, file);
3987
- const destPath = path$a.join(destination, file);
3988
- const stat = fs$6.lstatSync(srcPath);
4010
+ const srcPath = path$b.join(source, file);
4011
+ const destPath = path$b.join(destination, file);
4012
+ const stat = fs$7.lstatSync(srcPath);
3989
4013
 
3990
4014
  // Skip symlinks to prevent following links to sensitive files
3991
4015
  if (stat.isSymbolicLink()) {
@@ -3996,7 +4020,7 @@ function copyDirectory(source, destination) {
3996
4020
  if (stat.isDirectory()) {
3997
4021
  copyDirectory(srcPath, destPath);
3998
4022
  } else {
3999
- fs$6.copyFileSync(srcPath, destPath);
4023
+ fs$7.copyFileSync(srcPath, destPath);
4000
4024
  }
4001
4025
  }
4002
4026
  }
@@ -4012,7 +4036,7 @@ const settingsController$1 = {
4012
4036
  try {
4013
4037
  if (data) {
4014
4038
  // <appId>/settings.json
4015
- const filename = path$a.join(
4039
+ const filename = path$b.join(
4016
4040
  app$5.getPath("userData"),
4017
4041
  appName$4,
4018
4042
  configFilename$3,
@@ -4048,7 +4072,7 @@ const settingsController$1 = {
4048
4072
  getSettingsForApplication: (win) => {
4049
4073
  try {
4050
4074
  // <appId>/settings.json
4051
- const filename = path$a.join(
4075
+ const filename = path$b.join(
4052
4076
  app$5.getPath("userData"),
4053
4077
  appName$4,
4054
4078
  configFilename$3,
@@ -4079,7 +4103,7 @@ const settingsController$1 = {
4079
4103
  */
4080
4104
  getDataDirectory: (win) => {
4081
4105
  try {
4082
- const settingsPath = path$a.join(
4106
+ const settingsPath = path$b.join(
4083
4107
  app$5.getPath("userData"),
4084
4108
  appName$4,
4085
4109
  configFilename$3,
@@ -4087,7 +4111,7 @@ const settingsController$1 = {
4087
4111
  const settings = getFileContents$4(settingsPath, {});
4088
4112
  const userDataDir =
4089
4113
  settings.userDataDirectory ||
4090
- path$a.join(app$5.getPath("userData"), appName$4);
4114
+ path$b.join(app$5.getPath("userData"), appName$4);
4091
4115
 
4092
4116
  console.log("[settingsController] Data directory retrieved successfully");
4093
4117
  // Return the data for ipcMain.handle() - modern promise-based approach
@@ -4114,17 +4138,17 @@ const settingsController$1 = {
4114
4138
  setDataDirectory: (win, newPath) => {
4115
4139
  try {
4116
4140
  // Validate the path exists and is a directory
4117
- if (!fs$6.existsSync(newPath)) {
4118
- fs$6.mkdirSync(newPath, { recursive: true });
4141
+ if (!fs$7.existsSync(newPath)) {
4142
+ fs$7.mkdirSync(newPath, { recursive: true });
4119
4143
  }
4120
4144
 
4121
- const stats = fs$6.statSync(newPath);
4145
+ const stats = fs$7.statSync(newPath);
4122
4146
  if (!stats.isDirectory()) {
4123
4147
  throw new Error("Path is not a directory");
4124
4148
  }
4125
4149
 
4126
4150
  // Update settings
4127
- const settingsPath = path$a.join(
4151
+ const settingsPath = path$b.join(
4128
4152
  app$5.getPath("userData"),
4129
4153
  appName$4,
4130
4154
  configFilename$3,
@@ -4158,11 +4182,11 @@ const settingsController$1 = {
4158
4182
  migrateDataDirectory: (win, oldPath, newPath) => {
4159
4183
  try {
4160
4184
  // Resolve paths to prevent traversal
4161
- const resolvedOldPath = path$a.resolve(oldPath);
4162
- const resolvedNewPath = path$a.resolve(newPath);
4185
+ const resolvedOldPath = path$b.resolve(oldPath);
4186
+ const resolvedNewPath = path$b.resolve(newPath);
4163
4187
 
4164
4188
  // Validate oldPath is the current configured data directory
4165
- const settingsCheckPath = path$a.join(
4189
+ const settingsCheckPath = path$b.join(
4166
4190
  app$5.getPath("userData"),
4167
4191
  appName$4,
4168
4192
  configFilename$3,
@@ -4170,8 +4194,8 @@ const settingsController$1 = {
4170
4194
  const currentSettings = getFileContents$4(settingsCheckPath, {});
4171
4195
  const currentDataDir =
4172
4196
  currentSettings.userDataDirectory ||
4173
- path$a.join(app$5.getPath("userData"), appName$4);
4174
- if (resolvedOldPath !== path$a.resolve(currentDataDir)) {
4197
+ path$b.join(app$5.getPath("userData"), appName$4);
4198
+ if (resolvedOldPath !== path$b.resolve(currentDataDir)) {
4175
4199
  throw new Error("Source path must be the current data directory");
4176
4200
  }
4177
4201
 
@@ -4195,19 +4219,19 @@ const settingsController$1 = {
4195
4219
  }
4196
4220
 
4197
4221
  // Validate paths
4198
- if (!fs$6.existsSync(resolvedOldPath)) {
4222
+ if (!fs$7.existsSync(resolvedOldPath)) {
4199
4223
  throw new Error("Source directory does not exist");
4200
4224
  }
4201
4225
 
4202
- if (!fs$6.existsSync(resolvedNewPath)) {
4203
- fs$6.mkdirSync(resolvedNewPath, { recursive: true });
4226
+ if (!fs$7.existsSync(resolvedNewPath)) {
4227
+ fs$7.mkdirSync(resolvedNewPath, { recursive: true });
4204
4228
  }
4205
4229
 
4206
4230
  // Copy files
4207
4231
  copyDirectory(resolvedOldPath, resolvedNewPath);
4208
4232
 
4209
4233
  // Update settings to use new path
4210
- const settingsPath = path$a.join(
4234
+ const settingsPath = path$b.join(
4211
4235
  app$5.getPath("userData"),
4212
4236
  appName$4,
4213
4237
  configFilename$3,
@@ -4822,7 +4846,7 @@ function requireProviderController () {
4822
4846
  }
4823
4847
 
4824
4848
  const { app: app$4 } = require$$0$1;
4825
- const path$9 = require$$1$1;
4849
+ const path$a = require$$1$1;
4826
4850
  const { writeFileSync: writeFileSync$1 } = require$$2;
4827
4851
  const events$4 = events$8;
4828
4852
  const { getFileContents: getFileContents$3 } = file;
@@ -4842,7 +4866,7 @@ const layoutController$1 = {
4842
4866
  saveLayoutForApplication: (win, appId, layoutObject) => {
4843
4867
  try {
4844
4868
  // filename to the pages file (live pages)
4845
- const filename = path$9.join(
4869
+ const filename = path$a.join(
4846
4870
  app$4.getPath("userData"),
4847
4871
  appName$3,
4848
4872
  appId,
@@ -4875,7 +4899,7 @@ const layoutController$1 = {
4875
4899
  */
4876
4900
  listLayoutsForApplication: (win, appId) => {
4877
4901
  try {
4878
- const filename = path$9.join(
4902
+ const filename = path$a.join(
4879
4903
  app$4.getPath("userData"),
4880
4904
  appName$3,
4881
4905
  appId,
@@ -4918,8 +4942,8 @@ const {
4918
4942
  const {
4919
4943
  StreamableHTTPClientTransport,
4920
4944
  } = require$$2$3;
4921
- const path$8 = require$$1$1;
4922
- const fs$5 = require$$2;
4945
+ const path$9 = require$$1$1;
4946
+ const fs$6 = require$$2;
4923
4947
 
4924
4948
  /**
4925
4949
  * Cached shell PATH result (resolved once, reused for all spawns).
@@ -4968,7 +4992,7 @@ function getShellPath$1() {
4968
4992
  fallbackDirs.push(`${home}/.nodenv/shims`);
4969
4993
  try {
4970
4994
  const nvmDir = `${home}/.nvm/versions/node`;
4971
- const versions = fs$5.readdirSync(nvmDir).sort();
4995
+ const versions = fs$6.readdirSync(nvmDir).sort();
4972
4996
  if (versions.length > 0) {
4973
4997
  // Find the highest compatible version (v18/v20/v22)
4974
4998
  for (let i = versions.length - 1; i >= 0; i--) {
@@ -5104,15 +5128,15 @@ async function refreshGoogleOAuthToken(tokenRefresh) {
5104
5128
  const credPath = tokenRefresh.credentialsPath.replace(/^~/, home);
5105
5129
  const keysPath = tokenRefresh.oauthKeysPath.replace(/^~/, home);
5106
5130
 
5107
- if (!fs$5.existsSync(credPath) || !fs$5.existsSync(keysPath)) {
5131
+ if (!fs$6.existsSync(credPath) || !fs$6.existsSync(keysPath)) {
5108
5132
  console.log(
5109
5133
  "[mcpController] Token refresh skipped: credential files not found",
5110
5134
  );
5111
5135
  return;
5112
5136
  }
5113
5137
 
5114
- const credentials = JSON.parse(fs$5.readFileSync(credPath, "utf8"));
5115
- const keysFile = JSON.parse(fs$5.readFileSync(keysPath, "utf8"));
5138
+ const credentials = JSON.parse(fs$6.readFileSync(credPath, "utf8"));
5139
+ const keysFile = JSON.parse(fs$6.readFileSync(keysPath, "utf8"));
5116
5140
  const keyData = keysFile.installed || keysFile.web;
5117
5141
 
5118
5142
  if (
@@ -5181,7 +5205,7 @@ async function refreshGoogleOAuthToken(tokenRefresh) {
5181
5205
  credentials.refresh_token = body.refresh_token;
5182
5206
  }
5183
5207
 
5184
- fs$5.writeFileSync(credPath, JSON.stringify(credentials, null, 2));
5208
+ fs$6.writeFileSync(credPath, JSON.stringify(credentials, null, 2));
5185
5209
  console.log("[mcpController] Google OAuth token refreshed successfully");
5186
5210
  }
5187
5211
 
@@ -5335,7 +5359,7 @@ const mcpController$2 = {
5335
5359
  }
5336
5360
 
5337
5361
  // Interpolate {{MCP_DIR}} in args to resolve local MCP server scripts
5338
- const mcpDir = path$8.join(__dirname, "..", "mcp");
5362
+ const mcpDir = path$9.join(__dirname, "..", "mcp");
5339
5363
  for (let i = 0; i < args.length; i++) {
5340
5364
  if (
5341
5365
  typeof args[i] === "string" &&
@@ -5710,20 +5734,20 @@ const mcpController$2 = {
5710
5734
  */
5711
5735
  getCatalog: (win) => {
5712
5736
  try {
5713
- const catalogPath = path$8.join(
5737
+ const catalogPath = path$9.join(
5714
5738
  __dirname,
5715
5739
  "..",
5716
5740
  "mcp",
5717
5741
  "mcpServerCatalog.json",
5718
5742
  );
5719
5743
 
5720
- if (!fs$5.existsSync(catalogPath)) {
5744
+ if (!fs$6.existsSync(catalogPath)) {
5721
5745
  return {
5722
5746
  catalog: [],
5723
5747
  };
5724
5748
  }
5725
5749
 
5726
- const catalogData = fs$5.readFileSync(catalogPath, "utf8");
5750
+ const catalogData = fs$6.readFileSync(catalogPath, "utf8");
5727
5751
  const catalog = JSON.parse(catalogData);
5728
5752
 
5729
5753
  return {
@@ -5785,8 +5809,8 @@ const mcpController$2 = {
5785
5809
  const destPath = to.replace(/^~/, process.env.HOME || "");
5786
5810
  const destDir = require$$1$1.dirname(destPath);
5787
5811
  try {
5788
- fs$5.mkdirSync(destDir, { recursive: true });
5789
- fs$5.copyFileSync(sourcePath, destPath);
5812
+ fs$6.mkdirSync(destDir, { recursive: true });
5813
+ fs$6.copyFileSync(sourcePath, destPath);
5790
5814
  } catch (err) {
5791
5815
  return {
5792
5816
  error: true,
@@ -5822,7 +5846,7 @@ const mcpController$2 = {
5822
5846
  }
5823
5847
 
5824
5848
  // Interpolate {{MCP_DIR}} in authCommand args (same as startServer)
5825
- const mcpDir = path$8.join(__dirname, "..", "mcp");
5849
+ const mcpDir = path$9.join(__dirname, "..", "mcp");
5826
5850
  const resolvedArgs = (authCommand.args || []).map((arg) =>
5827
5851
  typeof arg === "string" && arg.includes("{{MCP_DIR}}")
5828
5852
  ? arg.replace(/\{\{MCP_DIR\}\}/g, mcpDir)
@@ -5918,8 +5942,8 @@ var mcpControllerExports = mcpController$3.exports;
5918
5942
  * - Support two-level browsing: packages (bundles) and widgets within packages
5919
5943
  */
5920
5944
 
5921
- const path$7 = require$$1$1;
5922
- const fs$4 = require$$2;
5945
+ const path$8 = require$$1$1;
5946
+ const fs$5 = require$$2;
5923
5947
 
5924
5948
  // Default registry URL (GitHub Pages)
5925
5949
  const DEFAULT_REGISTRY_URL =
@@ -5935,7 +5959,7 @@ let cacheTimestamp = 0;
5935
5959
  * Get the local test registry path for dev mode
5936
5960
  */
5937
5961
  function getTestRegistryPath() {
5938
- return path$7.join(__dirname, "..", "registry", "test-registry-index.json");
5962
+ return path$8.join(__dirname, "..", "registry", "test-registry-index.json");
5939
5963
  }
5940
5964
 
5941
5965
  /**
@@ -5971,12 +5995,12 @@ async function fetchRegistryIndex(forceRefresh = false) {
5971
5995
  if (isDev()) {
5972
5996
  // In dev mode, load from local test file
5973
5997
  const testPath = getTestRegistryPath();
5974
- if (fs$4.existsSync(testPath)) {
5998
+ if (fs$5.existsSync(testPath)) {
5975
5999
  console.log(
5976
6000
  "[RegistryController] Loading test registry from:",
5977
6001
  testPath,
5978
6002
  );
5979
- const raw = fs$4.readFileSync(testPath, "utf8");
6003
+ const raw = fs$5.readFileSync(testPath, "utf8");
5980
6004
  indexData = JSON.parse(raw);
5981
6005
  } else {
5982
6006
  console.warn(
@@ -6192,10 +6216,10 @@ var registryController$1 = {
6192
6216
  checkUpdates,
6193
6217
  };
6194
6218
 
6195
- var fs$3 = require$$2;
6219
+ var fs$4 = require$$2;
6196
6220
  var JSONStream = require$$4;
6197
6221
  const algoliasearch$1 = require$$2$4;
6198
- const path$6 = require$$3$2;
6222
+ const path$7 = require$$3$2;
6199
6223
  const { ensureDirectoryExistence, checkDirectory } = file;
6200
6224
 
6201
6225
  let AlgoliaIndex$1 = class AlgoliaIndex {
@@ -6233,7 +6257,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6233
6257
  var batchNumber = 1;
6234
6258
 
6235
6259
  // create the readStream to parse the large file (json)
6236
- var readStream = fs$3.createReadStream(filepath).pipe(parser);
6260
+ var readStream = fs$4.createReadStream(filepath).pipe(parser);
6237
6261
 
6238
6262
  var batch = [];
6239
6263
 
@@ -6247,7 +6271,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6247
6271
  // lets write to the batch file
6248
6272
  if (countForBatch === batchSize) {
6249
6273
  // write to the batch file
6250
- var writeStream = fs$3.createWriteStream(
6274
+ var writeStream = fs$4.createWriteStream(
6251
6275
  batchFilepath + "/batch_" + batchNumber + ".json",
6252
6276
  );
6253
6277
  writeStream.write(JSON.stringify(batch));
@@ -6298,11 +6322,11 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6298
6322
  return new Promise((resolve, reject) => {
6299
6323
  try {
6300
6324
  checkDirectory(directoryPath);
6301
- fs$3.readdir(directoryPath, (err, files) => {
6325
+ fs$4.readdir(directoryPath, (err, files) => {
6302
6326
  if (err) reject(err);
6303
6327
  if (files) {
6304
6328
  files.forEach((file) => {
6305
- fs$3.unlinkSync(path$6.join(directoryPath, file));
6329
+ fs$4.unlinkSync(path$7.join(directoryPath, file));
6306
6330
  });
6307
6331
  resolve();
6308
6332
  }
@@ -6321,11 +6345,11 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6321
6345
  ) {
6322
6346
  try {
6323
6347
  // read the directory...
6324
- const files = await fs$3.readdirSync(batchFilepath);
6348
+ const files = await fs$4.readdirSync(batchFilepath);
6325
6349
  let results = [];
6326
6350
  for (const fileIndex in files) {
6327
6351
  // for each file lets read the file and then push to algolia
6328
- const pathToBatch = path$6.join(batchFilepath, files[fileIndex]);
6352
+ const pathToBatch = path$7.join(batchFilepath, files[fileIndex]);
6329
6353
  const fileContents = await this.readFile(pathToBatch);
6330
6354
  if (fileContents) {
6331
6355
  if ("data" in fileContents && "filepath" in fileContents) {
@@ -6350,7 +6374,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
6350
6374
 
6351
6375
  async readFile(filepath) {
6352
6376
  return await new Promise((resolve, reject) => {
6353
- fs$3.readFile(filepath, "utf8", (err, data) => {
6377
+ fs$4.readFile(filepath, "utf8", (err, data) => {
6354
6378
  if (err) {
6355
6379
  reject(err);
6356
6380
  }
@@ -6500,7 +6524,7 @@ var algolia = AlgoliaIndex$1;
6500
6524
  const algoliasearch = require$$2$4;
6501
6525
  const events$3 = events$8;
6502
6526
  const AlgoliaIndex = algolia;
6503
- var fs$2 = require$$2;
6527
+ var fs$3 = require$$2;
6504
6528
 
6505
6529
  const algoliaController$1 = {
6506
6530
  /**
@@ -6608,7 +6632,7 @@ const algoliaController$1 = {
6608
6632
  // init the Algolia Index helper
6609
6633
  const a = new AlgoliaIndex(appId, apiKey, indexName);
6610
6634
  // create the write stream to store the hits
6611
- const writeStream = fs$2.createWriteStream(toFilename);
6635
+ const writeStream = fs$3.createWriteStream(toFilename);
6612
6636
  writeStream.write("[");
6613
6637
 
6614
6638
  let sep = "";
@@ -6780,7 +6804,7 @@ const openaiController$1 = {
6780
6804
  var openaiController_1 = openaiController$1;
6781
6805
 
6782
6806
  const { app: app$3 } = require$$0$1;
6783
- const path$5 = require$$1$1;
6807
+ const path$6 = require$$1$1;
6784
6808
  const { writeFileSync } = require$$2;
6785
6809
  const { getFileContents: getFileContents$2 } = file;
6786
6810
 
@@ -6791,7 +6815,7 @@ const menuItemsController$1 = {
6791
6815
  saveMenuItemForApplication: (win, appId, menuItem) => {
6792
6816
  try {
6793
6817
  // filename to the pages file (live pages)
6794
- const filename = path$5.join(
6818
+ const filename = path$6.join(
6795
6819
  app$3.getPath("userData"),
6796
6820
  appName$2,
6797
6821
  appId,
@@ -6827,7 +6851,7 @@ const menuItemsController$1 = {
6827
6851
 
6828
6852
  listMenuItemsForApplication: (win, appId) => {
6829
6853
  try {
6830
- const filename = path$5.join(
6854
+ const filename = path$6.join(
6831
6855
  app$3.getPath("userData"),
6832
6856
  appName$2,
6833
6857
  appId,
@@ -6853,13 +6877,13 @@ const menuItemsController$1 = {
6853
6877
 
6854
6878
  var menuItemsController_1 = menuItemsController$1;
6855
6879
 
6856
- const path$4 = require$$1$1;
6880
+ const path$5 = require$$1$1;
6857
6881
  const { app: app$2 } = require$$0$1;
6858
6882
 
6859
6883
  const pluginController$1 = {
6860
6884
  install: (win, packageName, filepath) => {
6861
6885
  try {
6862
- const rootPath = path$4.join(
6886
+ const rootPath = path$5.join(
6863
6887
  app$2.getPath("userData"),
6864
6888
  "plugins",
6865
6889
  packageName,
@@ -7907,190 +7931,188 @@ const CURRENT_SCHEMA_VERSION$1 = "1.0.0";
7907
7931
  * @returns {{ valid: boolean, errors: string[] }} Validation result
7908
7932
  */
7909
7933
  function validateDashboardConfig$1(config) {
7910
- const errors = [];
7934
+ const errors = [];
7911
7935
 
7912
- if (config === null || config === undefined || typeof config !== "object") {
7913
- return { valid: false, errors: ["Config must be a non-null object"] };
7914
- }
7936
+ if (config === null || config === undefined || typeof config !== "object") {
7937
+ return { valid: false, errors: ["Config must be a non-null object"] };
7938
+ }
7915
7939
 
7916
- // Required fields
7917
- for (const field of schema.required) {
7918
- if (!(field in config)) {
7919
- errors.push(`Missing required field: "${field}"`);
7920
- }
7940
+ // Required fields
7941
+ for (const field of schema.required) {
7942
+ if (!(field in config)) {
7943
+ errors.push(`Missing required field: "${field}"`);
7921
7944
  }
7945
+ }
7922
7946
 
7923
- // If required fields are missing, return early — further checks would be noisy
7924
- if (errors.length > 0) {
7925
- return { valid: false, errors };
7926
- }
7947
+ // If required fields are missing, return early — further checks would be noisy
7948
+ if (errors.length > 0) {
7949
+ return { valid: false, errors };
7950
+ }
7927
7951
 
7928
- // schemaVersion
7929
- if (typeof config.schemaVersion !== "string") {
7930
- errors.push(`"schemaVersion" must be a string`);
7931
- } else if (!/^\d+\.\d+\.\d+$/.test(config.schemaVersion)) {
7932
- errors.push(
7933
- `"schemaVersion" must be a semver string (e.g., "1.0.0"), got "${config.schemaVersion}"`,
7934
- );
7935
- }
7952
+ // schemaVersion
7953
+ if (typeof config.schemaVersion !== "string") {
7954
+ errors.push(`"schemaVersion" must be a string`);
7955
+ } else if (!/^\d+\.\d+\.\d+$/.test(config.schemaVersion)) {
7956
+ errors.push(
7957
+ `"schemaVersion" must be a semver string (e.g., "1.0.0"), got "${config.schemaVersion}"`,
7958
+ );
7959
+ }
7936
7960
 
7937
- // name
7938
- if (typeof config.name !== "string" || config.name.length === 0) {
7939
- errors.push(`"name" must be a non-empty string`);
7940
- } else if (config.name.length > 100) {
7941
- errors.push(`"name" must be 100 characters or fewer`);
7942
- }
7961
+ // name
7962
+ if (typeof config.name !== "string" || config.name.length === 0) {
7963
+ errors.push(`"name" must be a non-empty string`);
7964
+ } else if (config.name.length > 100) {
7965
+ errors.push(`"name" must be 100 characters or fewer`);
7966
+ }
7967
+
7968
+ // description (optional)
7969
+ if ("description" in config && typeof config.description !== "string") {
7970
+ errors.push(`"description" must be a string`);
7971
+ }
7943
7972
 
7944
- // description (optional)
7945
- if ("description" in config && typeof config.description !== "string") {
7946
- errors.push(`"description" must be a string`);
7973
+ // author (optional)
7974
+ if ("author" in config) {
7975
+ if (
7976
+ typeof config.author !== "object" ||
7977
+ config.author === null ||
7978
+ Array.isArray(config.author)
7979
+ ) {
7980
+ errors.push(`"author" must be an object with at least a "name" field`);
7981
+ } else if (!config.author.name || typeof config.author.name !== "string") {
7982
+ errors.push(`"author.name" must be a non-empty string`);
7947
7983
  }
7984
+ }
7948
7985
 
7949
- // author (optional)
7950
- if ("author" in config) {
7951
- if (
7952
- typeof config.author !== "object" ||
7953
- config.author === null ||
7954
- Array.isArray(config.author)
7955
- ) {
7956
- errors.push(`"author" must be an object with at least a "name" field`);
7957
- } else if (!config.author.name || typeof config.author.name !== "string") {
7958
- errors.push(`"author.name" must be a non-empty string`);
7986
+ // shareable (optional)
7987
+ if ("shareable" in config && typeof config.shareable !== "boolean") {
7988
+ errors.push(`"shareable" must be a boolean`);
7989
+ }
7990
+
7991
+ // tags (optional)
7992
+ if ("tags" in config) {
7993
+ if (!Array.isArray(config.tags)) {
7994
+ errors.push(`"tags" must be an array of strings`);
7995
+ } else {
7996
+ for (let i = 0; i < config.tags.length; i++) {
7997
+ if (typeof config.tags[i] !== "string") {
7998
+ errors.push(`"tags[${i}]" must be a string`);
7959
7999
  }
8000
+ }
7960
8001
  }
8002
+ }
7961
8003
 
7962
- // shareable (optional)
7963
- if ("shareable" in config && typeof config.shareable !== "boolean") {
7964
- errors.push(`"shareable" must be a boolean`);
8004
+ // workspace
8005
+ if (typeof config.workspace !== "object" || config.workspace === null) {
8006
+ errors.push(`"workspace" must be an object`);
8007
+ } else {
8008
+ if (!Array.isArray(config.workspace.layout)) {
8009
+ errors.push(`"workspace.layout" must be an array`);
8010
+ } else if (config.workspace.layout.length === 0) {
8011
+ errors.push(`"workspace.layout" must contain at least one layout item`);
7965
8012
  }
8013
+ }
7966
8014
 
7967
- // tags (optional)
7968
- if ("tags" in config) {
7969
- if (!Array.isArray(config.tags)) {
7970
- errors.push(`"tags" must be an array of strings`);
7971
- } else {
7972
- for (let i = 0; i < config.tags.length; i++) {
7973
- if (typeof config.tags[i] !== "string") {
7974
- errors.push(`"tags[${i}]" must be a string`);
7975
- }
7976
- }
7977
- }
8015
+ // widgets
8016
+ if (!Array.isArray(config.widgets)) {
8017
+ errors.push(`"widgets" must be an array`);
8018
+ } else {
8019
+ for (let i = 0; i < config.widgets.length; i++) {
8020
+ const w = config.widgets[i];
8021
+ if (typeof w !== "object" || w === null) {
8022
+ errors.push(`"widgets[${i}]" must be an object`);
8023
+ continue;
8024
+ }
8025
+ if (!w.id || typeof w.id !== "string") {
8026
+ errors.push(`"widgets[${i}].id" must be a non-empty string`);
8027
+ }
8028
+ if (!w.package || typeof w.package !== "string") {
8029
+ errors.push(`"widgets[${i}].package" must be a non-empty string`);
8030
+ }
8031
+ if ("version" in w && typeof w.version !== "string") {
8032
+ errors.push(`"widgets[${i}].version" must be a string`);
8033
+ }
8034
+ if ("required" in w && typeof w.required !== "boolean") {
8035
+ errors.push(`"widgets[${i}].required" must be a boolean`);
8036
+ }
8037
+ if ("author" in w && typeof w.author !== "string") {
8038
+ errors.push(`"widgets[${i}].author" must be a string`);
8039
+ }
7978
8040
  }
8041
+ }
7979
8042
 
7980
- // workspace
7981
- if (typeof config.workspace !== "object" || config.workspace === null) {
7982
- errors.push(`"workspace" must be an object`);
8043
+ // providers (optional)
8044
+ if ("providers" in config) {
8045
+ if (!Array.isArray(config.providers)) {
8046
+ errors.push(`"providers" must be an array`);
7983
8047
  } else {
7984
- if (!Array.isArray(config.workspace.layout)) {
7985
- errors.push(`"workspace.layout" must be an array`);
7986
- } else if (config.workspace.layout.length === 0) {
7987
- errors.push(`"workspace.layout" must contain at least one layout item`);
8048
+ const validClasses = ["credential", "mcp"];
8049
+ for (let i = 0; i < config.providers.length; i++) {
8050
+ const p = config.providers[i];
8051
+ if (typeof p !== "object" || p === null) {
8052
+ errors.push(`"providers[${i}]" must be an object`);
8053
+ continue;
8054
+ }
8055
+ if (!p.type || typeof p.type !== "string") {
8056
+ errors.push(`"providers[${i}].type" must be a non-empty string`);
7988
8057
  }
8058
+ if (!validClasses.includes(p.providerClass)) {
8059
+ errors.push(
8060
+ `"providers[${i}].providerClass" must be "credential" or "mcp", got "${p.providerClass}"`,
8061
+ );
8062
+ }
8063
+ if ("usedBy" in p && !Array.isArray(p.usedBy)) {
8064
+ errors.push(`"providers[${i}].usedBy" must be an array`);
8065
+ }
8066
+ }
7989
8067
  }
8068
+ }
7990
8069
 
7991
- // widgets
7992
- if (!Array.isArray(config.widgets)) {
7993
- errors.push(`"widgets" must be an array`);
8070
+ // eventWiring (optional)
8071
+ if ("eventWiring" in config) {
8072
+ if (!Array.isArray(config.eventWiring)) {
8073
+ errors.push(`"eventWiring" must be an array`);
7994
8074
  } else {
7995
- for (let i = 0; i < config.widgets.length; i++) {
7996
- const w = config.widgets[i];
7997
- if (typeof w !== "object" || w === null) {
7998
- errors.push(`"widgets[${i}]" must be an object`);
7999
- continue;
8000
- }
8001
- if (!w.id || typeof w.id !== "string") {
8002
- errors.push(`"widgets[${i}].id" must be a non-empty string`);
8003
- }
8004
- if (!w.package || typeof w.package !== "string") {
8005
- errors.push(`"widgets[${i}].package" must be a non-empty string`);
8006
- }
8007
- if ("version" in w && typeof w.version !== "string") {
8008
- errors.push(`"widgets[${i}].version" must be a string`);
8009
- }
8010
- if ("required" in w && typeof w.required !== "boolean") {
8011
- errors.push(`"widgets[${i}].required" must be a boolean`);
8012
- }
8013
- if ("author" in w && typeof w.author !== "string") {
8014
- errors.push(`"widgets[${i}].author" must be a string`);
8015
- }
8075
+ for (let i = 0; i < config.eventWiring.length; i++) {
8076
+ const ew = config.eventWiring[i];
8077
+ if (typeof ew !== "object" || ew === null) {
8078
+ errors.push(`"eventWiring[${i}]" must be an object`);
8079
+ continue;
8016
8080
  }
8017
- }
8018
-
8019
- // providers (optional)
8020
- if ("providers" in config) {
8021
- if (!Array.isArray(config.providers)) {
8022
- errors.push(`"providers" must be an array`);
8023
- } else {
8024
- const validClasses = ["credential", "mcp"];
8025
- for (let i = 0; i < config.providers.length; i++) {
8026
- const p = config.providers[i];
8027
- if (typeof p !== "object" || p === null) {
8028
- errors.push(`"providers[${i}]" must be an object`);
8029
- continue;
8030
- }
8031
- if (!p.type || typeof p.type !== "string") {
8032
- errors.push(
8033
- `"providers[${i}].type" must be a non-empty string`,
8034
- );
8035
- }
8036
- if (!validClasses.includes(p.providerClass)) {
8037
- errors.push(
8038
- `"providers[${i}].providerClass" must be "credential" or "mcp", got "${p.providerClass}"`,
8039
- );
8040
- }
8041
- if ("usedBy" in p && !Array.isArray(p.usedBy)) {
8042
- errors.push(`"providers[${i}].usedBy" must be an array`);
8043
- }
8044
- }
8081
+ // source
8082
+ if (
8083
+ typeof ew.source !== "object" ||
8084
+ ew.source === null ||
8085
+ !ew.source.widget ||
8086
+ !ew.source.event
8087
+ ) {
8088
+ errors.push(
8089
+ `"eventWiring[${i}].source" must have "widget" and "event" strings`,
8090
+ );
8045
8091
  }
8046
- }
8047
-
8048
- // eventWiring (optional)
8049
- if ("eventWiring" in config) {
8050
- if (!Array.isArray(config.eventWiring)) {
8051
- errors.push(`"eventWiring" must be an array`);
8052
- } else {
8053
- for (let i = 0; i < config.eventWiring.length; i++) {
8054
- const ew = config.eventWiring[i];
8055
- if (typeof ew !== "object" || ew === null) {
8056
- errors.push(`"eventWiring[${i}]" must be an object`);
8057
- continue;
8058
- }
8059
- // source
8060
- if (
8061
- typeof ew.source !== "object" ||
8062
- ew.source === null ||
8063
- !ew.source.widget ||
8064
- !ew.source.event
8065
- ) {
8066
- errors.push(
8067
- `"eventWiring[${i}].source" must have "widget" and "event" strings`,
8068
- );
8069
- }
8070
- // target
8071
- if (
8072
- typeof ew.target !== "object" ||
8073
- ew.target === null ||
8074
- !ew.target.widget ||
8075
- !ew.target.handler
8076
- ) {
8077
- errors.push(
8078
- `"eventWiring[${i}].target" must have "widget" and "handler" strings`,
8079
- );
8080
- }
8081
- }
8092
+ // target
8093
+ if (
8094
+ typeof ew.target !== "object" ||
8095
+ ew.target === null ||
8096
+ !ew.target.widget ||
8097
+ !ew.target.handler
8098
+ ) {
8099
+ errors.push(
8100
+ `"eventWiring[${i}].target" must have "widget" and "handler" strings`,
8101
+ );
8082
8102
  }
8103
+ }
8083
8104
  }
8105
+ }
8084
8106
 
8085
- // Reject unknown top-level fields
8086
- const allowedFields = Object.keys(schema.properties);
8087
- for (const key of Object.keys(config)) {
8088
- if (!allowedFields.includes(key)) {
8089
- errors.push(`Unknown field: "${key}"`);
8090
- }
8107
+ // Reject unknown top-level fields
8108
+ const allowedFields = Object.keys(schema.properties);
8109
+ for (const key of Object.keys(config)) {
8110
+ if (!allowedFields.includes(key)) {
8111
+ errors.push(`Unknown field: "${key}"`);
8091
8112
  }
8113
+ }
8092
8114
 
8093
- return { valid: errors.length === 0, errors };
8115
+ return { valid: errors.length === 0, errors };
8094
8116
  }
8095
8117
 
8096
8118
  /**
@@ -8100,29 +8122,29 @@ function validateDashboardConfig$1(config) {
8100
8122
  * @returns {Object} Config with defaults applied (does not mutate original)
8101
8123
  */
8102
8124
  function applyDefaults$1(config) {
8103
- return {
8104
- schemaVersion: CURRENT_SCHEMA_VERSION$1,
8105
- description: "",
8106
- shareable: true,
8107
- tags: [],
8108
- icon: "grip",
8109
- screenshots: [],
8110
- providers: [],
8111
- eventWiring: [],
8112
- ...config,
8113
- workspace: {
8114
- type: "workspace",
8115
- version: 1,
8116
- menuId: 1,
8117
- ...config.workspace,
8118
- },
8119
- };
8125
+ return {
8126
+ schemaVersion: CURRENT_SCHEMA_VERSION$1,
8127
+ description: "",
8128
+ shareable: true,
8129
+ tags: [],
8130
+ icon: "grip",
8131
+ screenshots: [],
8132
+ providers: [],
8133
+ eventWiring: [],
8134
+ ...config,
8135
+ workspace: {
8136
+ type: "workspace",
8137
+ version: 1,
8138
+ menuId: 1,
8139
+ ...config.workspace,
8140
+ },
8141
+ };
8120
8142
  }
8121
8143
 
8122
8144
  var dashboardConfigValidator$1 = {
8123
- validateDashboardConfig: validateDashboardConfig$1,
8124
- applyDefaults: applyDefaults$1,
8125
- CURRENT_SCHEMA_VERSION: CURRENT_SCHEMA_VERSION$1,
8145
+ validateDashboardConfig: validateDashboardConfig$1,
8146
+ applyDefaults: applyDefaults$1,
8147
+ CURRENT_SCHEMA_VERSION: CURRENT_SCHEMA_VERSION$1,
8126
8148
  };
8127
8149
 
8128
8150
  /**
@@ -8534,12 +8556,11 @@ function buildDashboardPreview(source) {
8534
8556
  const preview = {
8535
8557
  name: source.displayName || source.name || "Dashboard",
8536
8558
  description: source.description || "",
8537
- author: typeof source.author === "object"
8538
- ? source.author.name || ""
8539
- : source.author || "",
8540
- authorId: typeof source.author === "object"
8541
- ? source.author.id || ""
8542
- : "",
8559
+ author:
8560
+ typeof source.author === "object"
8561
+ ? source.author.name || ""
8562
+ : source.author || "",
8563
+ authorId: typeof source.author === "object" ? source.author.id || "" : "",
8543
8564
  version: source.version || "",
8544
8565
  icon: source.icon || "grip",
8545
8566
  tags: source.tags || [],
@@ -8567,8 +8588,12 @@ function buildDashboardPreview(source) {
8567
8588
  widgetCount: (source.widgets || []).length,
8568
8589
  eventCount: (source.eventWiring || []).length,
8569
8590
  providerCount: (source.providers || []).length,
8570
- requiredWidgets: (source.widgets || []).filter((w) => w.required !== false).length,
8571
- optionalWidgets: (source.widgets || []).filter((w) => w.required === false).length,
8591
+ requiredWidgets: (source.widgets || []).filter(
8592
+ (w) => w.required !== false,
8593
+ ).length,
8594
+ optionalWidgets: (source.widgets || []).filter(
8595
+ (w) => w.required === false,
8596
+ ).length,
8572
8597
  },
8573
8598
  };
8574
8599
 
@@ -8700,8 +8725,8 @@ var dynamicWidgetLoader$2 = {exports: {}};
8700
8725
  * Runs in the Electron main process at widget install time.
8701
8726
  */
8702
8727
 
8703
- const fs$1 = require$$2;
8704
- const path$3 = require$$1$1;
8728
+ const fs$2 = require$$2;
8729
+ const path$4 = require$$1$1;
8705
8730
 
8706
8731
  /**
8707
8732
  * Find the widgets/ directory, handling nested ZIP extraction.
@@ -8716,20 +8741,20 @@ const path$3 = require$$1$1;
8716
8741
  * @returns {string|null} Path to the widgets/ directory, or null
8717
8742
  */
8718
8743
  function findWidgetsDir$1(widgetPath) {
8719
- const direct = path$3.join(widgetPath, "widgets");
8720
- if (fs$1.existsSync(direct)) {
8744
+ const direct = path$4.join(widgetPath, "widgets");
8745
+ if (fs$2.existsSync(direct)) {
8721
8746
  return direct;
8722
8747
  }
8723
8748
 
8724
8749
  // Check configs/ directory (used by packageZip.js for distributed widgets)
8725
- const configs = path$3.join(widgetPath, "configs");
8726
- if (fs$1.existsSync(configs)) {
8750
+ const configs = path$4.join(widgetPath, "configs");
8751
+ if (fs$2.existsSync(configs)) {
8727
8752
  return configs;
8728
8753
  }
8729
8754
 
8730
8755
  // Check one level deeper for nested ZIP extraction
8731
8756
  try {
8732
- const entries = fs$1.readdirSync(widgetPath, { withFileTypes: true });
8757
+ const entries = fs$2.readdirSync(widgetPath, { withFileTypes: true });
8733
8758
  const subdirs = entries.filter(
8734
8759
  (e) =>
8735
8760
  e.isDirectory() &&
@@ -8739,8 +8764,8 @@ function findWidgetsDir$1(widgetPath) {
8739
8764
  );
8740
8765
 
8741
8766
  for (const subdir of subdirs) {
8742
- const nested = path$3.join(widgetPath, subdir.name, "widgets");
8743
- if (fs$1.existsSync(nested)) {
8767
+ const nested = path$4.join(widgetPath, subdir.name, "widgets");
8768
+ if (fs$2.existsSync(nested)) {
8744
8769
  console.log(`[WidgetCompiler] Found nested widgets/ at ${nested}`);
8745
8770
  return nested;
8746
8771
  }
@@ -8774,7 +8799,7 @@ async function compileWidget(widgetPath) {
8774
8799
  }
8775
8800
 
8776
8801
  // Discover .dash.js config files
8777
- const files = fs$1.readdirSync(widgetsDir);
8802
+ const files = fs$2.readdirSync(widgetsDir);
8778
8803
  const dashFiles = files.filter((f) => f.endsWith(".dash.js"));
8779
8804
 
8780
8805
  if (dashFiles.length === 0) {
@@ -8788,15 +8813,15 @@ async function compileWidget(widgetPath) {
8788
8813
  // Compute relative path from the entry file (in widgetPath) to widgetsDir,
8789
8814
  // since widgetsDir may be nested (e.g., ./weather-widget/widgets/).
8790
8815
  const relWidgetsDir =
8791
- "./" + path$3.relative(widgetPath, widgetsDir).split(path$3.sep).join("/");
8816
+ "./" + path$4.relative(widgetPath, widgetsDir).split(path$4.sep).join("/");
8792
8817
  const imports = [];
8793
8818
  const exportParts = [];
8794
8819
 
8795
8820
  for (const dashFile of dashFiles) {
8796
8821
  const componentName = dashFile.replace(".dash.js", "");
8797
8822
  const componentFile = `${componentName}.js`;
8798
- const componentFilePath = path$3.join(widgetsDir, componentFile);
8799
- const hasComponent = fs$1.existsSync(componentFilePath);
8823
+ const componentFilePath = path$4.join(widgetsDir, componentFile);
8824
+ const hasComponent = fs$2.existsSync(componentFilePath);
8800
8825
 
8801
8826
  // Import the config (always)
8802
8827
  imports.push(
@@ -8822,17 +8847,17 @@ async function compileWidget(widgetPath) {
8822
8847
  const entryContent = [...imports, "", ...exportParts, ""].join("\n");
8823
8848
 
8824
8849
  // Write temporary entry file in the widget root
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");
8850
+ const entryPath = path$4.join(widgetPath, "__compile_entry.js");
8851
+ const distDir = path$4.join(widgetPath, "dist");
8852
+ const outPath = path$4.join(distDir, "index.cjs.js");
8828
8853
 
8829
8854
  try {
8830
8855
  // Ensure dist/ directory exists
8831
- if (!fs$1.existsSync(distDir)) {
8832
- fs$1.mkdirSync(distDir, { recursive: true });
8856
+ if (!fs$2.existsSync(distDir)) {
8857
+ fs$2.mkdirSync(distDir, { recursive: true });
8833
8858
  }
8834
8859
 
8835
- fs$1.writeFileSync(entryPath, entryContent, "utf8");
8860
+ fs$2.writeFileSync(entryPath, entryContent, "utf8");
8836
8861
 
8837
8862
  console.log(
8838
8863
  `[WidgetCompiler] Compiling ${dashFiles.length} component(s) from ${widgetPath}`,
@@ -8873,8 +8898,8 @@ async function compileWidget(widgetPath) {
8873
8898
  } finally {
8874
8899
  // Clean up temporary entry file
8875
8900
  try {
8876
- if (fs$1.existsSync(entryPath)) {
8877
- fs$1.unlinkSync(entryPath);
8901
+ if (fs$2.existsSync(entryPath)) {
8902
+ fs$2.unlinkSync(entryPath);
8878
8903
  }
8879
8904
  } catch (cleanupError) {
8880
8905
  // Non-fatal
@@ -8900,8 +8925,8 @@ var widgetCompiler$1 = { compileWidget, findWidgetsDir: findWidgetsDir$1 };
8900
8925
  * Integrates with ComponentManager for automatic registration
8901
8926
  */
8902
8927
 
8903
- const fs = require$$2;
8904
- const path$2 = require$$1$1;
8928
+ const fs$1 = require$$2;
8929
+ const path$3 = require$$1$1;
8905
8930
  const vm = require$$2$5;
8906
8931
  const { findWidgetsDir } = widgetCompiler$1;
8907
8932
 
@@ -8942,14 +8967,14 @@ class DynamicWidgetLoader {
8942
8967
  );
8943
8968
 
8944
8969
  const widgetsDir =
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`);
8970
+ findWidgetsDir(widgetPath) || path$3.join(widgetPath, "widgets");
8971
+ const componentPath = path$3.join(widgetsDir, `${componentName}.js`);
8972
+ const configPath = path$3.join(widgetsDir, `${componentName}.dash.js`);
8948
8973
 
8949
- if (!fs.existsSync(componentPath)) {
8974
+ if (!fs$1.existsSync(componentPath)) {
8950
8975
  throw new Error(`Component file not found: ${componentPath}`);
8951
8976
  }
8952
- if (!fs.existsSync(configPath)) {
8977
+ if (!fs$1.existsSync(configPath)) {
8953
8978
  throw new Error(`Config file not found: ${configPath}`);
8954
8979
  }
8955
8980
 
@@ -9000,7 +9025,7 @@ class DynamicWidgetLoader {
9000
9025
  */
9001
9026
  async loadConfigFile(configPath) {
9002
9027
  try {
9003
- const source = fs.readFileSync(configPath, "utf8");
9028
+ const source = fs$1.readFileSync(configPath, "utf8");
9004
9029
 
9005
9030
  let exportMatch = source.match(/export\s+default\s+({[\s\S]*});?\s*$/);
9006
9031
 
@@ -9055,7 +9080,7 @@ class DynamicWidgetLoader {
9055
9080
  return [];
9056
9081
  }
9057
9082
 
9058
- const files = fs.readdirSync(widgetsDir);
9083
+ const files = fs$1.readdirSync(widgetsDir);
9059
9084
  const widgets = new Set();
9060
9085
 
9061
9086
  files.forEach((file) => {
@@ -10058,6 +10083,289 @@ var dynamicWidgetLoaderExports = dynamicWidgetLoader$2.exports;
10058
10083
 
10059
10084
  var widgetRegistryExports = widgetRegistry$1.exports;
10060
10085
 
10086
+ /**
10087
+ * registryAuthController.js
10088
+ *
10089
+ * Manages authentication with the Dash registry service.
10090
+ * Uses OAuth device code flow for desktop app authentication.
10091
+ *
10092
+ * Flow:
10093
+ * 1. App calls initiateDeviceFlow() — gets device code + verification URL
10094
+ * 2. User opens verification URL in browser, signs in, enters code
10095
+ * 3. App polls pollForToken() until authorized
10096
+ * 4. Token stored securely via electron-store (encrypted)
10097
+ */
10098
+
10099
+ const REGISTRY_BASE_URL$1 =
10100
+ process.env.DASH_REGISTRY_API_URL || "https://registry.trops.dev";
10101
+
10102
+ // Lazy-load electron-store to avoid issues when not installed
10103
+ let store = null;
10104
+ function getStore() {
10105
+ if (!store) {
10106
+ const Store = require$$1;
10107
+ store = new Store({
10108
+ name: "dash-registry-auth",
10109
+ encryptionKey: "dash-registry-v1",
10110
+ });
10111
+ }
10112
+ return store;
10113
+ }
10114
+
10115
+ /**
10116
+ * Initiate the OAuth device code flow.
10117
+ * Returns the device code, user code, and verification URL.
10118
+ *
10119
+ * @returns {Promise<Object>} { deviceCode, userCode, verificationUrl, verificationUrlComplete, expiresIn, interval }
10120
+ */
10121
+ async function initiateDeviceFlow$1() {
10122
+ const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/device`, {
10123
+ method: "POST",
10124
+ headers: { "Content-Type": "application/json" },
10125
+ });
10126
+
10127
+ if (!response.ok) {
10128
+ throw new Error(`Device flow initiation failed: ${response.status}`);
10129
+ }
10130
+
10131
+ const data = await response.json();
10132
+
10133
+ return {
10134
+ deviceCode: data.device_code,
10135
+ userCode: data.user_code,
10136
+ verificationUrl: data.verification_uri,
10137
+ verificationUrlComplete: data.verification_uri_complete,
10138
+ expiresIn: data.expires_in,
10139
+ interval: data.interval,
10140
+ };
10141
+ }
10142
+
10143
+ /**
10144
+ * Poll the registry for token after user completes browser auth.
10145
+ *
10146
+ * @param {string} deviceCode - The device code from initiateDeviceFlow()
10147
+ * @returns {Promise<Object>} { status: 'pending' | 'authorized' | 'expired', token?, userId? }
10148
+ */
10149
+ async function pollForToken$1(deviceCode) {
10150
+ const response = await fetch(
10151
+ `${REGISTRY_BASE_URL$1}/api/auth/device?device_code=${encodeURIComponent(deviceCode)}`,
10152
+ );
10153
+
10154
+ if (response.status === 428) {
10155
+ return { status: "pending" };
10156
+ }
10157
+
10158
+ if (response.status === 400) {
10159
+ const data = await response.json();
10160
+ if (data.error === "expired_token") {
10161
+ return { status: "expired" };
10162
+ }
10163
+ return { status: "pending" };
10164
+ }
10165
+
10166
+ if (response.ok) {
10167
+ const data = await response.json();
10168
+
10169
+ // Store the token securely
10170
+ const s = getStore();
10171
+ s.set("accessToken", data.access_token);
10172
+ s.set("userId", data.user_id);
10173
+ s.set("tokenType", data.token_type);
10174
+ s.set("authenticatedAt", new Date().toISOString());
10175
+
10176
+ return {
10177
+ status: "authorized",
10178
+ token: data.access_token,
10179
+ userId: data.user_id,
10180
+ };
10181
+ }
10182
+
10183
+ throw new Error(`Unexpected response: ${response.status}`);
10184
+ }
10185
+
10186
+ /**
10187
+ * Get the stored auth token.
10188
+ *
10189
+ * @returns {Object|null} { token, userId, authenticatedAt } or null if not authenticated
10190
+ */
10191
+ function getStoredToken$1() {
10192
+ try {
10193
+ const s = getStore();
10194
+ const token = s.get("accessToken");
10195
+ if (!token) return null;
10196
+
10197
+ return {
10198
+ token,
10199
+ userId: s.get("userId"),
10200
+ authenticatedAt: s.get("authenticatedAt"),
10201
+ };
10202
+ } catch {
10203
+ return null;
10204
+ }
10205
+ }
10206
+
10207
+ /**
10208
+ * Check if the user is authenticated with the registry.
10209
+ *
10210
+ * @returns {Object} { authenticated: boolean, userId?: string }
10211
+ */
10212
+ function getAuthStatus() {
10213
+ const stored = getStoredToken$1();
10214
+ if (!stored) {
10215
+ return { authenticated: false };
10216
+ }
10217
+
10218
+ return {
10219
+ authenticated: true,
10220
+ userId: stored.userId,
10221
+ authenticatedAt: stored.authenticatedAt,
10222
+ };
10223
+ }
10224
+
10225
+ /**
10226
+ * Get the user's registry profile.
10227
+ *
10228
+ * @returns {Promise<Object|null>} User profile or null
10229
+ */
10230
+ async function getRegistryProfile$1() {
10231
+ const stored = getStoredToken$1();
10232
+ if (!stored) return null;
10233
+
10234
+ try {
10235
+ const response = await fetch(`${REGISTRY_BASE_URL$1}/api/auth/me`, {
10236
+ headers: {
10237
+ Authorization: `Bearer ${stored.token}`,
10238
+ },
10239
+ });
10240
+
10241
+ if (!response.ok) return null;
10242
+
10243
+ const data = await response.json();
10244
+ return data.user || null;
10245
+ } catch {
10246
+ return null;
10247
+ }
10248
+ }
10249
+
10250
+ /**
10251
+ * Clear stored auth token (logout).
10252
+ */
10253
+ function clearToken() {
10254
+ try {
10255
+ const s = getStore();
10256
+ s.clear();
10257
+ console.log("[RegistryAuthController] Token cleared");
10258
+ } catch (err) {
10259
+ console.error("[RegistryAuthController] Error clearing token:", err);
10260
+ }
10261
+ }
10262
+
10263
+ var registryAuthController$1 = {
10264
+ initiateDeviceFlow: initiateDeviceFlow$1,
10265
+ pollForToken: pollForToken$1,
10266
+ getStoredToken: getStoredToken$1,
10267
+ getAuthStatus,
10268
+ getRegistryProfile: getRegistryProfile$1,
10269
+ clearToken,
10270
+ };
10271
+
10272
+ /**
10273
+ * registryApiController.js
10274
+ *
10275
+ * Client for the Dash registry API.
10276
+ * Handles publishing packages and generating registry URLs.
10277
+ */
10278
+
10279
+ const fs = require$$2;
10280
+ const path$2 = require$$1$1;
10281
+ const { getStoredToken } = registryAuthController$1;
10282
+
10283
+ const REGISTRY_BASE_URL =
10284
+ process.env.DASH_REGISTRY_API_URL || "https://registry.trops.dev";
10285
+
10286
+ /**
10287
+ * Publish a package to the registry.
10288
+ *
10289
+ * @param {string} zipPath - Path to the ZIP file
10290
+ * @param {Object} manifest - Package manifest JSON
10291
+ * @returns {Promise<Object>} { success, registryUrl, packageId, version, error? }
10292
+ */
10293
+ async function publishToRegistry$1(zipPath, manifest) {
10294
+ const auth = getStoredToken();
10295
+ if (!auth) {
10296
+ return {
10297
+ success: false,
10298
+ error: "Not authenticated with registry",
10299
+ authRequired: true,
10300
+ };
10301
+ }
10302
+
10303
+ try {
10304
+ // Read the ZIP file
10305
+ const zipBuffer = fs.readFileSync(zipPath);
10306
+
10307
+ // Create FormData with the ZIP and manifest
10308
+ const formData = new FormData();
10309
+ formData.append(
10310
+ "file",
10311
+ new Blob([zipBuffer], { type: "application/zip" }),
10312
+ path$2.basename(zipPath),
10313
+ );
10314
+ formData.append("manifest", JSON.stringify(manifest));
10315
+
10316
+ // POST to registry
10317
+ const response = await fetch(`${REGISTRY_BASE_URL}/api/publish`, {
10318
+ method: "POST",
10319
+ headers: {
10320
+ Authorization: `Bearer ${auth.token}`,
10321
+ },
10322
+ body: formData,
10323
+ });
10324
+
10325
+ const data = await response.json();
10326
+
10327
+ if (!response.ok) {
10328
+ return {
10329
+ success: false,
10330
+ error: data.error || `Publish failed: ${response.status}`,
10331
+ details: data.details,
10332
+ };
10333
+ }
10334
+
10335
+ return {
10336
+ success: true,
10337
+ registryUrl: data.registryUrl,
10338
+ packageId: data.packageId,
10339
+ version: data.version,
10340
+ downloadUrl: data.downloadUrl,
10341
+ warnings: data.warnings,
10342
+ };
10343
+ } catch (err) {
10344
+ console.error("[RegistryApiController] Publish error:", err);
10345
+ return {
10346
+ success: false,
10347
+ error: err.message || "Failed to publish to registry",
10348
+ };
10349
+ }
10350
+ }
10351
+
10352
+ /**
10353
+ * Get the registry URL for a published package.
10354
+ *
10355
+ * @param {string} scope - Package scope (username)
10356
+ * @param {string} name - Package name
10357
+ * @returns {string} Full registry URL
10358
+ */
10359
+ function getRegistryUrl$1(scope, name) {
10360
+ return `${REGISTRY_BASE_URL}/package/${scope}/${name}`;
10361
+ }
10362
+
10363
+ var registryApiController$1 = {
10364
+ publishToRegistry: publishToRegistry$1,
10365
+ getRegistryUrl: getRegistryUrl$1,
10366
+ REGISTRY_BASE_URL,
10367
+ };
10368
+
10061
10369
  /**
10062
10370
  * dashboardConfigController.js
10063
10371
  *
@@ -10146,10 +10454,9 @@ async function exportDashboardConfig$1(
10146
10454
  schemaVersion: CURRENT_SCHEMA_VERSION,
10147
10455
  name: workspace.name || workspace.label || "Exported Dashboard",
10148
10456
  description: options.description || "",
10149
- author: {
10150
- name: options.authorName || "",
10151
- id: options.authorId || "",
10152
- },
10457
+ ...(options.authorName
10458
+ ? { author: { name: options.authorName, id: options.authorId || "" } }
10459
+ : {}),
10153
10460
  shareable: true,
10154
10461
  tags: options.tags || [],
10155
10462
  icon: options.icon || "grip",
@@ -10606,7 +10913,9 @@ async function installDashboardFromRegistry$1(
10606
10913
  * @returns {Promise<Object>} Compatibility report
10607
10914
  */
10608
10915
  async function checkCompatibility$1(dashboardWidgets, widgetRegistry = null) {
10609
- const { checkDashboardCompatibility } = dashboardConfigUtils$1;
10916
+ const {
10917
+ checkDashboardCompatibility,
10918
+ } = dashboardConfigUtils$1;
10610
10919
  const { fetchRegistryIndex } = registryController$1;
10611
10920
 
10612
10921
  const installedWidgets = widgetRegistry ? widgetRegistry.getWidgets() : [];
@@ -10659,7 +10968,9 @@ async function prepareDashboardForPublish$1(
10659
10968
  widgetRegistry = null,
10660
10969
  ) {
10661
10970
  try {
10662
- const { generateRegistryManifest } = dashboardConfigUtils$1;
10971
+ const {
10972
+ generateRegistryManifest,
10973
+ } = dashboardConfigUtils$1;
10663
10974
 
10664
10975
  // 1. Read workspace
10665
10976
  const filename = path$1.join(
@@ -10681,10 +10992,14 @@ async function prepareDashboardForPublish$1(
10681
10992
  }
10682
10993
 
10683
10994
  // 2. Check shareable flag — imported dashboards cannot be published
10684
- if (workspace._dashboardConfig && workspace._dashboardConfig.shareable === false) {
10995
+ if (
10996
+ workspace._dashboardConfig &&
10997
+ workspace._dashboardConfig.shareable === false
10998
+ ) {
10685
10999
  return {
10686
11000
  success: false,
10687
- error: "This dashboard was imported and cannot be published. Only dashboards you created can be shared.",
11001
+ error:
11002
+ "This dashboard was imported and cannot be published. Only dashboards you created can be shared.",
10688
11003
  };
10689
11004
  }
10690
11005
 
@@ -10700,10 +11015,9 @@ async function prepareDashboardForPublish$1(
10700
11015
  schemaVersion: CURRENT_SCHEMA_VERSION,
10701
11016
  name: workspace.name || workspace.label || "Dashboard",
10702
11017
  description: options.description || "",
10703
- author: {
10704
- name: options.authorName || "",
10705
- id: options.authorId || "",
10706
- },
11018
+ ...(options.authorName
11019
+ ? { author: { name: options.authorName, id: options.authorId || "" } }
11020
+ : {}),
10707
11021
  shareable: true,
10708
11022
  tags: options.tags || [],
10709
11023
  icon: options.icon || "grip",
@@ -10730,29 +11044,26 @@ async function prepareDashboardForPublish$1(
10730
11044
  };
10731
11045
  }
10732
11046
 
10733
- // 5. Verify all widgets exist in the registry
11047
+ // 5. Check which widgets exist in the registry (soft warning, not blocking)
10734
11048
  const { fetchRegistryIndex } = registryController$1;
10735
11049
  let registryPackages = [];
11050
+ let registryCheckFailed = false;
10736
11051
  try {
10737
11052
  const index = await fetchRegistryIndex();
10738
11053
  registryPackages = index.packages || [];
10739
11054
  } catch (err) {
10740
- return {
10741
- success: false,
10742
- error: `Cannot verify widgets in registry: ${err.message}`,
10743
- };
11055
+ console.warn(
11056
+ `[DashboardConfigController] Unable to verify registry: ${err.message}`,
11057
+ );
11058
+ registryCheckFailed = true;
10744
11059
  }
10745
11060
 
10746
- const registryNames = new Set(registryPackages.map((p) => p.name));
10747
- const missingFromRegistry = widgets
10748
- .filter((w) => w.required !== false && !registryNames.has(w.package))
10749
- .map((w) => w.package);
10750
-
10751
- if (missingFromRegistry.length > 0) {
10752
- return {
10753
- success: false,
10754
- error: `Required widgets not found in registry: ${missingFromRegistry.join(", ")}. Publish them first.`,
10755
- };
11061
+ let missingFromRegistry = [];
11062
+ if (!registryCheckFailed) {
11063
+ const registryNames = new Set(registryPackages.map((p) => p.name));
11064
+ missingFromRegistry = widgets
11065
+ .filter((w) => w.required !== false && !registryNames.has(w.package))
11066
+ .map((w) => w.package);
10756
11067
  }
10757
11068
 
10758
11069
  // 6. Generate registry manifest
@@ -10779,7 +11090,10 @@ async function prepareDashboardForPublish$1(
10779
11090
 
10780
11091
  // 8. Create ZIP with manifest and dashboard config
10781
11092
  const zip = new AdmZip();
10782
- zip.addFile("manifest.json", Buffer.from(JSON.stringify(manifest, null, 2), "utf-8"));
11093
+ zip.addFile(
11094
+ "manifest.json",
11095
+ Buffer.from(JSON.stringify(manifest, null, 2), "utf-8"),
11096
+ );
10783
11097
  zip.addFile(
10784
11098
  `${sanitizedName}.dashboard.json`,
10785
11099
  Buffer.from(JSON.stringify(dashboardConfig, null, 2), "utf-8"),
@@ -10790,11 +11104,44 @@ async function prepareDashboardForPublish$1(
10790
11104
  `[DashboardConfigController] Prepared publish package: ${filePath}`,
10791
11105
  );
10792
11106
 
11107
+ // 9. Attempt to publish to registry if authenticated
11108
+ let registrySubmission = null;
11109
+ try {
11110
+ const { getAuthStatus } = registryAuthController$1;
11111
+ const { publishToRegistry } = registryApiController$1;
11112
+ const authStatus = getAuthStatus();
11113
+
11114
+ if (authStatus.authenticated) {
11115
+ console.log("[DashboardConfigController] Publishing to registry...");
11116
+ registrySubmission = await publishToRegistry(filePath, manifest);
11117
+ if (registrySubmission.success) {
11118
+ console.log(
11119
+ `[DashboardConfigController] Published to registry: ${registrySubmission.registryUrl}`,
11120
+ );
11121
+ } else {
11122
+ console.warn(
11123
+ `[DashboardConfigController] Registry publish failed: ${registrySubmission.error}`,
11124
+ );
11125
+ }
11126
+ } else {
11127
+ registrySubmission = { success: false, authRequired: true };
11128
+ }
11129
+ } catch (err) {
11130
+ console.warn(
11131
+ `[DashboardConfigController] Registry publish error: ${err.message}`,
11132
+ );
11133
+ registrySubmission = { success: false, error: err.message };
11134
+ }
11135
+
10793
11136
  return {
10794
11137
  success: true,
10795
11138
  filePath,
10796
11139
  manifest,
10797
11140
  config: dashboardConfig,
11141
+ warnings:
11142
+ missingFromRegistry.length > 0 ? missingFromRegistry : undefined,
11143
+ registryCheckFailed: registryCheckFailed || undefined,
11144
+ registrySubmission,
10798
11145
  };
10799
11146
  } catch (error) {
10800
11147
  console.error(
@@ -10817,8 +11164,10 @@ async function prepareDashboardForPublish$1(
10817
11164
  * @returns {Promise<Object>} Preview data with compatibility report
10818
11165
  */
10819
11166
  async function getDashboardPreview$1(packageName, widgetRegistry = null) {
10820
- const { buildDashboardPreview, checkDashboardCompatibility } =
10821
- dashboardConfigUtils$1;
11167
+ const {
11168
+ buildDashboardPreview,
11169
+ checkDashboardCompatibility,
11170
+ } = dashboardConfigUtils$1;
10822
11171
  const { getPackage, fetchRegistryIndex } = registryController$1;
10823
11172
 
10824
11173
  const pkg = await getPackage(packageName);
@@ -10883,7 +11232,9 @@ async function checkDashboardUpdatesForApp$1(appId) {
10883
11232
  return {
10884
11233
  success: true,
10885
11234
  updates,
10886
- totalInstalled: workspaces.filter((w) => w._dashboardConfig?.registryPackage).length,
11235
+ totalInstalled: workspaces.filter(
11236
+ (w) => w._dashboardConfig?.registryPackage,
11237
+ ).length,
10887
11238
  };
10888
11239
  } catch (error) {
10889
11240
  console.error(
@@ -10907,7 +11258,9 @@ async function checkDashboardUpdatesForApp$1(appId) {
10907
11258
  * @returns {Object} Setup manifest with per-provider status
10908
11259
  */
10909
11260
  function getProviderSetupManifest$1(appId, requiredProviders = []) {
10910
- const { buildProviderSetupManifest } = dashboardConfigUtils$1;
11261
+ const {
11262
+ buildProviderSetupManifest,
11263
+ } = dashboardConfigUtils$1;
10911
11264
  const { listProviders } = requireProviderController();
10912
11265
 
10913
11266
  let configuredProviders = [];
@@ -11188,6 +11541,18 @@ const {
11188
11541
  checkDashboardUpdatesForApp,
11189
11542
  getProviderSetupManifest,
11190
11543
  } = dashboardConfigController$1;
11544
+ const {
11545
+ initiateDeviceFlow,
11546
+ pollForToken,
11547
+ getStoredToken: getRegistryToken,
11548
+ getAuthStatus: getRegistryAuthStatus,
11549
+ getRegistryProfile,
11550
+ clearToken: clearRegistryToken,
11551
+ } = registryAuthController$1;
11552
+ const {
11553
+ publishToRegistry,
11554
+ getRegistryUrl,
11555
+ } = registryApiController$1;
11191
11556
  const {
11192
11557
  saveDashboardRating,
11193
11558
  getDashboardRating,
@@ -11250,9 +11615,17 @@ var controller = {
11250
11615
  listDashboardRatings,
11251
11616
  deleteDashboardRating,
11252
11617
  enrichPackagesWithRatings,
11618
+ initiateDeviceFlow,
11619
+ pollForToken,
11620
+ getRegistryToken,
11621
+ getRegistryAuthStatus,
11622
+ getRegistryProfile,
11623
+ clearRegistryToken,
11624
+ publishToRegistry,
11625
+ getRegistryUrl,
11253
11626
  };
11254
11627
 
11255
- const { ipcRenderer: ipcRenderer$j } = require$$0$1;
11628
+ const { ipcRenderer: ipcRenderer$k } = require$$0$1;
11256
11629
  const {
11257
11630
  SECURE_STORE_ENCRYPTION_CHECK,
11258
11631
  SECURE_STORE_SET_DATA,
@@ -11264,10 +11637,10 @@ const {
11264
11637
  */
11265
11638
  const secureStoreApi$2 = {
11266
11639
  isEncryptionAvailable: () =>
11267
- ipcRenderer$j.invoke(SECURE_STORE_ENCRYPTION_CHECK, {}),
11640
+ ipcRenderer$k.invoke(SECURE_STORE_ENCRYPTION_CHECK, {}),
11268
11641
  saveData: (key, value) =>
11269
- ipcRenderer$j.invoke(SECURE_STORE_SET_DATA, { key, value }),
11270
- getData: (key) => ipcRenderer$j.invoke(SECURE_STORE_GET_DATA, { key }),
11642
+ ipcRenderer$k.invoke(SECURE_STORE_SET_DATA, { key, value }),
11643
+ getData: (key) => ipcRenderer$k.invoke(SECURE_STORE_GET_DATA, { key }),
11271
11644
  };
11272
11645
 
11273
11646
  var secureStoreApi_1 = secureStoreApi$2;
@@ -11278,7 +11651,7 @@ var secureStoreApi_1 = secureStoreApi$2;
11278
11651
  * Handle the workspace configuration file
11279
11652
  */
11280
11653
 
11281
- const { ipcRenderer: ipcRenderer$i } = require$$0$1;
11654
+ const { ipcRenderer: ipcRenderer$j } = require$$0$1;
11282
11655
  const {
11283
11656
  WORKSPACE_LIST,
11284
11657
  WORKSPACE_SAVE,
@@ -11295,7 +11668,7 @@ const workspaceApi$2 = {
11295
11668
  */
11296
11669
  listWorkspacesForApplication: (appId) => {
11297
11670
  console.log("listWorkspacesForApplication called with appId:", appId);
11298
- return ipcRenderer$i.invoke(WORKSPACE_LIST, { appId });
11671
+ return ipcRenderer$j.invoke(WORKSPACE_LIST, { appId });
11299
11672
  },
11300
11673
 
11301
11674
  /**
@@ -11306,7 +11679,7 @@ const workspaceApi$2 = {
11306
11679
  * @returns
11307
11680
  */
11308
11681
  saveWorkspaceForApplication: (appId, data) =>
11309
- ipcRenderer$i.invoke(WORKSPACE_SAVE, { appId, data }),
11682
+ ipcRenderer$j.invoke(WORKSPACE_SAVE, { appId, data }),
11310
11683
 
11311
11684
  /**
11312
11685
  * deleteWorkspaceForApplication
@@ -11316,7 +11689,7 @@ const workspaceApi$2 = {
11316
11689
  * @returns
11317
11690
  */
11318
11691
  deleteWorkspaceForApplication: (appId, workspaceId) =>
11319
- ipcRenderer$i.invoke(WORKSPACE_DELETE, { appId, workspaceId }),
11692
+ ipcRenderer$j.invoke(WORKSPACE_DELETE, { appId, workspaceId }),
11320
11693
  };
11321
11694
 
11322
11695
  var workspaceApi_1 = workspaceApi$2;
@@ -11328,15 +11701,15 @@ var workspaceApi_1 = workspaceApi$2;
11328
11701
  */
11329
11702
 
11330
11703
  // ipcRenderer that must be used to invoke the events
11331
- const { ipcRenderer: ipcRenderer$h } = require$$0$1;
11704
+ const { ipcRenderer: ipcRenderer$i } = require$$0$1;
11332
11705
 
11333
11706
  const { LAYOUT_LIST, LAYOUT_SAVE } = events$8;
11334
11707
 
11335
11708
  const layoutApi$2 = {
11336
11709
  listLayoutsForApplication: (appId) =>
11337
- ipcRenderer$h.invoke(LAYOUT_LIST, { appId }),
11710
+ ipcRenderer$i.invoke(LAYOUT_LIST, { appId }),
11338
11711
  saveLayoutForApplication: (appId, data) =>
11339
- ipcRenderer$h.invoke(LAYOUT_SAVE, { appId, data }),
11712
+ ipcRenderer$i.invoke(LAYOUT_SAVE, { appId, data }),
11340
11713
  };
11341
11714
 
11342
11715
  var layoutApi_1 = layoutApi$2;
@@ -11348,7 +11721,7 @@ var layoutApi_1 = layoutApi$2;
11348
11721
  */
11349
11722
 
11350
11723
  // ipcRenderer that must be used to invoke the events
11351
- const { ipcRenderer: ipcRenderer$g } = require$$0$1;
11724
+ const { ipcRenderer: ipcRenderer$h } = require$$0$1;
11352
11725
 
11353
11726
  const {
11354
11727
  DATA_JSON_TO_CSV_FILE,
@@ -11367,7 +11740,7 @@ const {
11367
11740
  const dataApi$2 = {
11368
11741
  // convert a json array of objects to a csv string and save to file
11369
11742
  convertJsonToCsvFile: (appId, jsonObject, filename) =>
11370
- ipcRenderer$g.invoke(DATA_JSON_TO_CSV_FILE, {
11743
+ ipcRenderer$h.invoke(DATA_JSON_TO_CSV_FILE, {
11371
11744
  appId,
11372
11745
  jsonObject,
11373
11746
  filename,
@@ -11375,10 +11748,10 @@ const dataApi$2 = {
11375
11748
 
11376
11749
  // convert a json array of objects to a csv string and return a string
11377
11750
  convertJsonToCsvString: (appId, jsonObject) =>
11378
- ipcRenderer$g.invoke(DATA_JSON_TO_CSV_STRING, { appId, jsonObject }),
11751
+ ipcRenderer$h.invoke(DATA_JSON_TO_CSV_STRING, { appId, jsonObject }),
11379
11752
 
11380
11753
  parseXMLStream: (filepath, outpath, start) =>
11381
- ipcRenderer$g.invoke(PARSE_XML_STREAM, {
11754
+ ipcRenderer$h.invoke(PARSE_XML_STREAM, {
11382
11755
  filepath,
11383
11756
  outpath,
11384
11757
  start,
@@ -11392,7 +11765,7 @@ const dataApi$2 = {
11392
11765
  headers = null,
11393
11766
  limit = null,
11394
11767
  ) => {
11395
- ipcRenderer$g.invoke(PARSE_CSV_STREAM, {
11768
+ ipcRenderer$h.invoke(PARSE_CSV_STREAM, {
11396
11769
  filepath,
11397
11770
  outpath,
11398
11771
  delimiter,
@@ -11403,15 +11776,15 @@ const dataApi$2 = {
11403
11776
  },
11404
11777
 
11405
11778
  readLinesFromFile: (filepath, lineCount) => {
11406
- ipcRenderer$g.invoke(READ_LINES, { filepath, lineCount });
11779
+ ipcRenderer$h.invoke(READ_LINES, { filepath, lineCount });
11407
11780
  },
11408
11781
 
11409
11782
  readJSONFromFile: (filepath, objectCount = null) => {
11410
- ipcRenderer$g.invoke(READ_JSON, { filepath, objectCount });
11783
+ ipcRenderer$h.invoke(READ_JSON, { filepath, objectCount });
11411
11784
  },
11412
11785
 
11413
11786
  readDataFromURL: (url, toFilepath) => {
11414
- ipcRenderer$g.invoke(READ_DATA_URL, { url, toFilepath });
11787
+ ipcRenderer$h.invoke(READ_DATA_URL, { url, toFilepath });
11415
11788
  },
11416
11789
 
11417
11790
  /*
@@ -11420,7 +11793,7 @@ const dataApi$2 = {
11420
11793
  * @param {object} returnEmpty the return empty object
11421
11794
  */
11422
11795
  saveData: (data, filename, append, returnEmpty, uuid) =>
11423
- ipcRenderer$g.invoke(DATA_SAVE_TO_FILE, {
11796
+ ipcRenderer$h.invoke(DATA_SAVE_TO_FILE, {
11424
11797
  data,
11425
11798
  filename,
11426
11799
  append,
@@ -11432,14 +11805,14 @@ const dataApi$2 = {
11432
11805
  * @param {string} filename the filename to read (not path)
11433
11806
  */
11434
11807
  readData: (filename, returnEmpty = []) =>
11435
- ipcRenderer$g.invoke(DATA_READ_FROM_FILE, { filename, returnEmpty }),
11808
+ ipcRenderer$h.invoke(DATA_READ_FROM_FILE, { filename, returnEmpty }),
11436
11809
 
11437
11810
  /**
11438
11811
  * transformFile
11439
11812
  * @returns
11440
11813
  */
11441
11814
  transformFile: (filepath, outFilepath, mappingFunctionBody, args) => {
11442
- ipcRenderer$g.invoke(TRANSFORM_FILE, {
11815
+ ipcRenderer$h.invoke(TRANSFORM_FILE, {
11443
11816
  filepath,
11444
11817
  outFilepath,
11445
11818
  mappingFunctionBody,
@@ -11448,7 +11821,7 @@ const dataApi$2 = {
11448
11821
  },
11449
11822
 
11450
11823
  extractColorsFromImageURL: (url) => {
11451
- ipcRenderer$g.invoke(EXTRACT_COLORS_FROM_IMAGE, {
11824
+ ipcRenderer$h.invoke(EXTRACT_COLORS_FROM_IMAGE, {
11452
11825
  url,
11453
11826
  });
11454
11827
  },
@@ -11463,7 +11836,7 @@ var dataApi_1 = dataApi$2;
11463
11836
  */
11464
11837
 
11465
11838
  // ipcRenderer that must be used to invoke the events
11466
- const { ipcRenderer: ipcRenderer$f } = require$$0$1;
11839
+ const { ipcRenderer: ipcRenderer$g } = require$$0$1;
11467
11840
 
11468
11841
  const {
11469
11842
  SETTINGS_GET,
@@ -11474,14 +11847,14 @@ const {
11474
11847
  } = events$8;
11475
11848
 
11476
11849
  const settingsApi$2 = {
11477
- getSettingsForApplication: () => ipcRenderer$f.invoke(SETTINGS_GET, {}),
11850
+ getSettingsForApplication: () => ipcRenderer$g.invoke(SETTINGS_GET, {}),
11478
11851
  saveSettingsForApplication: (data) =>
11479
- ipcRenderer$f.invoke(SETTINGS_SAVE, { data }),
11480
- getDataDirectory: () => ipcRenderer$f.invoke(SETTINGS_GET_DATA_DIR, {}),
11852
+ ipcRenderer$g.invoke(SETTINGS_SAVE, { data }),
11853
+ getDataDirectory: () => ipcRenderer$g.invoke(SETTINGS_GET_DATA_DIR, {}),
11481
11854
  setDataDirectory: (dataDirectory) =>
11482
- ipcRenderer$f.invoke(SETTINGS_SET_DATA_DIR, { dataDirectory }),
11855
+ ipcRenderer$g.invoke(SETTINGS_SET_DATA_DIR, { dataDirectory }),
11483
11856
  migrateDataDirectory: (oldDirectory, newDirectory) =>
11484
- ipcRenderer$f.invoke(SETTINGS_MIGRATE_DATA_DIR, {
11857
+ ipcRenderer$g.invoke(SETTINGS_MIGRATE_DATA_DIR, {
11485
11858
  oldDirectory,
11486
11859
  newDirectory,
11487
11860
  }),
@@ -11496,7 +11869,7 @@ var settingsApi_1 = settingsApi$2;
11496
11869
  */
11497
11870
 
11498
11871
  // ipcRenderer that must be used to invoke the events
11499
- const { ipcRenderer: ipcRenderer$e } = require$$0$1;
11872
+ const { ipcRenderer: ipcRenderer$f } = require$$0$1;
11500
11873
 
11501
11874
  const { CHOOSE_FILE } = events$8;
11502
11875
 
@@ -11508,7 +11881,7 @@ const dialogApi$2 = {
11508
11881
  */
11509
11882
  chooseFile: (allowFile = true, extensions = ["*"]) => {
11510
11883
  console.log("dialog api choose file");
11511
- return ipcRenderer$e.invoke(CHOOSE_FILE, { allowFile, extensions });
11884
+ return ipcRenderer$f.invoke(CHOOSE_FILE, { allowFile, extensions });
11512
11885
  },
11513
11886
  };
11514
11887
 
@@ -11527,7 +11900,7 @@ var dialogApi_1 = dialogApi$2;
11527
11900
  * mainApi.widgets.uninstall('Weather')
11528
11901
  */
11529
11902
 
11530
- const { ipcRenderer: ipcRenderer$d } = require$$0$1;
11903
+ const { ipcRenderer: ipcRenderer$e } = require$$0$1;
11531
11904
 
11532
11905
  const widgetApi$2 = {
11533
11906
  /**
@@ -11536,7 +11909,7 @@ const widgetApi$2 = {
11536
11909
  */
11537
11910
  list: async () => {
11538
11911
  try {
11539
- return await ipcRenderer$d.invoke("widget:list");
11912
+ return await ipcRenderer$e.invoke("widget:list");
11540
11913
  } catch (error) {
11541
11914
  console.error("[WidgetApi] Error listing widgets:", error);
11542
11915
  throw error;
@@ -11550,7 +11923,7 @@ const widgetApi$2 = {
11550
11923
  */
11551
11924
  get: async (widgetName) => {
11552
11925
  try {
11553
- return await ipcRenderer$d.invoke("widget:get", widgetName);
11926
+ return await ipcRenderer$e.invoke("widget:get", widgetName);
11554
11927
  } catch (error) {
11555
11928
  console.error(`[WidgetApi] Error getting widget ${widgetName}:`, error);
11556
11929
  throw error;
@@ -11581,7 +11954,7 @@ const widgetApi$2 = {
11581
11954
  console.log(
11582
11955
  `[WidgetApi] Installing widget: ${widgetName} from ${downloadUrl}`,
11583
11956
  );
11584
- const config = await ipcRenderer$d.invoke(
11957
+ const config = await ipcRenderer$e.invoke(
11585
11958
  "widget:install",
11586
11959
  widgetName,
11587
11960
  downloadUrl,
@@ -11621,7 +11994,7 @@ const widgetApi$2 = {
11621
11994
  console.log(
11622
11995
  `[WidgetApi] Installing local widget: ${widgetName} from ${localPath}`,
11623
11996
  );
11624
- const config = await ipcRenderer$d.invoke(
11997
+ const config = await ipcRenderer$e.invoke(
11625
11998
  "widget:install-local",
11626
11999
  widgetName,
11627
12000
  localPath,
@@ -11652,7 +12025,7 @@ const widgetApi$2 = {
11652
12025
  loadFolder: async (folderPath) => {
11653
12026
  try {
11654
12027
  console.log(`[WidgetApi] Loading widgets from folder: ${folderPath}`);
11655
- const results = await ipcRenderer$d.invoke(
12028
+ const results = await ipcRenderer$e.invoke(
11656
12029
  "widget:load-folder",
11657
12030
  folderPath,
11658
12031
  );
@@ -11676,7 +12049,7 @@ const widgetApi$2 = {
11676
12049
  uninstall: async (widgetName) => {
11677
12050
  try {
11678
12051
  console.log(`[WidgetApi] Uninstalling widget: ${widgetName}`);
11679
- const success = await ipcRenderer$d.invoke("widget:uninstall", widgetName);
12052
+ const success = await ipcRenderer$e.invoke("widget:uninstall", widgetName);
11680
12053
  if (success) {
11681
12054
  console.log(`[WidgetApi] ✓ Widget ${widgetName} uninstalled`);
11682
12055
  } else {
@@ -11699,7 +12072,7 @@ const widgetApi$2 = {
11699
12072
  */
11700
12073
  getCachePath: async () => {
11701
12074
  try {
11702
- return await ipcRenderer$d.invoke("widget:cache-path");
12075
+ return await ipcRenderer$e.invoke("widget:cache-path");
11703
12076
  } catch (error) {
11704
12077
  console.error("[WidgetApi] Error getting cache path:", error);
11705
12078
  throw error;
@@ -11713,7 +12086,7 @@ const widgetApi$2 = {
11713
12086
  */
11714
12087
  getStoragePath: async () => {
11715
12088
  try {
11716
- return await ipcRenderer$d.invoke("widget:storage-path");
12089
+ return await ipcRenderer$e.invoke("widget:storage-path");
11717
12090
  } catch (error) {
11718
12091
  console.error("[WidgetApi] Error getting storage path:", error);
11719
12092
  throw error;
@@ -11730,7 +12103,7 @@ const widgetApi$2 = {
11730
12103
  setStoragePath: async (customPath) => {
11731
12104
  try {
11732
12105
  console.log(`[WidgetApi] Setting storage path to: ${customPath}`);
11733
- const result = await ipcRenderer$d.invoke(
12106
+ const result = await ipcRenderer$e.invoke(
11734
12107
  "widget:set-storage-path",
11735
12108
  customPath,
11736
12109
  );
@@ -11752,7 +12125,7 @@ const widgetApi$2 = {
11752
12125
  */
11753
12126
  getComponentConfigs: async () => {
11754
12127
  try {
11755
- return await ipcRenderer$d.invoke("widget:get-component-configs");
12128
+ return await ipcRenderer$e.invoke("widget:get-component-configs");
11756
12129
  } catch (error) {
11757
12130
  console.error("[WidgetApi] Error getting component configs:", error);
11758
12131
  return [];
@@ -11767,7 +12140,7 @@ const widgetApi$2 = {
11767
12140
  */
11768
12141
  readBundle: async (widgetName) => {
11769
12142
  try {
11770
- return await ipcRenderer$d.invoke("widget:read-bundle", widgetName);
12143
+ return await ipcRenderer$e.invoke("widget:read-bundle", widgetName);
11771
12144
  } catch (error) {
11772
12145
  console.error(
11773
12146
  `[WidgetApi] Error reading bundle for ${widgetName}:`,
@@ -11784,7 +12157,7 @@ const widgetApi$2 = {
11784
12157
  */
11785
12158
  readAllBundles: async () => {
11786
12159
  try {
11787
- return await ipcRenderer$d.invoke("widget:read-all-bundles");
12160
+ return await ipcRenderer$e.invoke("widget:read-all-bundles");
11788
12161
  } catch (error) {
11789
12162
  console.error("[WidgetApi] Error reading all bundles:", error);
11790
12163
  return [];
@@ -11804,7 +12177,7 @@ const widgetApi$2 = {
11804
12177
  * });
11805
12178
  */
11806
12179
  onInstalled: (callback) => {
11807
- ipcRenderer$d.on("widget:installed", (event, data) => {
12180
+ ipcRenderer$e.on("widget:installed", (event, data) => {
11808
12181
  callback(data);
11809
12182
  });
11810
12183
  },
@@ -11822,7 +12195,7 @@ const widgetApi$2 = {
11822
12195
  * });
11823
12196
  */
11824
12197
  onLoaded: (callback) => {
11825
- ipcRenderer$d.on("widgets:loaded", (event, data) => {
12198
+ ipcRenderer$e.on("widgets:loaded", (event, data) => {
11826
12199
  callback(data);
11827
12200
  });
11828
12201
  },
@@ -11833,7 +12206,7 @@ const widgetApi$2 = {
11833
12206
  * @param {Function} callback - The callback to remove
11834
12207
  */
11835
12208
  removeInstalledListener: (callback) => {
11836
- ipcRenderer$d.removeListener("widget:installed", callback);
12209
+ ipcRenderer$e.removeListener("widget:installed", callback);
11837
12210
  },
11838
12211
 
11839
12212
  /**
@@ -11842,7 +12215,7 @@ const widgetApi$2 = {
11842
12215
  * @param {Function} callback - The callback to remove
11843
12216
  */
11844
12217
  removeLoadedListener: (callback) => {
11845
- ipcRenderer$d.removeListener("widgets:loaded", callback);
12218
+ ipcRenderer$e.removeListener("widgets:loaded", callback);
11846
12219
  },
11847
12220
  };
11848
12221
 
@@ -11855,7 +12228,7 @@ var widgetApi_1 = widgetApi$2;
11855
12228
  * Communicates with main process via IPC to handle encryption and file storage
11856
12229
  */
11857
12230
 
11858
- const { ipcRenderer: ipcRenderer$c } = require$$0$1;
12231
+ const { ipcRenderer: ipcRenderer$d } = require$$0$1;
11859
12232
  const {
11860
12233
  PROVIDER_SAVE,
11861
12234
  PROVIDER_LIST,
@@ -11887,7 +12260,7 @@ const providerApi$2 = {
11887
12260
  mcpConfig = null,
11888
12261
  allowedTools = null,
11889
12262
  ) =>
11890
- ipcRenderer$c.invoke(PROVIDER_SAVE, {
12263
+ ipcRenderer$d.invoke(PROVIDER_SAVE, {
11891
12264
  appId,
11892
12265
  providerName,
11893
12266
  providerType,
@@ -11905,7 +12278,7 @@ const providerApi$2 = {
11905
12278
  * @param {String} appId - the appId specified in the dash initialization
11906
12279
  * @returns {Promise<Array>} Array of provider objects with name, type, credentials
11907
12280
  */
11908
- listProviders: (appId) => ipcRenderer$c.invoke(PROVIDER_LIST, { appId }),
12281
+ listProviders: (appId) => ipcRenderer$d.invoke(PROVIDER_LIST, { appId }),
11909
12282
 
11910
12283
  /**
11911
12284
  * getProvider
@@ -11917,7 +12290,7 @@ const providerApi$2 = {
11917
12290
  * @returns {Promise<Object>} Provider object with name, type, credentials
11918
12291
  */
11919
12292
  getProvider: (appId, providerName) =>
11920
- ipcRenderer$c.invoke(PROVIDER_GET, { appId, providerName }),
12293
+ ipcRenderer$d.invoke(PROVIDER_GET, { appId, providerName }),
11921
12294
 
11922
12295
  /**
11923
12296
  * deleteProvider
@@ -11929,7 +12302,7 @@ const providerApi$2 = {
11929
12302
  * @returns {Promise}
11930
12303
  */
11931
12304
  deleteProvider: (appId, providerName) =>
11932
- ipcRenderer$c.invoke(PROVIDER_DELETE, { appId, providerName }),
12305
+ ipcRenderer$d.invoke(PROVIDER_DELETE, { appId, providerName }),
11933
12306
 
11934
12307
  /**
11935
12308
  * listProvidersForApplication
@@ -11939,14 +12312,14 @@ const providerApi$2 = {
11939
12312
  * @param {String} appId - the appId specified in the dash initialization
11940
12313
  */
11941
12314
  listProvidersForApplication: (appId) => {
11942
- ipcRenderer$c
12315
+ ipcRenderer$d
11943
12316
  .invoke(PROVIDER_LIST, { appId })
11944
12317
  .then((result) => {
11945
12318
  // Emit the event for ElectronDashboardApi to listen to
11946
- ipcRenderer$c.send("PROVIDER_LIST_COMPLETE", result);
12319
+ ipcRenderer$d.send("PROVIDER_LIST_COMPLETE", result);
11947
12320
  })
11948
12321
  .catch((error) => {
11949
- ipcRenderer$c.send("PROVIDER_LIST_ERROR", {
12322
+ ipcRenderer$d.send("PROVIDER_LIST_ERROR", {
11950
12323
  error: error.message,
11951
12324
  });
11952
12325
  });
@@ -11963,7 +12336,7 @@ const providerApi$2 = {
11963
12336
  providerType,
11964
12337
  credentials,
11965
12338
  ) => {
11966
- ipcRenderer$c
12339
+ ipcRenderer$d
11967
12340
  .invoke(PROVIDER_SAVE, {
11968
12341
  appId,
11969
12342
  providerName,
@@ -11971,10 +12344,10 @@ const providerApi$2 = {
11971
12344
  credentials,
11972
12345
  })
11973
12346
  .then((result) => {
11974
- ipcRenderer$c.send("PROVIDER_SAVE_COMPLETE", result);
12347
+ ipcRenderer$d.send("PROVIDER_SAVE_COMPLETE", result);
11975
12348
  })
11976
12349
  .catch((error) => {
11977
- ipcRenderer$c.send("PROVIDER_SAVE_ERROR", {
12350
+ ipcRenderer$d.send("PROVIDER_SAVE_ERROR", {
11978
12351
  error: error.message,
11979
12352
  });
11980
12353
  });
@@ -11986,13 +12359,13 @@ const providerApi$2 = {
11986
12359
  * Event-listener-based version for use with ElectronDashboardApi
11987
12360
  */
11988
12361
  getProviderForApplication: (appId, providerName) => {
11989
- ipcRenderer$c
12362
+ ipcRenderer$d
11990
12363
  .invoke(PROVIDER_GET, { appId, providerName })
11991
12364
  .then((result) => {
11992
- ipcRenderer$c.send("PROVIDER_GET_COMPLETE", result);
12365
+ ipcRenderer$d.send("PROVIDER_GET_COMPLETE", result);
11993
12366
  })
11994
12367
  .catch((error) => {
11995
- ipcRenderer$c.send("PROVIDER_GET_ERROR", {
12368
+ ipcRenderer$d.send("PROVIDER_GET_ERROR", {
11996
12369
  error: error.message,
11997
12370
  });
11998
12371
  });
@@ -12004,13 +12377,13 @@ const providerApi$2 = {
12004
12377
  * Event-listener-based version for use with ElectronDashboardApi
12005
12378
  */
12006
12379
  deleteProviderForApplication: (appId, providerName) => {
12007
- ipcRenderer$c
12380
+ ipcRenderer$d
12008
12381
  .invoke(PROVIDER_DELETE, { appId, providerName })
12009
12382
  .then((result) => {
12010
- ipcRenderer$c.send("PROVIDER_DELETE_COMPLETE", result);
12383
+ ipcRenderer$d.send("PROVIDER_DELETE_COMPLETE", result);
12011
12384
  })
12012
12385
  .catch((error) => {
12013
- ipcRenderer$c.send("PROVIDER_DELETE_ERROR", {
12386
+ ipcRenderer$d.send("PROVIDER_DELETE_ERROR", {
12014
12387
  error: error.message,
12015
12388
  });
12016
12389
  });
@@ -12026,7 +12399,7 @@ var providerApi_1 = providerApi$2;
12026
12399
  * Communicates with main process via IPC to manage MCP server lifecycle.
12027
12400
  */
12028
12401
 
12029
- const { ipcRenderer: ipcRenderer$b } = require$$0$1;
12402
+ const { ipcRenderer: ipcRenderer$c } = require$$0$1;
12030
12403
  const {
12031
12404
  MCP_START_SERVER,
12032
12405
  MCP_STOP_SERVER,
@@ -12050,7 +12423,7 @@ const mcpApi$2 = {
12050
12423
  * @returns {Promise<{ success, serverName, tools, status } | { error, message }>}
12051
12424
  */
12052
12425
  startServer: (serverName, mcpConfig, credentials) =>
12053
- ipcRenderer$b.invoke(MCP_START_SERVER, {
12426
+ ipcRenderer$c.invoke(MCP_START_SERVER, {
12054
12427
  serverName,
12055
12428
  mcpConfig,
12056
12429
  credentials,
@@ -12064,7 +12437,7 @@ const mcpApi$2 = {
12064
12437
  * @returns {Promise<{ success, serverName } | { error, message }>}
12065
12438
  */
12066
12439
  stopServer: (serverName) =>
12067
- ipcRenderer$b.invoke(MCP_STOP_SERVER, { serverName }),
12440
+ ipcRenderer$c.invoke(MCP_STOP_SERVER, { serverName }),
12068
12441
 
12069
12442
  /**
12070
12443
  * listTools
@@ -12073,7 +12446,7 @@ const mcpApi$2 = {
12073
12446
  * @param {string} serverName the server name
12074
12447
  * @returns {Promise<{ tools } | { error, message }>}
12075
12448
  */
12076
- listTools: (serverName) => ipcRenderer$b.invoke(MCP_LIST_TOOLS, { serverName }),
12449
+ listTools: (serverName) => ipcRenderer$c.invoke(MCP_LIST_TOOLS, { serverName }),
12077
12450
 
12078
12451
  /**
12079
12452
  * callTool
@@ -12086,7 +12459,7 @@ const mcpApi$2 = {
12086
12459
  * @returns {Promise<{ result } | { error, message }>}
12087
12460
  */
12088
12461
  callTool: (serverName, toolName, args, allowedTools = null) =>
12089
- ipcRenderer$b.invoke(MCP_CALL_TOOL, {
12462
+ ipcRenderer$c.invoke(MCP_CALL_TOOL, {
12090
12463
  serverName,
12091
12464
  toolName,
12092
12465
  args,
@@ -12101,7 +12474,7 @@ const mcpApi$2 = {
12101
12474
  * @returns {Promise<{ resources } | { error, message }>}
12102
12475
  */
12103
12476
  listResources: (serverName) =>
12104
- ipcRenderer$b.invoke(MCP_LIST_RESOURCES, { serverName }),
12477
+ ipcRenderer$c.invoke(MCP_LIST_RESOURCES, { serverName }),
12105
12478
 
12106
12479
  /**
12107
12480
  * readResource
@@ -12112,7 +12485,7 @@ const mcpApi$2 = {
12112
12485
  * @returns {Promise<{ resource } | { error, message }>}
12113
12486
  */
12114
12487
  readResource: (serverName, uri) =>
12115
- ipcRenderer$b.invoke(MCP_READ_RESOURCE, { serverName, uri }),
12488
+ ipcRenderer$c.invoke(MCP_READ_RESOURCE, { serverName, uri }),
12116
12489
 
12117
12490
  /**
12118
12491
  * getServerStatus
@@ -12122,7 +12495,7 @@ const mcpApi$2 = {
12122
12495
  * @returns {Promise<{ status, tools, error }>}
12123
12496
  */
12124
12497
  getServerStatus: (serverName) =>
12125
- ipcRenderer$b.invoke(MCP_SERVER_STATUS, { serverName }),
12498
+ ipcRenderer$c.invoke(MCP_SERVER_STATUS, { serverName }),
12126
12499
 
12127
12500
  /**
12128
12501
  * getCatalog
@@ -12130,7 +12503,7 @@ const mcpApi$2 = {
12130
12503
  *
12131
12504
  * @returns {Promise<{ catalog } | { error, message }>}
12132
12505
  */
12133
- getCatalog: () => ipcRenderer$b.invoke(MCP_GET_CATALOG),
12506
+ getCatalog: () => ipcRenderer$c.invoke(MCP_GET_CATALOG),
12134
12507
 
12135
12508
  /**
12136
12509
  * runAuth
@@ -12142,7 +12515,7 @@ const mcpApi$2 = {
12142
12515
  * @returns {Promise<{ success } | { error, message }>}
12143
12516
  */
12144
12517
  runAuth: (mcpConfig, credentials, authCommand) =>
12145
- ipcRenderer$b.invoke(MCP_RUN_AUTH, { mcpConfig, credentials, authCommand }),
12518
+ ipcRenderer$c.invoke(MCP_RUN_AUTH, { mcpConfig, credentials, authCommand }),
12146
12519
  };
12147
12520
 
12148
12521
  var mcpApi_1 = mcpApi$2;
@@ -12160,7 +12533,7 @@ var mcpApi_1 = mcpApi$2;
12160
12533
  * mainApi.registry.checkUpdates([{ name: "weather-widgets", version: "1.0.0" }])
12161
12534
  */
12162
12535
 
12163
- const { ipcRenderer: ipcRenderer$a } = require$$0$1;
12536
+ const { ipcRenderer: ipcRenderer$b } = require$$0$1;
12164
12537
 
12165
12538
  const registryApi$2 = {
12166
12539
  /**
@@ -12170,7 +12543,7 @@ const registryApi$2 = {
12170
12543
  */
12171
12544
  fetchIndex: async (forceRefresh = false) => {
12172
12545
  try {
12173
- return await ipcRenderer$a.invoke("registry:fetch-index", forceRefresh);
12546
+ return await ipcRenderer$b.invoke("registry:fetch-index", forceRefresh);
12174
12547
  } catch (error) {
12175
12548
  console.error("[RegistryApi] Error fetching index:", error);
12176
12549
  throw error;
@@ -12185,7 +12558,7 @@ const registryApi$2 = {
12185
12558
  */
12186
12559
  search: async (query = "", filters = {}) => {
12187
12560
  try {
12188
- return await ipcRenderer$a.invoke("registry:search", query, filters);
12561
+ return await ipcRenderer$b.invoke("registry:search", query, filters);
12189
12562
  } catch (error) {
12190
12563
  console.error("[RegistryApi] Error searching registry:", error);
12191
12564
  throw error;
@@ -12199,7 +12572,7 @@ const registryApi$2 = {
12199
12572
  */
12200
12573
  getPackage: async (packageName) => {
12201
12574
  try {
12202
- return await ipcRenderer$a.invoke("registry:get-package", packageName);
12575
+ return await ipcRenderer$b.invoke("registry:get-package", packageName);
12203
12576
  } catch (error) {
12204
12577
  console.error(
12205
12578
  `[RegistryApi] Error getting package ${packageName}:`,
@@ -12216,7 +12589,7 @@ const registryApi$2 = {
12216
12589
  */
12217
12590
  checkUpdates: async (installedWidgets = []) => {
12218
12591
  try {
12219
- return await ipcRenderer$a.invoke(
12592
+ return await ipcRenderer$b.invoke(
12220
12593
  "registry:check-updates",
12221
12594
  installedWidgets,
12222
12595
  );
@@ -12234,7 +12607,7 @@ const registryApi$2 = {
12234
12607
  */
12235
12608
  searchDashboards: async (query = "", filters = {}) => {
12236
12609
  try {
12237
- return await ipcRenderer$a.invoke(
12610
+ return await ipcRenderer$b.invoke(
12238
12611
  "registry:search-dashboards",
12239
12612
  query,
12240
12613
  filters,
@@ -12254,17 +12627,17 @@ var registryApi_1 = registryApi$2;
12254
12627
  * Handle the theme configuration file
12255
12628
  */
12256
12629
 
12257
- const { ipcRenderer: ipcRenderer$9 } = require$$0$1;
12630
+ const { ipcRenderer: ipcRenderer$a } = require$$0$1;
12258
12631
 
12259
12632
  const { THEME_LIST, THEME_SAVE, THEME_DELETE } = events$8;
12260
12633
 
12261
12634
  const themeApi$2 = {
12262
12635
  listThemesForApplication: (appId) =>
12263
- ipcRenderer$9.invoke(THEME_LIST, { appId }),
12636
+ ipcRenderer$a.invoke(THEME_LIST, { appId }),
12264
12637
  saveThemeForApplication: (appId, themeName, themeObject) =>
12265
- ipcRenderer$9.invoke(THEME_SAVE, { appId, themeName, themeObject }),
12638
+ ipcRenderer$a.invoke(THEME_SAVE, { appId, themeName, themeObject }),
12266
12639
  deleteThemeForApplication: (appId, themeKey) =>
12267
- ipcRenderer$9.invoke(THEME_DELETE, { appId, themeKey }),
12640
+ ipcRenderer$a.invoke(THEME_DELETE, { appId, themeKey }),
12268
12641
  };
12269
12642
 
12270
12643
  var themeApi_1 = themeApi$2;
@@ -12276,7 +12649,7 @@ var themeApi_1 = themeApi$2;
12276
12649
  */
12277
12650
 
12278
12651
  // ipcRenderer that must be used to invoke the events
12279
- const { ipcRenderer: ipcRenderer$8 } = require$$0$1;
12652
+ const { ipcRenderer: ipcRenderer$9 } = require$$0$1;
12280
12653
 
12281
12654
  const {
12282
12655
  ALGOLIA_LIST_INDICES,
@@ -12290,10 +12663,10 @@ const {
12290
12663
 
12291
12664
  const algoliaApi$2 = {
12292
12665
  listIndices: (application) =>
12293
- ipcRenderer$8.invoke(ALGOLIA_LIST_INDICES, application),
12666
+ ipcRenderer$9.invoke(ALGOLIA_LIST_INDICES, application),
12294
12667
 
12295
12668
  browseObjects: (appId, apiKey, indexName) => {
12296
- ipcRenderer$8.invoke(ALGOLIA_BROWSE_OBJECTS, {
12669
+ ipcRenderer$9.invoke(ALGOLIA_BROWSE_OBJECTS, {
12297
12670
  appId,
12298
12671
  apiKey,
12299
12672
  indexName,
@@ -12301,10 +12674,10 @@ const algoliaApi$2 = {
12301
12674
  });
12302
12675
  },
12303
12676
 
12304
- saveSynonyms: () => ipcRenderer$8.invoke(ALGOLIA_SAVE_SYNONYMS, {}),
12677
+ saveSynonyms: () => ipcRenderer$9.invoke(ALGOLIA_SAVE_SYNONYMS, {}),
12305
12678
 
12306
12679
  getAnalyticsForQuery: (application, indexName, query) =>
12307
- ipcRenderer$8.invoke(ALGOLIA_ANALYTICS_FOR_QUERY, {
12680
+ ipcRenderer$9.invoke(ALGOLIA_ANALYTICS_FOR_QUERY, {
12308
12681
  application,
12309
12682
  indexName,
12310
12683
  query,
@@ -12317,7 +12690,7 @@ const algoliaApi$2 = {
12317
12690
  dir,
12318
12691
  createIfNotExists = false,
12319
12692
  ) =>
12320
- ipcRenderer$8.invoke(ALGOLIA_PARTIAL_UPDATE_OBJECTS, {
12693
+ ipcRenderer$9.invoke(ALGOLIA_PARTIAL_UPDATE_OBJECTS, {
12321
12694
  appId,
12322
12695
  apiKey,
12323
12696
  indexName,
@@ -12326,7 +12699,7 @@ const algoliaApi$2 = {
12326
12699
  }),
12327
12700
 
12328
12701
  createBatchesFromFile: (filepath, batchFilepath, batchSize) => {
12329
- ipcRenderer$8.invoke(ALGOLIA_CREATE_BATCH, {
12702
+ ipcRenderer$9.invoke(ALGOLIA_CREATE_BATCH, {
12330
12703
  filepath,
12331
12704
  batchFilepath,
12332
12705
  batchSize,
@@ -12334,7 +12707,7 @@ const algoliaApi$2 = {
12334
12707
  },
12335
12708
 
12336
12709
  browseObjectsToFile: (appId, apiKey, indexName, toFilename, query = "") => {
12337
- ipcRenderer$8.invoke(ALGOLIA_BROWSE_OBJECTS, {
12710
+ ipcRenderer$9.invoke(ALGOLIA_BROWSE_OBJECTS, {
12338
12711
  appId,
12339
12712
  apiKey,
12340
12713
  indexName,
@@ -12344,7 +12717,7 @@ const algoliaApi$2 = {
12344
12717
  },
12345
12718
 
12346
12719
  search: (appId, apiKey, indexName, query = "", options = {}) =>
12347
- ipcRenderer$8.invoke(ALGOLIA_SEARCH, {
12720
+ ipcRenderer$9.invoke(ALGOLIA_SEARCH, {
12348
12721
  appId,
12349
12722
  apiKey,
12350
12723
  indexName,
@@ -12359,14 +12732,14 @@ var algoliaApi_1 = algoliaApi$2;
12359
12732
  * openAI
12360
12733
  */
12361
12734
 
12362
- const { ipcRenderer: ipcRenderer$7 } = require$$0$1;
12735
+ const { ipcRenderer: ipcRenderer$8 } = require$$0$1;
12363
12736
 
12364
12737
  const { OPENAI_DESCRIBE_IMAGE } = openaiEvents$1;
12365
12738
 
12366
12739
  const openaiApi$2 = {
12367
12740
  // convert a json array of objects to a csv string and save to file
12368
12741
  describeImage: (imageUrl, apiKey, prompt = "What's in this image?") =>
12369
- ipcRenderer$7.invoke(OPENAI_DESCRIBE_IMAGE, { imageUrl, apiKey, prompt }),
12742
+ ipcRenderer$8.invoke(OPENAI_DESCRIBE_IMAGE, { imageUrl, apiKey, prompt }),
12370
12743
  };
12371
12744
 
12372
12745
  var openaiApi_1 = openaiApi$2;
@@ -12377,14 +12750,14 @@ var openaiApi_1 = openaiApi$2;
12377
12750
  */
12378
12751
 
12379
12752
  // ipcRenderer that must be used to invoke the events
12380
- const { ipcRenderer: ipcRenderer$6 } = require$$0$1;
12753
+ const { ipcRenderer: ipcRenderer$7 } = require$$0$1;
12381
12754
 
12382
12755
  const { MENU_ITEMS_SAVE, MENU_ITEMS_LIST } = events$8;
12383
12756
 
12384
12757
  const menuItemsApi$2 = {
12385
12758
  saveMenuItem: (appId, menuItem) =>
12386
- ipcRenderer$6.invoke(MENU_ITEMS_SAVE, { appId, menuItem }),
12387
- listMenuItems: (appId) => ipcRenderer$6.invoke(MENU_ITEMS_LIST, { appId }),
12759
+ ipcRenderer$7.invoke(MENU_ITEMS_SAVE, { appId, menuItem }),
12760
+ listMenuItems: (appId) => ipcRenderer$7.invoke(MENU_ITEMS_LIST, { appId }),
12388
12761
  };
12389
12762
 
12390
12763
  var menuItemsApi_1 = menuItemsApi$2;
@@ -12396,12 +12769,12 @@ var menuItemsApi_1 = menuItemsApi$2;
12396
12769
  */
12397
12770
 
12398
12771
  // ipcRenderer that must be used to invoke the events
12399
- const { ipcRenderer: ipcRenderer$5 } = require$$0$1;
12772
+ const { ipcRenderer: ipcRenderer$6 } = require$$0$1;
12400
12773
 
12401
12774
  const pluginApi$2 = {
12402
12775
  install: (packageName, filepath) =>
12403
- ipcRenderer$5.invoke("plugin-install", { packageName, filepath }),
12404
- uninstall: (filepath) => ipcRenderer$5.invoke("plugin-uninstall", filepath),
12776
+ ipcRenderer$6.invoke("plugin-install", { packageName, filepath }),
12777
+ uninstall: (filepath) => ipcRenderer$6.invoke("plugin-uninstall", filepath),
12405
12778
  };
12406
12779
 
12407
12780
  var pluginApi_1 = pluginApi$2;
@@ -12414,7 +12787,7 @@ var pluginApi_1 = pluginApi$2;
12414
12787
  * tool-use events, and request cancellation.
12415
12788
  */
12416
12789
 
12417
- const { ipcRenderer: ipcRenderer$4 } = require$$0$1;
12790
+ const { ipcRenderer: ipcRenderer$5 } = require$$0$1;
12418
12791
  const {
12419
12792
  LLM_SEND_MESSAGE,
12420
12793
  LLM_ABORT_REQUEST,
@@ -12436,7 +12809,7 @@ const _listenerMap = new Map();
12436
12809
  function _addListener(channel, callback) {
12437
12810
  const id = String(++_nextListenerId);
12438
12811
  const wrapped = (_event, data) => callback(data);
12439
- ipcRenderer$4.on(channel, wrapped);
12812
+ ipcRenderer$5.on(channel, wrapped);
12440
12813
  _listenerMap.set(id, { channel, wrapped });
12441
12814
  return id;
12442
12815
  }
@@ -12451,7 +12824,7 @@ const llmApi$2 = {
12451
12824
  * @returns {Promise<void>}
12452
12825
  */
12453
12826
  sendMessage: (requestId, params) =>
12454
- ipcRenderer$4.invoke(LLM_SEND_MESSAGE, { requestId, ...params }),
12827
+ ipcRenderer$5.invoke(LLM_SEND_MESSAGE, { requestId, ...params }),
12455
12828
 
12456
12829
  /**
12457
12830
  * abortRequest
@@ -12461,7 +12834,7 @@ const llmApi$2 = {
12461
12834
  * @returns {Promise<{ success: boolean }>}
12462
12835
  */
12463
12836
  abortRequest: (requestId) =>
12464
- ipcRenderer$4.invoke(LLM_ABORT_REQUEST, { requestId }),
12837
+ ipcRenderer$5.invoke(LLM_ABORT_REQUEST, { requestId }),
12465
12838
 
12466
12839
  /**
12467
12840
  * listConnectedTools
@@ -12469,7 +12842,7 @@ const llmApi$2 = {
12469
12842
  *
12470
12843
  * @returns {Promise<Array<{ serverName, tools, resources, status }>>}
12471
12844
  */
12472
- listConnectedTools: () => ipcRenderer$4.invoke(LLM_LIST_CONNECTED_TOOLS),
12845
+ listConnectedTools: () => ipcRenderer$5.invoke(LLM_LIST_CONNECTED_TOOLS),
12473
12846
 
12474
12847
  /**
12475
12848
  * checkCliAvailable
@@ -12477,7 +12850,7 @@ const llmApi$2 = {
12477
12850
  *
12478
12851
  * @returns {Promise<{ available: boolean, path?: string }>}
12479
12852
  */
12480
- checkCliAvailable: () => ipcRenderer$4.invoke(LLM_CHECK_CLI_AVAILABLE),
12853
+ checkCliAvailable: () => ipcRenderer$5.invoke(LLM_CHECK_CLI_AVAILABLE),
12481
12854
 
12482
12855
  /**
12483
12856
  * clearCliSession
@@ -12487,7 +12860,7 @@ const llmApi$2 = {
12487
12860
  * @returns {Promise<{ success: boolean }>}
12488
12861
  */
12489
12862
  clearCliSession: (widgetUuid) =>
12490
- ipcRenderer$4.invoke(LLM_CLEAR_CLI_SESSION, { widgetUuid }),
12863
+ ipcRenderer$5.invoke(LLM_CLEAR_CLI_SESSION, { widgetUuid }),
12491
12864
 
12492
12865
  /**
12493
12866
  * getCliSessionStatus
@@ -12497,7 +12870,7 @@ const llmApi$2 = {
12497
12870
  * @returns {Promise<{ hasSession: boolean, sessionId?: string, isProcessActive: boolean }>}
12498
12871
  */
12499
12872
  getCliSessionStatus: (widgetUuid) =>
12500
- ipcRenderer$4.invoke(LLM_CLI_SESSION_STATUS, { widgetUuid }),
12873
+ ipcRenderer$5.invoke(LLM_CLI_SESSION_STATUS, { widgetUuid }),
12501
12874
 
12502
12875
  /**
12503
12876
  * endCliSession
@@ -12507,7 +12880,7 @@ const llmApi$2 = {
12507
12880
  * @returns {Promise<{ success: boolean }>}
12508
12881
  */
12509
12882
  endCliSession: (widgetUuid) =>
12510
- ipcRenderer$4.invoke(LLM_CLI_END_SESSION, { widgetUuid }),
12883
+ ipcRenderer$5.invoke(LLM_CLI_END_SESSION, { widgetUuid }),
12511
12884
 
12512
12885
  // --- Stream event listeners ---
12513
12886
  // Each on* method returns an opaque string ID. Strings cross the
@@ -12541,7 +12914,7 @@ const llmApi$2 = {
12541
12914
  const listenerId = id !== undefined ? String(id) : String(idOrChannel);
12542
12915
  const entry = _listenerMap.get(listenerId);
12543
12916
  if (entry) {
12544
- ipcRenderer$4.removeListener(entry.channel, entry.wrapped);
12917
+ ipcRenderer$5.removeListener(entry.channel, entry.wrapped);
12545
12918
  _listenerMap.delete(listenerId);
12546
12919
  }
12547
12920
  },
@@ -12553,14 +12926,14 @@ const llmApi$2 = {
12553
12926
  */
12554
12927
  removeAllStreamListeners: () => {
12555
12928
  for (const [, entry] of _listenerMap) {
12556
- ipcRenderer$4.removeListener(entry.channel, entry.wrapped);
12929
+ ipcRenderer$5.removeListener(entry.channel, entry.wrapped);
12557
12930
  }
12558
12931
  _listenerMap.clear();
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);
12932
+ ipcRenderer$5.removeAllListeners(LLM_STREAM_DELTA);
12933
+ ipcRenderer$5.removeAllListeners(LLM_STREAM_TOOL_CALL);
12934
+ ipcRenderer$5.removeAllListeners(LLM_STREAM_TOOL_RESULT);
12935
+ ipcRenderer$5.removeAllListeners(LLM_STREAM_COMPLETE);
12936
+ ipcRenderer$5.removeAllListeners(LLM_STREAM_ERROR);
12564
12937
  },
12565
12938
  };
12566
12939
 
@@ -12574,7 +12947,7 @@ var llmApi_1 = llmApi$2;
12574
12947
  * and manage the response cache.
12575
12948
  */
12576
12949
 
12577
- const { ipcRenderer: ipcRenderer$3 } = require$$0$1;
12950
+ const { ipcRenderer: ipcRenderer$4 } = require$$0$1;
12578
12951
  const {
12579
12952
  CLIENT_CACHE_INVALIDATE,
12580
12953
  CLIENT_CACHE_INVALIDATE_ALL,
@@ -12591,28 +12964,28 @@ const clientCacheApi$2 = {
12591
12964
  * @returns {Promise<{success: boolean}>}
12592
12965
  */
12593
12966
  invalidate: (appId, providerName) =>
12594
- ipcRenderer$3.invoke(CLIENT_CACHE_INVALIDATE, { appId, providerName }),
12967
+ ipcRenderer$4.invoke(CLIENT_CACHE_INVALIDATE, { appId, providerName }),
12595
12968
 
12596
12969
  /**
12597
12970
  * Invalidate all cached clients.
12598
12971
  *
12599
12972
  * @returns {Promise<{success: boolean}>}
12600
12973
  */
12601
- invalidateAll: () => ipcRenderer$3.invoke(CLIENT_CACHE_INVALIDATE_ALL),
12974
+ invalidateAll: () => ipcRenderer$4.invoke(CLIENT_CACHE_INVALIDATE_ALL),
12602
12975
 
12603
12976
  /**
12604
12977
  * Clear the response cache.
12605
12978
  *
12606
12979
  * @returns {Promise<{success: boolean}>}
12607
12980
  */
12608
- clearResponseCache: () => ipcRenderer$3.invoke(RESPONSE_CACHE_CLEAR),
12981
+ clearResponseCache: () => ipcRenderer$4.invoke(RESPONSE_CACHE_CLEAR),
12609
12982
 
12610
12983
  /**
12611
12984
  * Get response cache statistics.
12612
12985
  *
12613
12986
  * @returns {Promise<{entries: number, inflight: number, keys: string[]}>}
12614
12987
  */
12615
- responseCacheStats: () => ipcRenderer$3.invoke(RESPONSE_CACHE_STATS),
12988
+ responseCacheStats: () => ipcRenderer$4.invoke(RESPONSE_CACHE_STATS),
12616
12989
  };
12617
12990
 
12618
12991
  var clientCacheApi_1 = clientCacheApi$2;
@@ -12624,7 +12997,7 @@ var clientCacheApi_1 = clientCacheApi$2;
12624
12997
  * Exposed via contextBridge through mainApi.
12625
12998
  */
12626
12999
 
12627
- const { ipcRenderer: ipcRenderer$2 } = require$$0$1;
13000
+ const { ipcRenderer: ipcRenderer$3 } = require$$0$1;
12628
13001
  const {
12629
13002
  DASHBOARD_CONFIG_EXPORT,
12630
13003
  DASHBOARD_CONFIG_IMPORT,
@@ -12646,7 +13019,7 @@ const dashboardConfigApi$2 = {
12646
13019
  * @returns {Promise<Object>} Result with success, filePath, and config
12647
13020
  */
12648
13021
  exportDashboardConfig: (appId, workspaceId, options = {}) =>
12649
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_EXPORT, {
13022
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_EXPORT, {
12650
13023
  appId,
12651
13024
  workspaceId,
12652
13025
  options,
@@ -12661,7 +13034,7 @@ const dashboardConfigApi$2 = {
12661
13034
  * @returns {Promise<Object>} Result with success, workspace, and summary
12662
13035
  */
12663
13036
  importDashboardConfig: (appId) =>
12664
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_IMPORT, { appId }),
13037
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_IMPORT, { appId }),
12665
13038
 
12666
13039
  /**
12667
13040
  * Install a dashboard from the registry by package name.
@@ -12673,7 +13046,7 @@ const dashboardConfigApi$2 = {
12673
13046
  * @returns {Promise<Object>} Result with success, workspace, and summary
12674
13047
  */
12675
13048
  installDashboardFromRegistry: (appId, packageName) =>
12676
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_INSTALL, {
13049
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_INSTALL, {
12677
13050
  appId,
12678
13051
  packageName,
12679
13052
  }),
@@ -12686,7 +13059,7 @@ const dashboardConfigApi$2 = {
12686
13059
  * @returns {Promise<Object>} Compatibility report with per-widget status
12687
13060
  */
12688
13061
  checkDashboardCompatibility: (appId, dashboardWidgets) =>
12689
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_COMPATIBILITY, {
13062
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_COMPATIBILITY, {
12690
13063
  appId,
12691
13064
  dashboardWidgets,
12692
13065
  }),
@@ -12702,7 +13075,7 @@ const dashboardConfigApi$2 = {
12702
13075
  * @returns {Promise<Object>} Result with success, manifest, filePath
12703
13076
  */
12704
13077
  prepareDashboardForPublish: (appId, workspaceId, options = {}) =>
12705
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_PUBLISH, {
13078
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_PUBLISH, {
12706
13079
  appId,
12707
13080
  workspaceId,
12708
13081
  options,
@@ -12716,7 +13089,7 @@ const dashboardConfigApi$2 = {
12716
13089
  * @returns {Promise<Object>} Preview with metadata, widgets, wiring, compatibility
12717
13090
  */
12718
13091
  getDashboardPreview: (packageName) =>
12719
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_PREVIEW, { packageName }),
13092
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_PREVIEW, { packageName }),
12720
13093
 
12721
13094
  /**
12722
13095
  * Check installed dashboards for available updates.
@@ -12725,7 +13098,7 @@ const dashboardConfigApi$2 = {
12725
13098
  * @returns {Promise<Object>} Result with updates array
12726
13099
  */
12727
13100
  checkDashboardUpdates: (appId) =>
12728
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_CHECK_UPDATES, { appId }),
13101
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_CHECK_UPDATES, { appId }),
12729
13102
 
12730
13103
  /**
12731
13104
  * Get provider setup manifest for a dashboard's requirements.
@@ -12735,7 +13108,7 @@ const dashboardConfigApi$2 = {
12735
13108
  * @returns {Promise<Object>} Setup manifest with per-provider status
12736
13109
  */
12737
13110
  getProviderSetupManifest: (appId, requiredProviders) =>
12738
- ipcRenderer$2.invoke(DASHBOARD_CONFIG_PROVIDER_SETUP, {
13111
+ ipcRenderer$3.invoke(DASHBOARD_CONFIG_PROVIDER_SETUP, {
12739
13112
  appId,
12740
13113
  requiredProviders,
12741
13114
  }),
@@ -12743,6 +13116,73 @@ const dashboardConfigApi$2 = {
12743
13116
 
12744
13117
  var dashboardConfigApi_1 = dashboardConfigApi$2;
12745
13118
 
13119
+ /**
13120
+ * registryAuthApi.js
13121
+ *
13122
+ * IPC bridge for registry authentication (renderer side).
13123
+ * Exposed via contextBridge through mainApi.
13124
+ */
13125
+
13126
+ const { ipcRenderer: ipcRenderer$2 } = require$$0$1;
13127
+ const {
13128
+ REGISTRY_AUTH_INITIATE_LOGIN,
13129
+ REGISTRY_AUTH_POLL_TOKEN,
13130
+ REGISTRY_AUTH_GET_STATUS,
13131
+ REGISTRY_AUTH_GET_PROFILE,
13132
+ REGISTRY_AUTH_LOGOUT,
13133
+ REGISTRY_AUTH_PUBLISH,
13134
+ } = events$8;
13135
+
13136
+ const registryAuthApi$2 = {
13137
+ /**
13138
+ * Initiate the device code flow for registry login.
13139
+ * Returns device code, user code, and verification URL.
13140
+ *
13141
+ * @returns {Promise<Object>} { deviceCode, userCode, verificationUrl, verificationUrlComplete, expiresIn, interval }
13142
+ */
13143
+ initiateLogin: () => ipcRenderer$2.invoke(REGISTRY_AUTH_INITIATE_LOGIN),
13144
+
13145
+ /**
13146
+ * Poll for token after user completes browser auth.
13147
+ *
13148
+ * @param {string} deviceCode - Device code from initiateLogin
13149
+ * @returns {Promise<Object>} { status: 'pending' | 'authorized' | 'expired', token?, userId? }
13150
+ */
13151
+ pollToken: (deviceCode) =>
13152
+ ipcRenderer$2.invoke(REGISTRY_AUTH_POLL_TOKEN, { deviceCode }),
13153
+
13154
+ /**
13155
+ * Get current auth status.
13156
+ *
13157
+ * @returns {Promise<Object>} { authenticated: boolean, userId?: string }
13158
+ */
13159
+ getStatus: () => ipcRenderer$2.invoke(REGISTRY_AUTH_GET_STATUS),
13160
+
13161
+ /**
13162
+ * Get the authenticated user's registry profile.
13163
+ *
13164
+ * @returns {Promise<Object|null>} User profile or null
13165
+ */
13166
+ getProfile: () => ipcRenderer$2.invoke(REGISTRY_AUTH_GET_PROFILE),
13167
+
13168
+ /**
13169
+ * Logout from registry.
13170
+ */
13171
+ logout: () => ipcRenderer$2.invoke(REGISTRY_AUTH_LOGOUT),
13172
+
13173
+ /**
13174
+ * Publish a ZIP to the registry.
13175
+ *
13176
+ * @param {string} zipPath - Path to the ZIP file
13177
+ * @param {Object} manifest - Package manifest
13178
+ * @returns {Promise<Object>} { success, registryUrl, packageId, version, error? }
13179
+ */
13180
+ publish: (zipPath, manifest) =>
13181
+ ipcRenderer$2.invoke(REGISTRY_AUTH_PUBLISH, { zipPath, manifest }),
13182
+ };
13183
+
13184
+ var registryAuthApi_1 = registryAuthApi$2;
13185
+
12746
13186
  /**
12747
13187
  * dashboardRatingsApi.js
12748
13188
  *
@@ -12810,6 +13250,7 @@ const llmApi$1 = llmApi_1;
12810
13250
  const clientCacheApi$1 = clientCacheApi_1;
12811
13251
  const dashboardConfigApi$1 = dashboardConfigApi_1;
12812
13252
  const dashboardRatingsApi = dashboardRatingsApi_1;
13253
+ const registryAuthApi$1 = registryAuthApi_1;
12813
13254
 
12814
13255
  // Events constants
12815
13256
  const events$1 = events$8;
@@ -12883,6 +13324,7 @@ function createMainApi$1(extensions = {}) {
12883
13324
  clientCache: clientCacheApi$1,
12884
13325
  dashboardConfig: dashboardConfigApi$1,
12885
13326
  dashboardRatings: dashboardRatingsApi,
13327
+ registryAuth: registryAuthApi$1,
12886
13328
 
12887
13329
  widgetEvent: {
12888
13330
  publish: (eventType, content) => {
@@ -12929,6 +13371,8 @@ const pluginController = pluginController_1;
12929
13371
  const llmController = llmController_1;
12930
13372
  const cliController = cliController_1;
12931
13373
  const dashboardConfigController = dashboardConfigController$1;
13374
+ const registryAuthController = registryAuthController$1;
13375
+ const registryApiController = registryApiController$1;
12932
13376
 
12933
13377
  // --- Utils ---
12934
13378
  const clientCache = requireClientCache();
@@ -12957,6 +13401,7 @@ const pluginApi = pluginApi_1;
12957
13401
  const llmApi = llmApi_1;
12958
13402
  const clientCacheApi = clientCacheApi_1;
12959
13403
  const dashboardConfigApi = dashboardConfigApi_1;
13404
+ const registryAuthApi = registryAuthApi_1;
12960
13405
 
12961
13406
  // --- Events ---
12962
13407
  const events = events$8;
@@ -12992,6 +13437,8 @@ var electron = {
12992
13437
  llmController,
12993
13438
  cliController,
12994
13439
  dashboardConfigController,
13440
+ registryAuthController,
13441
+ registryApiController,
12995
13442
 
12996
13443
  // Controller functions (flat) — spread for convenient destructuring
12997
13444
  ...controllers,
@@ -13015,6 +13462,7 @@ var electron = {
13015
13462
  llmApi,
13016
13463
  clientCacheApi,
13017
13464
  dashboardConfigApi,
13465
+ registryAuthApi,
13018
13466
 
13019
13467
  // Events
13020
13468
  events,