@trops/dash-core 0.1.174 → 0.1.176

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.
@@ -358,7 +358,7 @@ const PROVIDER_SAVE_COMPLETE = "provider-save-complete";
358
358
  const PROVIDER_SAVE_ERROR = "provider-save-error";
359
359
 
360
360
  const PROVIDER_LIST$1 = "provider-list";
361
- const PROVIDER_LIST_COMPLETE = "provider-list-complete";
361
+ const PROVIDER_LIST_COMPLETE$1 = "provider-list-complete";
362
362
  const PROVIDER_LIST_ERROR = "provider-list-error";
363
363
 
364
364
  const PROVIDER_GET$1 = "provider-get";
@@ -374,7 +374,7 @@ var providerEvents$1 = {
374
374
  PROVIDER_SAVE_COMPLETE,
375
375
  PROVIDER_SAVE_ERROR,
376
376
  PROVIDER_LIST: PROVIDER_LIST$1,
377
- PROVIDER_LIST_COMPLETE,
377
+ PROVIDER_LIST_COMPLETE: PROVIDER_LIST_COMPLETE$1,
378
378
  PROVIDER_LIST_ERROR,
379
379
  PROVIDER_GET: PROVIDER_GET$1,
380
380
  PROVIDER_GET_COMPLETE,
@@ -1215,7 +1215,7 @@ const { getFileContents: getFileContents$7 } = file;
1215
1215
  const configFilename$5 = "workspaces.json";
1216
1216
  const appName$7 = "Dashboard";
1217
1217
 
1218
- const workspaceController$2 = {
1218
+ const workspaceController$3 = {
1219
1219
  /**
1220
1220
  * createWorkspace
1221
1221
  *
@@ -1457,7 +1457,7 @@ const workspaceController$2 = {
1457
1457
  },
1458
1458
  };
1459
1459
 
1460
- var workspaceController_1 = workspaceController$2;
1460
+ var workspaceController_1 = workspaceController$3;
1461
1461
 
1462
1462
  const { app: app$9 } = require$$0$2;
1463
1463
  const path$f = require$$1$2;
@@ -1467,7 +1467,7 @@ const { getFileContents: getFileContents$6 } = file;
1467
1467
  const configFilename$4 = "themes.json";
1468
1468
  const appName$6 = "Dashboard";
1469
1469
 
1470
- const themeController$4 = {
1470
+ const themeController$5 = {
1471
1471
  /**
1472
1472
  * saveTheme
1473
1473
  * Create a new Theme that can be used in the application
@@ -1598,7 +1598,7 @@ const themeController$4 = {
1598
1598
  },
1599
1599
  };
1600
1600
 
1601
- var themeController_1 = themeController$4;
1601
+ var themeController_1 = themeController$5;
1602
1602
 
1603
1603
  /**
1604
1604
  * Utils/tranaform
@@ -4294,7 +4294,7 @@ function copyDirectory(source, destination) {
4294
4294
  }
4295
4295
  }
4296
4296
 
4297
- const settingsController$3 = {
4297
+ const settingsController$4 = {
4298
4298
  /**
4299
4299
  * saveSettingsForApplication
4300
4300
  * Save the settings object to a file (settings.json)
@@ -4526,7 +4526,7 @@ const settingsController$3 = {
4526
4526
  },
4527
4527
  };
4528
4528
 
4529
- var settingsController_1 = settingsController$3;
4529
+ var settingsController_1 = settingsController$4;
4530
4530
 
4531
4531
  /**
4532
4532
  * responseCache.js
@@ -31851,7 +31851,7 @@ const path$2 = require$$1$2;
31851
31851
  const { app: app$2, dialog: dialog$1 } = require$$0$2;
31852
31852
  const AdmZip$1 = require$$3$4;
31853
31853
 
31854
- const themeController$3 = themeController_1;
31854
+ const themeController$4 = themeController_1;
31855
31855
  const registryController$2 = registryController$3;
31856
31856
  const registryApiController$1 = registryApiController$2;
31857
31857
  const {
@@ -31958,7 +31958,7 @@ function extractColors(themeData) {
31958
31958
  async function prepareThemeForPublish$1(win, appId, themeKey, options = {}) {
31959
31959
  try {
31960
31960
  // Read the theme data
31961
- const themesResult = themeController$3.listThemesForApplication(win, appId);
31961
+ const themesResult = themeController$4.listThemesForApplication(win, appId);
31962
31962
  if (themesResult.error) {
31963
31963
  return {
31964
31964
  success: false,
@@ -32169,7 +32169,7 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
32169
32169
  const themeKey = pkg.displayName || pkg.name;
32170
32170
 
32171
32171
  // Save via themeController
32172
- const saveResult = themeController$3.saveThemeForApplication(
32172
+ const saveResult = themeController$4.saveThemeForApplication(
32173
32173
  win,
32174
32174
  appId,
32175
32175
  themeKey,
@@ -32206,7 +32206,7 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
32206
32206
  */
32207
32207
  function getThemePublishPreview$1(appId, themeKey) {
32208
32208
  try {
32209
- const themesResult = themeController$3.listThemesForApplication(null, appId);
32209
+ const themesResult = themeController$4.listThemesForApplication(null, appId);
32210
32210
  if (themesResult.error) {
32211
32211
  return {
32212
32212
  success: false,
@@ -32273,7 +32273,7 @@ const {
32273
32273
  applyEventWiringToLayout,
32274
32274
  } = dashboardConfigUtils$1;
32275
32275
  const { searchRegistry, getPackage } = registryController$3;
32276
- const themeController$2 = themeController_1;
32276
+ const themeController$3 = themeController_1;
32277
32277
 
32278
32278
  const configFilename = "workspaces.json";
32279
32279
  const appName$1 = "Dashboard";
@@ -32353,7 +32353,7 @@ async function exportDashboardConfig$1(
32353
32353
  // 4. Bundle theme if workspace has a themeKey
32354
32354
  if (workspace.themeKey) {
32355
32355
  try {
32356
- const themeResult = themeController$2.listThemesForApplication(
32356
+ const themeResult = themeController$3.listThemesForApplication(
32357
32357
  win,
32358
32358
  appId,
32359
32359
  );
@@ -32708,7 +32708,7 @@ async function processDashboardConfig(
32708
32708
  if (dashboardConfig.theme) {
32709
32709
  const bundledTheme = dashboardConfig.theme;
32710
32710
  try {
32711
- const themeResult = themeController$2.listThemesForApplication(win, appId);
32711
+ const themeResult = themeController$3.listThemesForApplication(win, appId);
32712
32712
  const existingThemes = themeResult.themes || {};
32713
32713
  const themeKey = bundledTheme.key;
32714
32714
 
@@ -32722,7 +32722,7 @@ async function processDashboardConfig(
32722
32722
  installedAt: new Date().toISOString(),
32723
32723
  };
32724
32724
  }
32725
- themeController$2.saveThemeForApplication(
32725
+ themeController$3.saveThemeForApplication(
32726
32726
  win,
32727
32727
  appId,
32728
32728
  themeKey,
@@ -33120,7 +33120,7 @@ async function prepareDashboardForPublish$1(
33120
33120
  // 4. Bundle theme if workspace has a themeKey
33121
33121
  if (workspace.themeKey) {
33122
33122
  try {
33123
- const themeResult = themeController$2.listThemesForApplication(
33123
+ const themeResult = themeController$3.listThemesForApplication(
33124
33124
  win,
33125
33125
  appId,
33126
33126
  );
@@ -66056,7 +66056,7 @@ const {
66056
66056
  StreamableHTTPServerTransport,
66057
66057
  } = streamableHttp;
66058
66058
 
66059
- const settingsController$2 = settingsController_1;
66059
+ const settingsController$3 = settingsController_1;
66060
66060
 
66061
66061
  // --- State ---
66062
66062
  let mcpServer = null;
@@ -66111,14 +66111,14 @@ const registeredResources = [];
66111
66111
  * Register a tool to be exposed via the MCP server.
66112
66112
  * Call this before starting the server (or restart after registering).
66113
66113
  */
66114
- function registerTool$3(toolDef) {
66114
+ function registerTool$4(toolDef) {
66115
66115
  registeredTools.push(toolDef);
66116
66116
  }
66117
66117
 
66118
66118
  /**
66119
66119
  * Register a resource to be exposed via the MCP server.
66120
66120
  */
66121
- function registerResource(resourceDef) {
66121
+ function registerResource$1(resourceDef) {
66122
66122
  registeredResources.push(resourceDef);
66123
66123
  }
66124
66124
 
@@ -66141,16 +66141,16 @@ function applyRegistrations(server) {
66141
66141
 
66142
66142
  // --- Settings Helpers ---
66143
66143
  function getMcpServerSettings(win) {
66144
- const result = settingsController$2.getSettingsForApplication(win);
66144
+ const result = settingsController$3.getSettingsForApplication(win);
66145
66145
  const settings = result?.settings || {};
66146
66146
  return settings.mcpDashServer || {};
66147
66147
  }
66148
66148
 
66149
66149
  function saveMcpServerSettings(win, mcpSettings) {
66150
- const result = settingsController$2.getSettingsForApplication(win);
66150
+ const result = settingsController$3.getSettingsForApplication(win);
66151
66151
  const settings = result?.settings || {};
66152
66152
  settings.mcpDashServer = mcpSettings;
66153
- settingsController$2.saveSettingsForApplication(win, settings);
66153
+ settingsController$3.saveSettingsForApplication(win, settings);
66154
66154
  }
66155
66155
 
66156
66156
  // --- App ID Resolution ---
@@ -66189,7 +66189,7 @@ function getServerContext() {
66189
66189
  }
66190
66190
 
66191
66191
  // --- Controller ---
66192
- const mcpDashServerController$3 = {
66192
+ const mcpDashServerController$4 = {
66193
66193
  /**
66194
66194
  * Start the MCP Dash server.
66195
66195
  * @param {BrowserWindow} win
@@ -66207,7 +66207,7 @@ const mcpDashServerController$3 = {
66207
66207
  const serverSettings = getMcpServerSettings(win);
66208
66208
  const port = options.port || serverSettings.port || 3141;
66209
66209
  const token =
66210
- serverSettings.token || mcpDashServerController$3.getOrCreateToken(win);
66210
+ serverSettings.token || mcpDashServerController$4.getOrCreateToken(win);
66211
66211
 
66212
66212
  // Create McpServer
66213
66213
  mcpServer = new McpServer({
@@ -66385,8 +66385,8 @@ const mcpDashServerController$3 = {
66385
66385
  * Restart the server (stop + start).
66386
66386
  */
66387
66387
  restartServer: async (win, options = {}) => {
66388
- await mcpDashServerController$3.stopServer(win);
66389
- return mcpDashServerController$3.startServer(win, options);
66388
+ await mcpDashServerController$4.stopServer(win);
66389
+ return mcpDashServerController$4.startServer(win, options);
66390
66390
  },
66391
66391
 
66392
66392
  /**
@@ -66426,7 +66426,7 @@ const mcpDashServerController$3 = {
66426
66426
  const serverSettings = getMcpServerSettings(win);
66427
66427
  if (serverSettings.enabled) {
66428
66428
  console.log("[mcpDashServer] Auto-starting server...");
66429
- return mcpDashServerController$3.startServer(win, {
66429
+ return mcpDashServerController$4.startServer(win, {
66430
66430
  port: serverSettings.port,
66431
66431
  });
66432
66432
  }
@@ -66434,12 +66434,12 @@ const mcpDashServerController$3 = {
66434
66434
  },
66435
66435
 
66436
66436
  // Expose registration functions for other controllers
66437
- registerTool: registerTool$3,
66438
- registerResource,
66437
+ registerTool: registerTool$4,
66438
+ registerResource: registerResource$1,
66439
66439
  getServerContext,
66440
66440
  };
66441
66441
 
66442
- var mcpDashServerController_1 = mcpDashServerController$3;
66442
+ var mcpDashServerController_1 = mcpDashServerController$4;
66443
66443
 
66444
66444
  /**
66445
66445
  * clientFactories.js
@@ -66872,7 +66872,7 @@ const {
66872
66872
  matchTailwindFamily,
66873
66873
  generateThemeFromPalette,
66874
66874
  } = paletteToThemeMapper_1;
66875
- const mcpDashServerController$2 = mcpDashServerController_1;
66875
+ const mcpDashServerController$3 = mcpDashServerController_1;
66876
66876
 
66877
66877
  var controller = {
66878
66878
  showDialog,
@@ -66955,7 +66955,7 @@ var controller = {
66955
66955
  assignRoles,
66956
66956
  matchTailwindFamily,
66957
66957
  generateThemeFromPalette,
66958
- mcpDashServerController: mcpDashServerController$2,
66958
+ mcpDashServerController: mcpDashServerController$3,
66959
66959
  };
66960
66960
 
66961
66961
  const { ipcRenderer: ipcRenderer$q } = require$$0$2;
@@ -69218,7 +69218,78 @@ const themeTools$1 = [
69218
69218
  },
69219
69219
  ];
69220
69220
 
69221
- var toolDefinitions = { dashboardTools: dashboardTools$1, widgetTools: widgetTools$1, themeTools: themeTools$1 };
69221
+ const providerTools$1 = [
69222
+ {
69223
+ name: "list_providers",
69224
+ description:
69225
+ "List all configured providers with their names, types, and status. Credential secrets are never returned.",
69226
+ inputSchema: {
69227
+ type: "object",
69228
+ properties: {},
69229
+ required: [],
69230
+ },
69231
+ },
69232
+ {
69233
+ name: "add_provider",
69234
+ description:
69235
+ "Add a new provider configuration. Supports credential providers (API keys) and MCP providers (server connections). Credentials are encrypted at rest.",
69236
+ inputSchema: {
69237
+ type: "object",
69238
+ properties: {
69239
+ name: {
69240
+ type: "string",
69241
+ description:
69242
+ "Unique display name for the provider (e.g. 'Algolia Production', 'Slack')",
69243
+ },
69244
+ type: {
69245
+ type: "string",
69246
+ description:
69247
+ "Provider type identifier (e.g. 'algolia', 'slack', 'openai', 'github')",
69248
+ },
69249
+ providerClass: {
69250
+ type: "string",
69251
+ enum: ["credential", "mcp"],
69252
+ description:
69253
+ "Provider class: 'credential' for API key providers, 'mcp' for MCP server providers. Defaults to 'credential'.",
69254
+ },
69255
+ credentials: {
69256
+ type: "object",
69257
+ description:
69258
+ "Credentials object (e.g. { apiKey: '...', appId: '...' }). Encrypted at rest, never returned in responses.",
69259
+ },
69260
+ mcpConfig: {
69261
+ type: "object",
69262
+ description:
69263
+ "MCP server configuration (transport, command, args, envMapping). Only used when providerClass is 'mcp'.",
69264
+ },
69265
+ allowedTools: {
69266
+ type: "array",
69267
+ items: { type: "string" },
69268
+ description:
69269
+ "Optional list of allowed MCP tool names. Only used when providerClass is 'mcp'.",
69270
+ },
69271
+ },
69272
+ required: ["name", "type", "credentials"],
69273
+ },
69274
+ },
69275
+ {
69276
+ name: "remove_provider",
69277
+ description:
69278
+ "Remove a provider by name. This deletes the provider and its stored credentials permanently.",
69279
+ inputSchema: {
69280
+ type: "object",
69281
+ properties: {
69282
+ name: {
69283
+ type: "string",
69284
+ description: "Name of the provider to remove",
69285
+ },
69286
+ },
69287
+ required: ["name"],
69288
+ },
69289
+ },
69290
+ ];
69291
+
69292
+ var toolDefinitions = { dashboardTools: dashboardTools$1, widgetTools: widgetTools$1, themeTools: themeTools$1, providerTools: providerTools$1 };
69222
69293
 
69223
69294
  /**
69224
69295
  * toolHandlers.js
@@ -69226,16 +69297,16 @@ var toolDefinitions = { dashboardTools: dashboardTools$1, widgetTools: widgetToo
69226
69297
  * MCP tool handlers for dashboard/workspace CRUD and app statistics.
69227
69298
  * Each handler delegates to existing controllers via getServerContext().
69228
69299
  */
69229
- const mcpDashServerController$1 = mcpDashServerController_1;
69230
- const workspaceController$1 = workspaceController_1;
69231
- const themeController$1 = themeController_1;
69232
- const providerController$1 = requireProviderController();
69300
+ const mcpDashServerController$2 = mcpDashServerController_1;
69301
+ const workspaceController$2 = workspaceController_1;
69302
+ const themeController$2 = themeController_1;
69303
+ const providerController$2 = requireProviderController();
69233
69304
 
69234
69305
  /**
69235
69306
  * Helper: get win + appId or throw a descriptive error.
69236
69307
  */
69237
- function requireContext() {
69238
- const ctx = mcpDashServerController$1.getServerContext();
69308
+ function requireContext$1() {
69309
+ const ctx = mcpDashServerController$2.getServerContext();
69239
69310
  if (!ctx) {
69240
69311
  throw new Error("MCP server is not running or has no active window");
69241
69312
  }
@@ -69246,7 +69317,7 @@ function requireContext() {
69246
69317
  * Helper: count widgets in a workspace's layout array.
69247
69318
  * Widgets are layout items whose component is registered and is not a container.
69248
69319
  */
69249
- function countWidgets(layout) {
69320
+ function countWidgets$1(layout) {
69250
69321
  if (!Array.isArray(layout)) return 0;
69251
69322
  return layout.filter(
69252
69323
  (item) =>
@@ -69261,8 +69332,8 @@ function countWidgets(layout) {
69261
69332
  * list_dashboards — Returns all workspaces with id, name, widget count, active state.
69262
69333
  */
69263
69334
  async function handleListDashboards$1() {
69264
- const { win, appId } = requireContext();
69265
- const result = workspaceController$1.listWorkspacesForApplication(win, appId);
69335
+ const { win, appId } = requireContext$1();
69336
+ const result = workspaceController$2.listWorkspacesForApplication(win, appId);
69266
69337
 
69267
69338
  if (result.error) {
69268
69339
  return {
@@ -69279,7 +69350,7 @@ async function handleListDashboards$1() {
69279
69350
  const dashboards = (result.workspaces || []).map((ws, index) => ({
69280
69351
  id: String(ws.id),
69281
69352
  name: ws.name || ws.label || `Dashboard ${index + 1}`,
69282
- widgetCount: countWidgets(ws.layout),
69353
+ widgetCount: countWidgets$1(ws.layout),
69283
69354
  isActive: index === 0,
69284
69355
  }));
69285
69356
 
@@ -69292,8 +69363,8 @@ async function handleListDashboards$1() {
69292
69363
  * get_dashboard — Returns full details for a dashboard by ID (or the active one).
69293
69364
  */
69294
69365
  async function handleGetDashboard$1({ dashboardId }) {
69295
- const { win, appId } = requireContext();
69296
- const result = workspaceController$1.listWorkspacesForApplication(win, appId);
69366
+ const { win, appId } = requireContext$1();
69367
+ const result = workspaceController$2.listWorkspacesForApplication(win, appId);
69297
69368
 
69298
69369
  if (result.error) {
69299
69370
  return {
@@ -69388,7 +69459,7 @@ async function handleCreateDashboard$1({ name }) {
69388
69459
  };
69389
69460
  }
69390
69461
 
69391
- const { win, appId } = requireContext();
69462
+ const { win, appId } = requireContext$1();
69392
69463
 
69393
69464
  const newWorkspace = {
69394
69465
  id: Date.now(),
@@ -69408,7 +69479,7 @@ async function handleCreateDashboard$1({ name }) {
69408
69479
  ],
69409
69480
  };
69410
69481
 
69411
- const result = workspaceController$1.saveWorkspaceForApplication(
69482
+ const result = workspaceController$2.saveWorkspaceForApplication(
69412
69483
  win,
69413
69484
  appId,
69414
69485
  newWorkspace,
@@ -69458,10 +69529,10 @@ async function handleDeleteDashboard$1({ dashboardId }) {
69458
69529
  };
69459
69530
  }
69460
69531
 
69461
- const { win, appId } = requireContext();
69532
+ const { win, appId } = requireContext$1();
69462
69533
 
69463
69534
  // Check how many dashboards exist
69464
- const listResult = workspaceController$1.listWorkspacesForApplication(
69535
+ const listResult = workspaceController$2.listWorkspacesForApplication(
69465
69536
  win,
69466
69537
  appId,
69467
69538
  );
@@ -69499,7 +69570,7 @@ async function handleDeleteDashboard$1({ dashboardId }) {
69499
69570
 
69500
69571
  // Use numeric ID if stored as number
69501
69572
  const targetWs = workspaces.find((ws) => String(ws.id) === dashboardId);
69502
- const result = workspaceController$1.deleteWorkspaceForApplication(
69573
+ const result = workspaceController$2.deleteWorkspaceForApplication(
69503
69574
  win,
69504
69575
  appId,
69505
69576
  targetWs.id,
@@ -69535,24 +69606,24 @@ async function handleDeleteDashboard$1({ dashboardId }) {
69535
69606
  * get_app_stats — Returns counts of dashboards, widgets, themes, and providers.
69536
69607
  */
69537
69608
  async function handleGetAppStats$1() {
69538
- const { win, appId } = requireContext();
69609
+ const { win, appId } = requireContext$1();
69539
69610
 
69540
69611
  // Dashboards + widget count
69541
- const wsResult = workspaceController$1.listWorkspacesForApplication(win, appId);
69612
+ const wsResult = workspaceController$2.listWorkspacesForApplication(win, appId);
69542
69613
  const workspaces = wsResult.workspaces || [];
69543
69614
  const dashboardCount = workspaces.length;
69544
69615
  const widgetCount = workspaces.reduce(
69545
- (sum, ws) => sum + countWidgets(ws.layout),
69616
+ (sum, ws) => sum + countWidgets$1(ws.layout),
69546
69617
  0,
69547
69618
  );
69548
69619
 
69549
69620
  // Themes
69550
- const themeResult = themeController$1.listThemesForApplication(win, appId);
69621
+ const themeResult = themeController$2.listThemesForApplication(win, appId);
69551
69622
  const themes = themeResult.themes || {};
69552
69623
  const themeCount = Object.keys(themes).length;
69553
69624
 
69554
69625
  // Providers
69555
- const providerResult = providerController$1.listProviders(win, appId);
69626
+ const providerResult = providerController$2.listProviders(win, appId);
69556
69627
  const providers = providerResult.providers || {};
69557
69628
  const providerCount = Object.keys(providers).length;
69558
69629
 
@@ -69643,8 +69714,8 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
69643
69714
  };
69644
69715
  }
69645
69716
 
69646
- const { win, appId } = requireContext();
69647
- const result = workspaceController$1.listWorkspacesForApplication(win, appId);
69717
+ const { win, appId } = requireContext$1();
69718
+ const result = workspaceController$2.listWorkspacesForApplication(win, appId);
69648
69719
  if (result.error) {
69649
69720
  return {
69650
69721
  content: [
@@ -69685,7 +69756,7 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
69685
69756
 
69686
69757
  workspace.layout = [...layout, newItem];
69687
69758
 
69688
- const saveResult = workspaceController$1.saveWorkspaceForApplication(
69759
+ const saveResult = workspaceController$2.saveWorkspaceForApplication(
69689
69760
  win,
69690
69761
  appId,
69691
69762
  workspace,
@@ -69736,8 +69807,8 @@ async function handleRemoveWidget$1({ dashboardId, widgetId }) {
69736
69807
  };
69737
69808
  }
69738
69809
 
69739
- const { win, appId } = requireContext();
69740
- const result = workspaceController$1.listWorkspacesForApplication(win, appId);
69810
+ const { win, appId } = requireContext$1();
69811
+ const result = workspaceController$2.listWorkspacesForApplication(win, appId);
69741
69812
  if (result.error) {
69742
69813
  return {
69743
69814
  content: [
@@ -69770,7 +69841,7 @@ async function handleRemoveWidget$1({ dashboardId, widgetId }) {
69770
69841
 
69771
69842
  workspace.layout = layout.filter((item) => String(item.id) !== widgetId);
69772
69843
 
69773
- const saveResult = workspaceController$1.saveWorkspaceForApplication(
69844
+ const saveResult = workspaceController$2.saveWorkspaceForApplication(
69774
69845
  win,
69775
69846
  appId,
69776
69847
  workspace,
@@ -69794,7 +69865,7 @@ async function handleRemoveWidget$1({ dashboardId, widgetId }) {
69794
69865
  text: JSON.stringify({
69795
69866
  success: true,
69796
69867
  removed: widgetId,
69797
- remainingWidgets: countWidgets(workspace.layout),
69868
+ remainingWidgets: countWidgets$1(workspace.layout),
69798
69869
  }),
69799
69870
  },
69800
69871
  ],
@@ -69831,8 +69902,8 @@ async function handleConfigureWidget$1({ dashboardId, widgetId, config }) {
69831
69902
  };
69832
69903
  }
69833
69904
 
69834
- const { win, appId } = requireContext();
69835
- const result = workspaceController$1.listWorkspacesForApplication(win, appId);
69905
+ const { win, appId } = requireContext$1();
69906
+ const result = workspaceController$2.listWorkspacesForApplication(win, appId);
69836
69907
  if (result.error) {
69837
69908
  return {
69838
69909
  content: [
@@ -69866,7 +69937,7 @@ async function handleConfigureWidget$1({ dashboardId, widgetId, config }) {
69866
69937
  // Merge config
69867
69938
  item.config = { ...(item.config || {}), ...config };
69868
69939
 
69869
- const saveResult = workspaceController$1.saveWorkspaceForApplication(
69940
+ const saveResult = workspaceController$2.saveWorkspaceForApplication(
69870
69941
  win,
69871
69942
  appId,
69872
69943
  workspace,
@@ -70055,7 +70126,7 @@ async function handleSearchWidgets$1({ query }) {
70055
70126
 
70056
70127
  // --- Theme Tool Handlers ---
70057
70128
 
70058
- const settingsController$1 = settingsController_1;
70129
+ const settingsController$2 = settingsController_1;
70059
70130
  const themeFromUrlController$1 = themeFromUrlController_1;
70060
70131
  const paletteToThemeMapper$1 = paletteToThemeMapper_1;
70061
70132
  const extractionCacheController$1 = extractionCacheController_1;
@@ -70065,8 +70136,8 @@ const { THEME_SAVE_COMPLETE, SETTINGS_SAVE_COMPLETE } = events$8;
70065
70136
  * list_themes — Returns all saved themes with name, active state, and color summary.
70066
70137
  */
70067
70138
  async function handleListThemes$1() {
70068
- const { win, appId } = requireContext();
70069
- const result = themeController$1.listThemesForApplication(win, appId);
70139
+ const { win, appId } = requireContext$1();
70140
+ const result = themeController$2.listThemesForApplication(win, appId);
70070
70141
 
70071
70142
  if (result.error) {
70072
70143
  return {
@@ -70078,7 +70149,7 @@ async function handleListThemes$1() {
70078
70149
  }
70079
70150
 
70080
70151
  const themes = result.themes || {};
70081
- const settingsResult = settingsController$1.getSettingsForApplication(win);
70152
+ const settingsResult = settingsController$2.getSettingsForApplication(win);
70082
70153
  const activeThemeKey = settingsResult?.settings?.theme || null;
70083
70154
 
70084
70155
  const themeList = Object.keys(themes).map((name) => ({
@@ -70119,8 +70190,8 @@ async function handleGetTheme$1({ name }) {
70119
70190
  };
70120
70191
  }
70121
70192
 
70122
- const { win, appId } = requireContext();
70123
- const result = themeController$1.listThemesForApplication(win, appId);
70193
+ const { win, appId } = requireContext$1();
70194
+ const result = themeController$2.listThemesForApplication(win, appId);
70124
70195
 
70125
70196
  if (result.error) {
70126
70197
  return {
@@ -70146,7 +70217,7 @@ async function handleGetTheme$1({ name }) {
70146
70217
  };
70147
70218
  }
70148
70219
 
70149
- const settingsResult = settingsController$1.getSettingsForApplication(win);
70220
+ const settingsResult = settingsController$2.getSettingsForApplication(win);
70150
70221
  const activeThemeKey = settingsResult?.settings?.theme || null;
70151
70222
 
70152
70223
  return {
@@ -70199,10 +70270,10 @@ async function handleCreateTheme$1({ name, colors }) {
70199
70270
  };
70200
70271
  }
70201
70272
 
70202
- const { win, appId } = requireContext();
70273
+ const { win, appId } = requireContext$1();
70203
70274
  const themeName = name.trim();
70204
70275
 
70205
- const result = themeController$1.saveThemeForApplication(
70276
+ const result = themeController$2.saveThemeForApplication(
70206
70277
  win,
70207
70278
  appId,
70208
70279
  themeName,
@@ -70267,7 +70338,7 @@ async function handleCreateThemeFromUrl$1({ url, name }) {
70267
70338
  };
70268
70339
  }
70269
70340
 
70270
- const { win, appId } = requireContext();
70341
+ const { win, appId } = requireContext$1();
70271
70342
  const { BrowserWindow } = require$$0$2;
70272
70343
 
70273
70344
  const LOAD_TIMEOUT_MS = 15000;
@@ -70417,7 +70488,7 @@ async function handleCreateThemeFromUrl$1({ url, name }) {
70417
70488
  }
70418
70489
 
70419
70490
  // Save the generated theme
70420
- const saveResult = themeController$1.saveThemeForApplication(
70491
+ const saveResult = themeController$2.saveThemeForApplication(
70421
70492
  win,
70422
70493
  appId,
70423
70494
  themeName,
@@ -70487,11 +70558,11 @@ async function handleApplyTheme$1({ name }) {
70487
70558
  };
70488
70559
  }
70489
70560
 
70490
- const { win, appId } = requireContext();
70561
+ const { win, appId } = requireContext$1();
70491
70562
  const themeName = name.trim();
70492
70563
 
70493
70564
  // Verify the theme exists
70494
- const themeResult = themeController$1.listThemesForApplication(win, appId);
70565
+ const themeResult = themeController$2.listThemesForApplication(win, appId);
70495
70566
  if (themeResult.error) {
70496
70567
  return {
70497
70568
  content: [
@@ -70520,11 +70591,11 @@ async function handleApplyTheme$1({ name }) {
70520
70591
  }
70521
70592
 
70522
70593
  // Update settings to set the active theme
70523
- const settingsResult = settingsController$1.getSettingsForApplication(win);
70594
+ const settingsResult = settingsController$2.getSettingsForApplication(win);
70524
70595
  const settings = settingsResult?.settings || {};
70525
70596
  settings.theme = themeName;
70526
70597
 
70527
- const saveResult = settingsController$1.saveSettingsForApplication(
70598
+ const saveResult = settingsController$2.saveSettingsForApplication(
70528
70599
  win,
70529
70600
  settings,
70530
70601
  );
@@ -70554,6 +70625,232 @@ async function handleApplyTheme$1({ name }) {
70554
70625
  };
70555
70626
  }
70556
70627
 
70628
+ // --- Provider Tool Handlers ---
70629
+
70630
+ const { PROVIDER_LIST_COMPLETE } = events$8;
70631
+
70632
+ /**
70633
+ * list_providers — Returns all configured providers with name, type, class, and status.
70634
+ * Credentials/secrets are NEVER included in the response.
70635
+ */
70636
+ async function handleListProviders$1() {
70637
+ const { win, appId } = requireContext$1();
70638
+ const result = providerController$2.listProviders(win, appId);
70639
+
70640
+ if (result.error) {
70641
+ return {
70642
+ content: [
70643
+ { type: "text", text: JSON.stringify({ error: result.message }) },
70644
+ ],
70645
+ isError: true,
70646
+ };
70647
+ }
70648
+
70649
+ const providers = (result.providers || []).map((p) => ({
70650
+ name: p.name,
70651
+ type: p.type,
70652
+ providerClass: p.providerClass || "credential",
70653
+ dateCreated: p.dateCreated,
70654
+ dateUpdated: p.dateUpdated,
70655
+ }));
70656
+
70657
+ return {
70658
+ content: [
70659
+ {
70660
+ type: "text",
70661
+ text: JSON.stringify({ providers, count: providers.length }, null, 2),
70662
+ },
70663
+ ],
70664
+ };
70665
+ }
70666
+
70667
+ /**
70668
+ * add_provider — Adds a new provider with encrypted credentials.
70669
+ * Credentials are accepted on input but never returned in the response.
70670
+ */
70671
+ async function handleAddProvider$1({
70672
+ name,
70673
+ type,
70674
+ providerClass,
70675
+ credentials,
70676
+ mcpConfig,
70677
+ allowedTools,
70678
+ }) {
70679
+ if (!name || typeof name !== "string" || !name.trim()) {
70680
+ return {
70681
+ content: [
70682
+ {
70683
+ type: "text",
70684
+ text: JSON.stringify({
70685
+ error: "name is required and must be a non-empty string",
70686
+ }),
70687
+ },
70688
+ ],
70689
+ isError: true,
70690
+ };
70691
+ }
70692
+
70693
+ if (!type || typeof type !== "string" || !type.trim()) {
70694
+ return {
70695
+ content: [
70696
+ {
70697
+ type: "text",
70698
+ text: JSON.stringify({
70699
+ error: "type is required and must be a non-empty string",
70700
+ }),
70701
+ },
70702
+ ],
70703
+ isError: true,
70704
+ };
70705
+ }
70706
+
70707
+ if (
70708
+ !credentials ||
70709
+ typeof credentials !== "object" ||
70710
+ Array.isArray(credentials)
70711
+ ) {
70712
+ return {
70713
+ content: [
70714
+ {
70715
+ type: "text",
70716
+ text: JSON.stringify({
70717
+ error: "credentials is required and must be an object",
70718
+ }),
70719
+ },
70720
+ ],
70721
+ isError: true,
70722
+ };
70723
+ }
70724
+
70725
+ const resolvedClass = providerClass || "credential";
70726
+ if (resolvedClass !== "credential" && resolvedClass !== "mcp") {
70727
+ return {
70728
+ content: [
70729
+ {
70730
+ type: "text",
70731
+ text: JSON.stringify({
70732
+ error: "providerClass must be 'credential' or 'mcp'",
70733
+ }),
70734
+ },
70735
+ ],
70736
+ isError: true,
70737
+ };
70738
+ }
70739
+
70740
+ const { win, appId } = requireContext$1();
70741
+ const providerName = name.trim();
70742
+ const providerType = type.trim();
70743
+
70744
+ // Check for duplicate names
70745
+ const existing = providerController$2.listProviders(win, appId);
70746
+ if (!existing.error) {
70747
+ const duplicate = (existing.providers || []).find(
70748
+ (p) => p.name === providerName,
70749
+ );
70750
+ if (duplicate) {
70751
+ return {
70752
+ content: [
70753
+ {
70754
+ type: "text",
70755
+ text: JSON.stringify({
70756
+ error: `A provider with name "${providerName}" already exists. Remove it first or use a different name.`,
70757
+ }),
70758
+ },
70759
+ ],
70760
+ isError: true,
70761
+ };
70762
+ }
70763
+ }
70764
+
70765
+ const result = providerController$2.saveProvider(
70766
+ win,
70767
+ appId,
70768
+ providerName,
70769
+ providerType,
70770
+ credentials,
70771
+ resolvedClass,
70772
+ resolvedClass === "mcp" ? mcpConfig || null : null,
70773
+ resolvedClass === "mcp" ? allowedTools || null : null,
70774
+ );
70775
+
70776
+ if (result.error) {
70777
+ return {
70778
+ content: [
70779
+ { type: "text", text: JSON.stringify({ error: result.message }) },
70780
+ ],
70781
+ isError: true,
70782
+ };
70783
+ }
70784
+
70785
+ // Notify the renderer so the UI updates
70786
+ const listResult = providerController$2.listProviders(win, appId);
70787
+ win.webContents.send(PROVIDER_LIST_COMPLETE, listResult);
70788
+
70789
+ return {
70790
+ content: [
70791
+ {
70792
+ type: "text",
70793
+ text: JSON.stringify(
70794
+ {
70795
+ name: providerName,
70796
+ type: providerType,
70797
+ providerClass: resolvedClass,
70798
+ created: true,
70799
+ },
70800
+ null,
70801
+ 2,
70802
+ ),
70803
+ },
70804
+ ],
70805
+ };
70806
+ }
70807
+
70808
+ /**
70809
+ * remove_provider — Removes a provider by name, deleting its stored credentials.
70810
+ */
70811
+ async function handleRemoveProvider$1({ name }) {
70812
+ if (!name || typeof name !== "string" || !name.trim()) {
70813
+ return {
70814
+ content: [
70815
+ {
70816
+ type: "text",
70817
+ text: JSON.stringify({
70818
+ error: "name is required and must be a non-empty string",
70819
+ }),
70820
+ },
70821
+ ],
70822
+ isError: true,
70823
+ };
70824
+ }
70825
+
70826
+ const { win, appId } = requireContext$1();
70827
+ const providerName = name.trim();
70828
+
70829
+ const result = providerController$2.deleteProvider(win, appId, providerName);
70830
+
70831
+ if (result.error) {
70832
+ return {
70833
+ content: [
70834
+ { type: "text", text: JSON.stringify({ error: result.message }) },
70835
+ ],
70836
+ isError: true,
70837
+ };
70838
+ }
70839
+
70840
+ // Notify the renderer so the UI updates
70841
+ const listResult = providerController$2.listProviders(win, appId);
70842
+ win.webContents.send(PROVIDER_LIST_COMPLETE, listResult);
70843
+
70844
+ return {
70845
+ content: [
70846
+ {
70847
+ type: "text",
70848
+ text: JSON.stringify({ name: providerName, removed: true }, null, 2),
70849
+ },
70850
+ ],
70851
+ };
70852
+ }
70853
+
70557
70854
  var toolHandlers = {
70558
70855
  handleListDashboards: handleListDashboards$1,
70559
70856
  handleGetDashboard: handleGetDashboard$1,
@@ -70570,6 +70867,9 @@ var toolHandlers = {
70570
70867
  handleCreateTheme: handleCreateTheme$1,
70571
70868
  handleCreateThemeFromUrl: handleCreateThemeFromUrl$1,
70572
70869
  handleApplyTheme: handleApplyTheme$1,
70870
+ handleListProviders: handleListProviders$1,
70871
+ handleAddProvider: handleAddProvider$1,
70872
+ handleRemoveProvider: handleRemoveProvider$1,
70573
70873
  };
70574
70874
 
70575
70875
  /**
@@ -70579,7 +70879,7 @@ var toolHandlers = {
70579
70879
  * Call registerDashboardTools() during app startup (before or after server start).
70580
70880
  */
70581
70881
 
70582
- const { registerTool: registerTool$2 } = mcpDashServerController_1;
70882
+ const { registerTool: registerTool$3 } = mcpDashServerController_1;
70583
70883
  const { dashboardTools } = toolDefinitions;
70584
70884
  const {
70585
70885
  handleListDashboards,
@@ -70590,7 +70890,7 @@ const {
70590
70890
  } = toolHandlers;
70591
70891
 
70592
70892
  // Map tool names to handler functions
70593
- const handlerMap$2 = {
70893
+ const handlerMap$4 = {
70594
70894
  list_dashboards: handleListDashboards,
70595
70895
  get_dashboard: handleGetDashboard,
70596
70896
  create_dashboard: handleCreateDashboard,
@@ -70603,12 +70903,12 @@ const handlerMap$2 = {
70603
70903
  */
70604
70904
  function registerDashboardTools$1() {
70605
70905
  for (const tool of dashboardTools) {
70606
- const handler = handlerMap$2[tool.name];
70906
+ const handler = handlerMap$4[tool.name];
70607
70907
  if (!handler) {
70608
70908
  console.warn(`[dashboardTools] No handler found for tool: ${tool.name}`);
70609
70909
  continue;
70610
70910
  }
70611
- registerTool$2({
70911
+ registerTool$3({
70612
70912
  name: tool.name,
70613
70913
  description: tool.description,
70614
70914
  inputSchema: tool.inputSchema,
@@ -70629,7 +70929,7 @@ var dashboardTools_1 = { registerDashboardTools: registerDashboardTools$1 };
70629
70929
  * Call registerWidgetTools() during app startup (before or after server start).
70630
70930
  */
70631
70931
 
70632
- const { registerTool: registerTool$1 } = mcpDashServerController_1;
70932
+ const { registerTool: registerTool$2 } = mcpDashServerController_1;
70633
70933
  const { widgetTools } = toolDefinitions;
70634
70934
  const {
70635
70935
  handleAddWidget,
@@ -70640,7 +70940,7 @@ const {
70640
70940
  } = toolHandlers;
70641
70941
 
70642
70942
  // Map tool names to handler functions
70643
- const handlerMap$1 = {
70943
+ const handlerMap$3 = {
70644
70944
  add_widget: handleAddWidget,
70645
70945
  remove_widget: handleRemoveWidget,
70646
70946
  configure_widget: handleConfigureWidget,
@@ -70653,12 +70953,12 @@ const handlerMap$1 = {
70653
70953
  */
70654
70954
  function registerWidgetTools$1() {
70655
70955
  for (const tool of widgetTools) {
70656
- const handler = handlerMap$1[tool.name];
70956
+ const handler = handlerMap$3[tool.name];
70657
70957
  if (!handler) {
70658
70958
  console.warn(`[widgetTools] No handler found for tool: ${tool.name}`);
70659
70959
  continue;
70660
70960
  }
70661
- registerTool$1({
70961
+ registerTool$2({
70662
70962
  name: tool.name,
70663
70963
  description: tool.description,
70664
70964
  inputSchema: tool.inputSchema,
@@ -70677,7 +70977,7 @@ var widgetTools_1 = { registerWidgetTools: registerWidgetTools$1 };
70677
70977
  * Call registerThemeTools() during app startup (before or after server start).
70678
70978
  */
70679
70979
 
70680
- const { registerTool } = mcpDashServerController_1;
70980
+ const { registerTool: registerTool$1 } = mcpDashServerController_1;
70681
70981
  const { themeTools } = toolDefinitions;
70682
70982
  const {
70683
70983
  handleListThemes,
@@ -70688,7 +70988,7 @@ const {
70688
70988
  } = toolHandlers;
70689
70989
 
70690
70990
  // Map tool names to handler functions
70691
- const handlerMap = {
70991
+ const handlerMap$2 = {
70692
70992
  list_themes: handleListThemes,
70693
70993
  get_theme: handleGetTheme,
70694
70994
  create_theme: handleCreateTheme,
@@ -70701,12 +71001,12 @@ const handlerMap = {
70701
71001
  */
70702
71002
  function registerThemeTools$1() {
70703
71003
  for (const tool of themeTools) {
70704
- const handler = handlerMap[tool.name];
71004
+ const handler = handlerMap$2[tool.name];
70705
71005
  if (!handler) {
70706
71006
  console.warn(`[themeTools] No handler found for tool: ${tool.name}`);
70707
71007
  continue;
70708
71008
  }
70709
- registerTool({
71009
+ registerTool$1({
70710
71010
  name: tool.name,
70711
71011
  description: tool.description,
70712
71012
  inputSchema: tool.inputSchema,
@@ -70718,6 +71018,373 @@ function registerThemeTools$1() {
70718
71018
 
70719
71019
  var themeTools_1 = { registerThemeTools: registerThemeTools$1 };
70720
71020
 
71021
+ /**
71022
+ * providerTools.js
71023
+ *
71024
+ * Registers provider MCP tools with the MCP Dash server.
71025
+ * Call registerProviderTools() during app startup (before or after server start).
71026
+ */
71027
+
71028
+ const { registerTool } = mcpDashServerController_1;
71029
+ const { providerTools } = toolDefinitions;
71030
+ const {
71031
+ handleListProviders,
71032
+ handleAddProvider,
71033
+ handleRemoveProvider,
71034
+ } = toolHandlers;
71035
+
71036
+ // Map tool names to handler functions
71037
+ const handlerMap$1 = {
71038
+ list_providers: handleListProviders,
71039
+ add_provider: handleAddProvider,
71040
+ remove_provider: handleRemoveProvider,
71041
+ };
71042
+
71043
+ /**
71044
+ * Register all provider tools with the MCP server controller.
71045
+ */
71046
+ function registerProviderTools$1() {
71047
+ for (const tool of providerTools) {
71048
+ const handler = handlerMap$1[tool.name];
71049
+ if (!handler) {
71050
+ console.warn(`[providerTools] No handler found for tool: ${tool.name}`);
71051
+ continue;
71052
+ }
71053
+ registerTool({
71054
+ name: tool.name,
71055
+ description: tool.description,
71056
+ inputSchema: tool.inputSchema,
71057
+ handler,
71058
+ });
71059
+ }
71060
+ console.log(
71061
+ `[providerTools] Registered ${providerTools.length} provider tools`,
71062
+ );
71063
+ }
71064
+
71065
+ var providerTools_1 = { registerProviderTools: registerProviderTools$1 };
71066
+
71067
+ /**
71068
+ * resourceDefinitions.js
71069
+ *
71070
+ * MCP resource definitions for read-only app state via dash:// URIs.
71071
+ * Each resource exposes a snapshot of Dash state to external LLM clients.
71072
+ */
71073
+
71074
+ const dashResources$1 = [
71075
+ {
71076
+ name: "active-dashboard",
71077
+ uri: "dash://dashboards/active",
71078
+ description:
71079
+ "Current active dashboard — layout, widgets, theme, and widget count",
71080
+ },
71081
+ {
71082
+ name: "all-dashboards",
71083
+ uri: "dash://dashboards",
71084
+ description:
71085
+ "Summary of all dashboards — IDs, names, widget counts, active state",
71086
+ },
71087
+ {
71088
+ name: "all-themes",
71089
+ uri: "dash://themes",
71090
+ description:
71091
+ "All saved themes — names, active state, and color definitions",
71092
+ },
71093
+ {
71094
+ name: "all-providers",
71095
+ uri: "dash://providers",
71096
+ description:
71097
+ "All configured providers — names, types, classes (no credentials or secrets)",
71098
+ },
71099
+ {
71100
+ name: "app-info",
71101
+ uri: "dash://app/info",
71102
+ description:
71103
+ "Application info — version, appId, and counts of dashboards, widgets, themes, providers",
71104
+ },
71105
+ ];
71106
+
71107
+ var resourceDefinitions = { dashResources: dashResources$1 };
71108
+
71109
+ /**
71110
+ * resourceHandlers.js
71111
+ *
71112
+ * MCP resource handlers for read-only app state.
71113
+ * Each handler delegates to existing controllers via getServerContext().
71114
+ * Returns { contents: [{ uri, mimeType, text }] } per MCP resource spec.
71115
+ */
71116
+
71117
+ const mcpDashServerController$1 = mcpDashServerController_1;
71118
+ const workspaceController$1 = workspaceController_1;
71119
+ const themeController$1 = themeController_1;
71120
+ const providerController$1 = requireProviderController();
71121
+ const settingsController$1 = settingsController_1;
71122
+
71123
+ /**
71124
+ * Helper: get win + appId or throw a descriptive error.
71125
+ */
71126
+ function requireContext() {
71127
+ const ctx = mcpDashServerController$1.getServerContext();
71128
+ if (!ctx) {
71129
+ throw new Error("MCP server is not running or has no active window");
71130
+ }
71131
+ return ctx;
71132
+ }
71133
+
71134
+ /**
71135
+ * Helper: count widgets in a workspace's layout array.
71136
+ */
71137
+ function countWidgets(layout) {
71138
+ if (!Array.isArray(layout)) return 0;
71139
+ return layout.filter(
71140
+ (item) =>
71141
+ item.component &&
71142
+ item.component !== "Container" &&
71143
+ item.component !== "LayoutContainer" &&
71144
+ item.component !== "LayoutGridContainer",
71145
+ ).length;
71146
+ }
71147
+
71148
+ /**
71149
+ * Helper: wrap data as an MCP resource response.
71150
+ */
71151
+ function resourceResponse(uri, data) {
71152
+ return {
71153
+ contents: [
71154
+ {
71155
+ uri,
71156
+ mimeType: "application/json",
71157
+ text: JSON.stringify(data, null, 2),
71158
+ },
71159
+ ],
71160
+ };
71161
+ }
71162
+
71163
+ /**
71164
+ * dash://dashboards/active — Current active dashboard state.
71165
+ */
71166
+ async function handleActiveDashboard$1(uri) {
71167
+ const { win, appId } = requireContext();
71168
+ const result = workspaceController$1.listWorkspacesForApplication(win, appId);
71169
+
71170
+ if (result.error) {
71171
+ return resourceResponse(uri.href, { error: result.message });
71172
+ }
71173
+
71174
+ const workspaces = result.workspaces || [];
71175
+ const workspace = workspaces[0];
71176
+
71177
+ if (!workspace) {
71178
+ return resourceResponse(uri.href, { error: "No dashboards exist" });
71179
+ }
71180
+
71181
+ const widgets = (workspace.layout || [])
71182
+ .filter(
71183
+ (item) =>
71184
+ item.component &&
71185
+ item.component !== "Container" &&
71186
+ item.component !== "LayoutContainer" &&
71187
+ item.component !== "LayoutGridContainer",
71188
+ )
71189
+ .map((item) => ({
71190
+ id: String(item.id),
71191
+ type: item.component,
71192
+ config: item.config || {},
71193
+ }));
71194
+
71195
+ return resourceResponse(uri.href, {
71196
+ id: String(workspace.id),
71197
+ name: workspace.name || workspace.label || "Dashboard",
71198
+ widgetCount: widgets.length,
71199
+ widgets,
71200
+ layout: workspace.layout || [],
71201
+ theme: workspace.theme || null,
71202
+ });
71203
+ }
71204
+
71205
+ /**
71206
+ * dash://dashboards — All dashboards summary.
71207
+ */
71208
+ async function handleAllDashboards$1(uri) {
71209
+ const { win, appId } = requireContext();
71210
+ const result = workspaceController$1.listWorkspacesForApplication(win, appId);
71211
+
71212
+ if (result.error) {
71213
+ return resourceResponse(uri.href, { error: result.message });
71214
+ }
71215
+
71216
+ const dashboards = (result.workspaces || []).map((ws, index) => ({
71217
+ id: String(ws.id),
71218
+ name: ws.name || ws.label || `Dashboard ${index + 1}`,
71219
+ widgetCount: countWidgets(ws.layout),
71220
+ isActive: index === 0,
71221
+ }));
71222
+
71223
+ return resourceResponse(uri.href, {
71224
+ dashboards,
71225
+ count: dashboards.length,
71226
+ });
71227
+ }
71228
+
71229
+ /**
71230
+ * dash://themes — All themes with active state.
71231
+ */
71232
+ async function handleAllThemes$1(uri) {
71233
+ const { win, appId } = requireContext();
71234
+ const result = themeController$1.listThemesForApplication(win, appId);
71235
+
71236
+ if (result.error) {
71237
+ return resourceResponse(uri.href, { error: result.message });
71238
+ }
71239
+
71240
+ const themes = result.themes || {};
71241
+ const settingsResult = settingsController$1.getSettingsForApplication(win);
71242
+ const activeThemeKey = settingsResult?.settings?.theme || null;
71243
+
71244
+ const themeList = Object.keys(themes).map((name) => ({
71245
+ name,
71246
+ isActive: name === activeThemeKey,
71247
+ colors: themes[name],
71248
+ }));
71249
+
71250
+ return resourceResponse(uri.href, {
71251
+ themes: themeList,
71252
+ count: themeList.length,
71253
+ activeTheme: activeThemeKey,
71254
+ });
71255
+ }
71256
+
71257
+ /**
71258
+ * dash://providers — All providers (no secrets).
71259
+ */
71260
+ async function handleAllProviders$1(uri) {
71261
+ const { win, appId } = requireContext();
71262
+ const result = providerController$1.listProviders(win, appId);
71263
+
71264
+ if (result.error) {
71265
+ return resourceResponse(uri.href, { error: result.message });
71266
+ }
71267
+
71268
+ const providers = (result.providers || []).map((p) => ({
71269
+ name: p.name,
71270
+ type: p.type,
71271
+ providerClass: p.providerClass || "credential",
71272
+ dateCreated: p.dateCreated,
71273
+ dateUpdated: p.dateUpdated,
71274
+ }));
71275
+
71276
+ return resourceResponse(uri.href, {
71277
+ providers,
71278
+ count: providers.length,
71279
+ });
71280
+ }
71281
+
71282
+ /**
71283
+ * dash://app/info — Version, appId, and aggregate stats.
71284
+ */
71285
+ async function handleAppInfo$1(uri) {
71286
+ const { win, appId } = requireContext();
71287
+
71288
+ // Dashboards + widget count
71289
+ const wsResult = workspaceController$1.listWorkspacesForApplication(win, appId);
71290
+ const workspaces = wsResult.workspaces || [];
71291
+ const dashboardCount = workspaces.length;
71292
+ const widgetCount = workspaces.reduce(
71293
+ (sum, ws) => sum + countWidgets(ws.layout),
71294
+ 0,
71295
+ );
71296
+
71297
+ // Themes
71298
+ const themeResult = themeController$1.listThemesForApplication(win, appId);
71299
+ const themes = themeResult.themes || {};
71300
+ const themeCount = Object.keys(themes).length;
71301
+
71302
+ // Providers
71303
+ const providerResult = providerController$1.listProviders(win, appId);
71304
+ const providers = providerResult.providers || {};
71305
+ const providerCount = Array.isArray(providers)
71306
+ ? providers.length
71307
+ : Object.keys(providers).length;
71308
+
71309
+ // Server status
71310
+ const status = mcpDashServerController$1.getStatus(win);
71311
+
71312
+ return resourceResponse(uri.href, {
71313
+ appId,
71314
+ server: {
71315
+ version: "1.0.0",
71316
+ port: status.port,
71317
+ uptime: status.uptime,
71318
+ toolCount: status.toolCount,
71319
+ resourceCount: status.resourceCount,
71320
+ },
71321
+ stats: {
71322
+ dashboardCount,
71323
+ widgetCount,
71324
+ themeCount,
71325
+ providerCount,
71326
+ },
71327
+ });
71328
+ }
71329
+
71330
+ var resourceHandlers = {
71331
+ handleActiveDashboard: handleActiveDashboard$1,
71332
+ handleAllDashboards: handleAllDashboards$1,
71333
+ handleAllThemes: handleAllThemes$1,
71334
+ handleAllProviders: handleAllProviders$1,
71335
+ handleAppInfo: handleAppInfo$1,
71336
+ };
71337
+
71338
+ /**
71339
+ * resources.js
71340
+ *
71341
+ * Registers MCP resources with the MCP Dash server.
71342
+ * Call registerResources() during app startup (before or after server start).
71343
+ */
71344
+
71345
+ const { registerResource } = mcpDashServerController_1;
71346
+ const { dashResources } = resourceDefinitions;
71347
+ const {
71348
+ handleActiveDashboard,
71349
+ handleAllDashboards,
71350
+ handleAllThemes,
71351
+ handleAllProviders,
71352
+ handleAppInfo,
71353
+ } = resourceHandlers;
71354
+
71355
+ // Map resource URIs to handler functions
71356
+ const handlerMap = {
71357
+ "dash://dashboards/active": handleActiveDashboard,
71358
+ "dash://dashboards": handleAllDashboards,
71359
+ "dash://themes": handleAllThemes,
71360
+ "dash://providers": handleAllProviders,
71361
+ "dash://app/info": handleAppInfo,
71362
+ };
71363
+
71364
+ /**
71365
+ * Register all MCP resources with the server controller.
71366
+ */
71367
+ function registerResources$1() {
71368
+ for (const resource of dashResources) {
71369
+ const handler = handlerMap[resource.uri];
71370
+ if (!handler) {
71371
+ console.warn(
71372
+ `[resources] No handler found for resource: ${resource.uri}`,
71373
+ );
71374
+ continue;
71375
+ }
71376
+ registerResource({
71377
+ name: resource.name,
71378
+ uri: resource.uri,
71379
+ metadata: { description: resource.description },
71380
+ handler,
71381
+ });
71382
+ }
71383
+ console.log(`[resources] Registered ${dashResources.length} MCP resources`);
71384
+ }
71385
+
71386
+ var resources = { registerResources: registerResources$1 };
71387
+
70721
71388
  /**
70722
71389
  * dashboardRatingsApi.js
70723
71390
  *
@@ -71042,9 +71709,13 @@ const dynamicWidgetLoader = dynamicWidgetLoaderExports;
71042
71709
  const { registerDashboardTools } = dashboardTools_1;
71043
71710
  const { registerWidgetTools } = widgetTools_1;
71044
71711
  const { registerThemeTools } = themeTools_1;
71712
+ const { registerProviderTools } = providerTools_1;
71713
+ const { registerResources } = resources;
71045
71714
  registerDashboardTools();
71046
71715
  registerWidgetTools();
71047
71716
  registerThemeTools();
71717
+ registerProviderTools();
71718
+ registerResources();
71048
71719
 
71049
71720
  // --- Schema ---
71050
71721
  const dashboardConfigValidator = dashboardConfigValidator$1;
@@ -71142,6 +71813,8 @@ var electron = {
71142
71813
  registerDashboardTools,
71143
71814
  registerWidgetTools,
71144
71815
  registerThemeTools,
71816
+ registerProviderTools,
71817
+ registerResources,
71145
71818
  };
71146
71819
 
71147
71820
  var index = /*@__PURE__*/getDefaultExportFromCjs(electron);