@trops/dash-core 0.1.55 → 0.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -672,6 +672,8 @@ var MCP_SERVER_STATUS_COMPLETE = "mcp:server-status:complete";
672
672
  var MCP_SERVER_STATUS_ERROR = "mcp:server-status:error";
673
673
  var MCP_GET_CATALOG_COMPLETE = "mcp:get-catalog:complete";
674
674
  var MCP_GET_CATALOG_ERROR = "mcp:get-catalog:error";
675
+ var MCP_RUN_AUTH_COMPLETE = "mcp:run-auth:complete";
676
+ var MCP_RUN_AUTH_ERROR = "mcp:run-auth:error";
675
677
 
676
678
  var DATA_JSON_TO_CSV_FILE = "data-json-to-csv-file";
677
679
  var DATA_JSON_TO_CSV_FILE_COMPLETE = "data-json-to-csv-file-complete";
@@ -780,6 +782,8 @@ var apiEvents = /*#__PURE__*/Object.freeze({
780
782
  MCP_LIST_TOOLS_ERROR: MCP_LIST_TOOLS_ERROR,
781
783
  MCP_READ_RESOURCE_COMPLETE: MCP_READ_RESOURCE_COMPLETE,
782
784
  MCP_READ_RESOURCE_ERROR: MCP_READ_RESOURCE_ERROR,
785
+ MCP_RUN_AUTH_COMPLETE: MCP_RUN_AUTH_COMPLETE,
786
+ MCP_RUN_AUTH_ERROR: MCP_RUN_AUTH_ERROR,
783
787
  MCP_SERVER_STATUS_COMPLETE: MCP_SERVER_STATUS_COMPLETE,
784
788
  MCP_SERVER_STATUS_ERROR: MCP_SERVER_STATUS_ERROR,
785
789
  MCP_START_SERVER_COMPLETE: MCP_START_SERVER_COMPLETE,
@@ -1478,6 +1482,27 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
1478
1482
  return false;
1479
1483
  }
1480
1484
  }
1485
+ }, {
1486
+ key: "mcpRunAuth",
1487
+ value: function mcpRunAuth(mcpConfig, credentials, authCommand, onSuccess, onError) {
1488
+ var _this26 = this;
1489
+ if (this.api !== null) {
1490
+ try {
1491
+ this.api.mcp.runAuth(mcpConfig, credentials, authCommand).then(function (result) {
1492
+ onSuccess(_this26.events.MCP_RUN_AUTH_COMPLETE, result);
1493
+ })["catch"](function (error) {
1494
+ onError(_this26.events.MCP_RUN_AUTH_ERROR, error);
1495
+ });
1496
+ return true;
1497
+ } catch (e) {
1498
+ onError(this.events.MCP_RUN_AUTH_ERROR, e);
1499
+ return false;
1500
+ }
1501
+ } else {
1502
+ onError(this.events.MCP_RUN_AUTH_ERROR, new Error("No Api found"));
1503
+ return false;
1504
+ }
1505
+ }
1481
1506
  }]);
1482
1507
  }();
1483
1508
 
@@ -19482,7 +19507,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
19482
19507
  * even when multiple hook instances call connect() simultaneously.
19483
19508
  */
19484
19509
  var connect = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
19485
- var cached, result, state, connectPromise, _result, _t, _t2;
19510
+ var cached, statusResult, result, state, connectPromise, _result, _t2, _t3;
19486
19511
  return _regeneratorRuntime.wrap(function (_context) {
19487
19512
  while (1) switch (_context.prev = _context.next) {
19488
19513
  case 0:
@@ -19513,65 +19538,90 @@ var useMcpProvider = function useMcpProvider(providerType) {
19513
19538
  setError("Provider \"".concat(selectedProviderName, "\" has no MCP configuration"));
19514
19539
  return _context.abrupt("return");
19515
19540
  case 4:
19516
- // 1. Already connected at module level? Apply cached result, skip IPC
19541
+ // 1. Already connected at module level? Verify with main process before trusting cache.
19542
+ // The server may have been stopped externally (e.g., Test Connection in settings).
19517
19543
  cached = serverStates.get(selectedProviderName);
19518
19544
  if (!(cached && cached.status === "connected")) {
19519
- _context.next = 5;
19545
+ _context.next = 9;
19546
+ break;
19547
+ }
19548
+ _context.prev = 5;
19549
+ _context.next = 6;
19550
+ return new Promise(function (resolve, reject) {
19551
+ dashApi.mcpGetServerStatus(selectedProviderName, function (event, result) {
19552
+ return resolve(result);
19553
+ }, function (event, err) {
19554
+ return reject(err);
19555
+ });
19556
+ });
19557
+ case 6:
19558
+ statusResult = _context.sent;
19559
+ if (!((statusResult === null || statusResult === void 0 ? void 0 : statusResult.status) === "connected")) {
19560
+ _context.next = 7;
19520
19561
  break;
19521
19562
  }
19522
19563
  cached.consumerCount++;
19523
19564
  applyResult(cached);
19524
19565
  return _context.abrupt("return");
19525
- case 5:
19566
+ case 7:
19567
+ // Server was stopped externally — clear stale cache and reconnect
19568
+ serverStates["delete"](selectedProviderName);
19569
+ _context.next = 9;
19570
+ break;
19571
+ case 8:
19572
+ _context.prev = 8;
19573
+ _context["catch"](5);
19574
+ serverStates["delete"](selectedProviderName);
19575
+ case 9:
19526
19576
  setIsConnecting(true);
19527
19577
  setError(null);
19528
19578
 
19529
19579
  // 2. Another hook instance already connecting? Piggyback on its promise
19530
19580
  if (!pendingConnects.has(selectedProviderName)) {
19531
- _context.next = 13;
19581
+ _context.next = 17;
19532
19582
  break;
19533
19583
  }
19534
- _context.prev = 6;
19535
- _context.next = 7;
19584
+ _context.prev = 10;
19585
+ _context.next = 11;
19536
19586
  return pendingConnects.get(selectedProviderName);
19537
- case 7:
19587
+ case 11:
19538
19588
  result = _context.sent;
19539
19589
  if (mountedRef.current) {
19540
- _context.next = 8;
19590
+ _context.next = 12;
19541
19591
  break;
19542
19592
  }
19543
19593
  return _context.abrupt("return");
19544
- case 8:
19594
+ case 12:
19545
19595
  if (!result.error) {
19546
- _context.next = 9;
19596
+ _context.next = 13;
19547
19597
  break;
19548
19598
  }
19549
19599
  setError(result.message);
19550
19600
  setIsConnecting(false);
19551
19601
  setStatus("error");
19552
19602
  return _context.abrupt("return");
19553
- case 9:
19603
+ case 13:
19554
19604
  // Increment consumer count and apply
19555
19605
  state = serverStates.get(selectedProviderName);
19556
19606
  if (state) state.consumerCount++;
19557
19607
  applyResult(result);
19558
- _context.next = 12;
19608
+ _context.next = 16;
19559
19609
  break;
19560
- case 10:
19561
- _context.prev = 10;
19562
- _t = _context["catch"](6);
19610
+ case 14:
19611
+ _context.prev = 14;
19612
+ _t2 = _context["catch"](10);
19563
19613
  if (mountedRef.current) {
19564
- _context.next = 11;
19614
+ _context.next = 15;
19565
19615
  break;
19566
19616
  }
19567
19617
  return _context.abrupt("return");
19568
- case 11:
19569
- setError((_t === null || _t === void 0 ? void 0 : _t.message) || "Failed to connect to MCP server");
19618
+ case 15:
19619
+ setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || "Failed to connect to MCP server");
19570
19620
  setIsConnecting(false);
19571
19621
  setStatus("error");
19572
- case 12:
19622
+ case 16:
19573
19623
  return _context.abrupt("return");
19574
- case 13:
19624
+ case 17:
19575
19625
  // 3. First caller — fire the IPC call and share the promise
19576
19626
  connectPromise = new Promise(function (resolve, reject) {
19577
19627
  dashApi.mcpStartServer(selectedProviderName, provider.mcpConfig, provider.credentials, function (event, result) {
@@ -19607,46 +19657,46 @@ var useMcpProvider = function useMcpProvider(providerType) {
19607
19657
  });
19608
19658
  });
19609
19659
  pendingConnects.set(selectedProviderName, connectPromise);
19610
- _context.prev = 14;
19611
- _context.next = 15;
19660
+ _context.prev = 18;
19661
+ _context.next = 19;
19612
19662
  return connectPromise;
19613
- case 15:
19663
+ case 19:
19614
19664
  _result = _context.sent;
19615
19665
  if (mountedRef.current) {
19616
- _context.next = 16;
19666
+ _context.next = 20;
19617
19667
  break;
19618
19668
  }
19619
19669
  return _context.abrupt("return");
19620
- case 16:
19670
+ case 20:
19621
19671
  if (!_result.error) {
19622
- _context.next = 17;
19672
+ _context.next = 21;
19623
19673
  break;
19624
19674
  }
19625
19675
  setError(_result.message);
19626
19676
  setIsConnecting(false);
19627
19677
  setStatus("error");
19628
19678
  return _context.abrupt("return");
19629
- case 17:
19679
+ case 21:
19630
19680
  applyResult(_result);
19631
- _context.next = 20;
19681
+ _context.next = 24;
19632
19682
  break;
19633
- case 18:
19634
- _context.prev = 18;
19635
- _t2 = _context["catch"](14);
19683
+ case 22:
19684
+ _context.prev = 22;
19685
+ _t3 = _context["catch"](18);
19636
19686
  if (mountedRef.current) {
19637
- _context.next = 19;
19687
+ _context.next = 23;
19638
19688
  break;
19639
19689
  }
19640
19690
  return _context.abrupt("return");
19641
- case 19:
19642
- setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || "Failed to connect to MCP server");
19691
+ case 23:
19692
+ setError((_t3 === null || _t3 === void 0 ? void 0 : _t3.message) || "Failed to connect to MCP server");
19643
19693
  setIsConnecting(false);
19644
19694
  setStatus("error");
19645
- case 20:
19695
+ case 24:
19646
19696
  case "end":
19647
19697
  return _context.stop();
19648
19698
  }
19649
- }, _callee, null, [[6, 10], [14, 18]]);
19699
+ }, _callee, null, [[5, 8], [10, 14], [18, 22]]);
19650
19700
  })), [dashApi, provider, providerType, selectedProviderName, applyResult]);
19651
19701
 
19652
19702
  /**
@@ -25849,7 +25899,7 @@ var FoldersSection = function FoldersSection(_ref) {
25849
25899
  function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
25850
25900
  function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
25851
25901
  var ProviderDetail = function ProviderDetail(_ref) {
25852
- var _testResult$tools;
25902
+ var _provider$mcpConfig, _testResult$tools;
25853
25903
  var _ref$providerName = _ref.providerName,
25854
25904
  providerName = _ref$providerName === void 0 ? null : _ref$providerName,
25855
25905
  _ref$provider = _ref.provider,
@@ -25871,7 +25921,9 @@ var ProviderDetail = function ProviderDetail(_ref) {
25871
25921
  onCancelEdit = _ref.onCancelEdit,
25872
25922
  onStartEdit = _ref.onStartEdit,
25873
25923
  onCreate = _ref.onCreate,
25874
- onDelete = _ref.onDelete;
25924
+ onDelete = _ref.onDelete,
25925
+ _ref$catalogAuthComma = _ref.catalogAuthCommand,
25926
+ catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma;
25875
25927
  var appContext = useContext(AppContext);
25876
25928
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
25877
25929
  var isMcp = (provider === null || provider === void 0 ? void 0 : provider.providerClass) === "mcp";
@@ -25886,6 +25938,19 @@ var ProviderDetail = function ProviderDetail(_ref) {
25886
25938
  testResult = _useState4[0],
25887
25939
  setTestResult = _useState4[1];
25888
25940
 
25941
+ // MCP auth state
25942
+ var _useState5 = useState(false),
25943
+ _useState6 = _slicedToArray(_useState5, 2),
25944
+ isAuthorizing = _useState6[0],
25945
+ setIsAuthorizing = _useState6[1];
25946
+ var _useState7 = useState(null),
25947
+ _useState8 = _slicedToArray(_useState7, 2),
25948
+ authResult = _useState8[0],
25949
+ setAuthResult = _useState8[1];
25950
+
25951
+ // Resolve authCommand: provider.mcpConfig.authCommand > catalogAuthCommand prop
25952
+ var resolvedAuthCommand = (provider === null || provider === void 0 || (_provider$mcpConfig = provider.mcpConfig) === null || _provider$mcpConfig === void 0 ? void 0 : _provider$mcpConfig.authCommand) || catalogAuthCommand || null;
25953
+
25889
25954
  // Derive credential fields for MCP providers in edit mode
25890
25955
  var mcpFormFields = useMemo(function () {
25891
25956
  if (!isMcp || !(provider !== null && provider !== void 0 && provider.mcpConfig)) return [];
@@ -25899,14 +25964,14 @@ var ProviderDetail = function ProviderDetail(_ref) {
25899
25964
  }, [isMcp, provider]);
25900
25965
 
25901
25966
  // Dynamic credential fields for create mode
25902
- var _useState5 = useState(isCreating ? [{
25967
+ var _useState9 = useState(isCreating ? [{
25903
25968
  id: "default_apiKey",
25904
25969
  key: "apiKey",
25905
25970
  secret: true
25906
25971
  }] : []),
25907
- _useState6 = _slicedToArray(_useState5, 2),
25908
- credentialFields = _useState6[0],
25909
- setCredentialFields = _useState6[1];
25972
+ _useState0 = _slicedToArray(_useState9, 2),
25973
+ credentialFields = _useState0[0],
25974
+ setCredentialFields = _useState0[1];
25910
25975
  var fieldIdRef = useRef(0);
25911
25976
  var handleFieldKeyChange = function handleFieldKeyChange(id, newKey) {
25912
25977
  setCredentialFields(function (prev) {
@@ -26009,6 +26074,31 @@ var ProviderDetail = function ProviderDetail(_ref) {
26009
26074
  setIsTesting(false);
26010
26075
  });
26011
26076
  };
26077
+ var handleAuthorize = function handleAuthorize() {
26078
+ if (!dashApi || !(provider !== null && provider !== void 0 && provider.mcpConfig) || !resolvedAuthCommand) return;
26079
+ setIsAuthorizing(true);
26080
+ setAuthResult(null);
26081
+ dashApi.mcpRunAuth(provider.mcpConfig, provider.credentials, resolvedAuthCommand, function (event, result) {
26082
+ if (result.error) {
26083
+ setAuthResult({
26084
+ success: false,
26085
+ message: result.message
26086
+ });
26087
+ } else {
26088
+ setAuthResult({
26089
+ success: true,
26090
+ message: "Authorized!"
26091
+ });
26092
+ }
26093
+ setIsAuthorizing(false);
26094
+ }, function (event, err) {
26095
+ setAuthResult({
26096
+ success: false,
26097
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Authorization failed"
26098
+ });
26099
+ setIsAuthorizing(false);
26100
+ });
26101
+ };
26012
26102
  var isFormMode = isEditing || isCreating;
26013
26103
 
26014
26104
  // ── MCP config info block (shared between read-only view and edit form) ──
@@ -26062,7 +26152,7 @@ var ProviderDetail = function ProviderDetail(_ref) {
26062
26152
 
26063
26153
  // ── Edit / Create form ──
26064
26154
  if (isFormMode) {
26065
- var _provider$mcpConfig;
26155
+ var _provider$mcpConfig2;
26066
26156
  return /*#__PURE__*/jsxs("div", {
26067
26157
  className: "flex flex-col flex-1 min-h-0",
26068
26158
  children: [/*#__PURE__*/jsxs("div", {
@@ -26159,7 +26249,7 @@ var ProviderDetail = function ProviderDetail(_ref) {
26159
26249
  className: "border-t border-white/10 pt-4",
26160
26250
  children: /*#__PURE__*/jsx("p", {
26161
26251
  className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
26162
- children: ((_provider$mcpConfig = provider.mcpConfig) === null || _provider$mcpConfig === void 0 ? void 0 : _provider$mcpConfig.transport) === "streamable_http" ? "Server Configuration" : "Authentication"
26252
+ children: ((_provider$mcpConfig2 = provider.mcpConfig) === null || _provider$mcpConfig2 === void 0 ? void 0 : _provider$mcpConfig2.transport) === "streamable_http" ? "Server Configuration" : "Authentication"
26163
26253
  })
26164
26254
  }), mcpFormFields.map(function (field) {
26165
26255
  return /*#__PURE__*/jsxs("div", {
@@ -26170,13 +26260,38 @@ var ProviderDetail = function ProviderDetail(_ref) {
26170
26260
  }), field.instructions && /*#__PURE__*/jsx("p", {
26171
26261
  className: "text-sm opacity-50",
26172
26262
  children: field.instructions
26173
- }), /*#__PURE__*/jsx(InputText, {
26174
- type: field.secret ? "password" : "text",
26175
- value: formCredentials[field.key] || "",
26176
- onChange: function onChange(value) {
26177
- return handleCredentialChange(field.key, value);
26178
- },
26179
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
26263
+ }), /*#__PURE__*/jsxs("div", {
26264
+ className: "flex gap-2",
26265
+ children: [/*#__PURE__*/jsx("div", {
26266
+ className: "flex-1",
26267
+ children: /*#__PURE__*/jsx(InputText, {
26268
+ type: field.secret ? "password" : "text",
26269
+ value: formCredentials[field.key] || "",
26270
+ onChange: function onChange(value) {
26271
+ return handleCredentialChange(field.key, value);
26272
+ },
26273
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
26274
+ })
26275
+ }), field.type === "file" && /*#__PURE__*/jsx("button", {
26276
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26277
+ var filepath;
26278
+ return _regeneratorRuntime.wrap(function (_context) {
26279
+ while (1) switch (_context.prev = _context.next) {
26280
+ case 0:
26281
+ _context.next = 1;
26282
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
26283
+ case 1:
26284
+ filepath = _context.sent;
26285
+ if (filepath) handleCredentialChange(field.key, filepath);
26286
+ case 2:
26287
+ case "end":
26288
+ return _context.stop();
26289
+ }
26290
+ }, _callee);
26291
+ })),
26292
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
26293
+ children: "Browse"
26294
+ })]
26180
26295
  })]
26181
26296
  }, field.key);
26182
26297
  })]
@@ -26296,6 +26411,16 @@ var ProviderDetail = function ProviderDetail(_ref) {
26296
26411
  })]
26297
26412
  })]
26298
26413
  })]
26414
+ }), authResult && /*#__PURE__*/jsx("div", {
26415
+ className: "p-3 rounded-lg text-sm ".concat(authResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
26416
+ children: /*#__PURE__*/jsxs("div", {
26417
+ className: "flex items-center gap-2",
26418
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26419
+ icon: authResult.success ? "circle-check" : "circle-exclamation"
26420
+ }), /*#__PURE__*/jsx("span", {
26421
+ children: authResult.message
26422
+ })]
26423
+ })
26299
26424
  }), testResult && /*#__PURE__*/jsxs("div", {
26300
26425
  className: "p-3 rounded-lg text-sm ".concat(testResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
26301
26426
  children: [/*#__PURE__*/jsxs("div", {
@@ -26324,7 +26449,11 @@ var ProviderDetail = function ProviderDetail(_ref) {
26324
26449
  })]
26325
26450
  }), /*#__PURE__*/jsxs("div", {
26326
26451
  className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
26327
- children: [isMcp && /*#__PURE__*/jsx(Button, {
26452
+ children: [isMcp && resolvedAuthCommand && /*#__PURE__*/jsx(Button, {
26453
+ title: isAuthorizing ? "Authorizing..." : "Authorize",
26454
+ onClick: handleAuthorize,
26455
+ size: "sm"
26456
+ }), isMcp && /*#__PURE__*/jsx(Button, {
26328
26457
  title: isTesting ? "Testing..." : "Test Connection",
26329
26458
  onClick: handleTestConnection,
26330
26459
  size: "sm"
@@ -27055,13 +27184,38 @@ var CustomMcpServerForm = function CustomMcpServerForm(_ref2) {
27055
27184
  children: [/*#__PURE__*/jsx(FormLabel, {
27056
27185
  label: field.displayName,
27057
27186
  required: field.required
27058
- }), /*#__PURE__*/jsx(InputText, {
27059
- type: field.secret ? "password" : "text",
27060
- value: credentialData[field.key] || "",
27061
- onChange: function onChange(value) {
27062
- return handleCredentialChange(field.key, value);
27063
- },
27064
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
27187
+ }), /*#__PURE__*/jsxs("div", {
27188
+ className: "flex gap-2",
27189
+ children: [/*#__PURE__*/jsx("div", {
27190
+ className: "flex-1",
27191
+ children: /*#__PURE__*/jsx(InputText, {
27192
+ type: field.secret ? "password" : "text",
27193
+ value: credentialData[field.key] || "",
27194
+ onChange: function onChange(value) {
27195
+ return handleCredentialChange(field.key, value);
27196
+ },
27197
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
27198
+ })
27199
+ }), field.type === "file" && /*#__PURE__*/jsx("button", {
27200
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27201
+ var filepath;
27202
+ return _regeneratorRuntime.wrap(function (_context) {
27203
+ while (1) switch (_context.prev = _context.next) {
27204
+ case 0:
27205
+ _context.next = 1;
27206
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
27207
+ case 1:
27208
+ filepath = _context.sent;
27209
+ if (filepath) handleCredentialChange(field.key, filepath);
27210
+ case 2:
27211
+ case "end":
27212
+ return _context.stop();
27213
+ }
27214
+ }, _callee);
27215
+ })),
27216
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27217
+ children: "Browse"
27218
+ })]
27065
27219
  }), formErrors[field.key] && /*#__PURE__*/jsx("p", {
27066
27220
  className: "text-sm text-red-400",
27067
27221
  children: formErrors[field.key]
@@ -27496,13 +27650,38 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27496
27650
  }), field.instructions && /*#__PURE__*/jsx("p", {
27497
27651
  className: "text-sm opacity-50",
27498
27652
  children: field.instructions
27499
- }), /*#__PURE__*/jsx(InputText, {
27500
- type: field.secret ? "password" : "text",
27501
- value: credentialData[field.key] || "",
27502
- onChange: function onChange(value) {
27503
- return handleCredentialChange(field.key, value);
27504
- },
27505
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
27653
+ }), /*#__PURE__*/jsxs("div", {
27654
+ className: "flex gap-2",
27655
+ children: [/*#__PURE__*/jsx("div", {
27656
+ className: "flex-1",
27657
+ children: /*#__PURE__*/jsx(InputText, {
27658
+ type: field.secret ? "password" : "text",
27659
+ value: credentialData[field.key] || "",
27660
+ onChange: function onChange(value) {
27661
+ return handleCredentialChange(field.key, value);
27662
+ },
27663
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
27664
+ })
27665
+ }), field.type === "file" && /*#__PURE__*/jsx("button", {
27666
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27667
+ var filepath;
27668
+ return _regeneratorRuntime.wrap(function (_context) {
27669
+ while (1) switch (_context.prev = _context.next) {
27670
+ case 0:
27671
+ _context.next = 1;
27672
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
27673
+ case 1:
27674
+ filepath = _context.sent;
27675
+ if (filepath) handleCredentialChange(field.key, filepath);
27676
+ case 2:
27677
+ case "end":
27678
+ return _context.stop();
27679
+ }
27680
+ }, _callee);
27681
+ })),
27682
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27683
+ children: "Browse"
27684
+ })]
27506
27685
  }), formErrors[field.key] && /*#__PURE__*/jsx("p", {
27507
27686
  className: "text-sm text-red-400",
27508
27687
  children: formErrors[field.key]
@@ -27641,46 +27820,58 @@ var ProvidersSection = function ProvidersSection(_ref) {
27641
27820
  var appContext = useContext(AppContext);
27642
27821
  var providers = (appContext === null || appContext === void 0 ? void 0 : appContext.providers) || {};
27643
27822
  var refreshProviders = appContext === null || appContext === void 0 ? void 0 : appContext.refreshProviders;
27644
- var _useState = useState("credentials"),
27823
+
27824
+ // Load MCP catalog for authCommand lookups
27825
+ var _useState = useState([]),
27645
27826
  _useState2 = _slicedToArray(_useState, 2),
27646
- providerTab = _useState2[0],
27647
- setProviderTab = _useState2[1];
27648
- var _useState3 = useState(null),
27827
+ catalog = _useState2[0],
27828
+ setCatalog = _useState2[1];
27829
+ useEffect(function () {
27830
+ if (!dashApi) return;
27831
+ dashApi.mcpGetCatalog(function (event, result) {
27832
+ if (result !== null && result !== void 0 && result.catalog) setCatalog(result.catalog);
27833
+ }, function () {});
27834
+ }, [dashApi]);
27835
+ var _useState3 = useState("credentials"),
27649
27836
  _useState4 = _slicedToArray(_useState3, 2),
27650
- selectedName = _useState4[0],
27651
- setSelectedName = _useState4[1];
27652
- var _useState5 = useState(false),
27837
+ providerTab = _useState4[0],
27838
+ setProviderTab = _useState4[1];
27839
+ var _useState5 = useState(null),
27653
27840
  _useState6 = _slicedToArray(_useState5, 2),
27654
- isCreating = _useState6[0],
27655
- setIsCreating = _useState6[1];
27841
+ selectedName = _useState6[0],
27842
+ setSelectedName = _useState6[1];
27656
27843
  var _useState7 = useState(false),
27657
27844
  _useState8 = _slicedToArray(_useState7, 2),
27658
- isEditing = _useState8[0],
27659
- setIsEditing = _useState8[1];
27660
- var _useState9 = useState(""),
27845
+ isCreating = _useState8[0],
27846
+ setIsCreating = _useState8[1];
27847
+ var _useState9 = useState(false),
27661
27848
  _useState0 = _slicedToArray(_useState9, 2),
27662
- formName = _useState0[0],
27663
- setFormName = _useState0[1];
27849
+ isEditing = _useState0[0],
27850
+ setIsEditing = _useState0[1];
27664
27851
  var _useState1 = useState(""),
27665
27852
  _useState10 = _slicedToArray(_useState1, 2),
27666
- formType = _useState10[0],
27667
- setFormType = _useState10[1];
27668
- var _useState11 = useState({}),
27853
+ formName = _useState10[0],
27854
+ setFormName = _useState10[1];
27855
+ var _useState11 = useState(""),
27669
27856
  _useState12 = _slicedToArray(_useState11, 2),
27670
- formCredentials = _useState12[0],
27671
- setFormCredentials = _useState12[1];
27672
- var _useState13 = useState(null),
27857
+ formType = _useState12[0],
27858
+ setFormType = _useState12[1];
27859
+ var _useState13 = useState({}),
27673
27860
  _useState14 = _slicedToArray(_useState13, 2),
27674
- deleteTarget = _useState14[0],
27675
- setDeleteTarget = _useState14[1];
27676
- var _useState15 = useState(false),
27861
+ formCredentials = _useState14[0],
27862
+ setFormCredentials = _useState14[1];
27863
+ var _useState15 = useState(null),
27677
27864
  _useState16 = _slicedToArray(_useState15, 2),
27678
- isAddingMcp = _useState16[0],
27679
- setIsAddingMcp = _useState16[1];
27865
+ deleteTarget = _useState16[0],
27866
+ setDeleteTarget = _useState16[1];
27680
27867
  var _useState17 = useState(false),
27681
27868
  _useState18 = _slicedToArray(_useState17, 2),
27682
- isEditingMcp = _useState18[0],
27683
- setIsEditingMcp = _useState18[1];
27869
+ isAddingMcp = _useState18[0],
27870
+ setIsAddingMcp = _useState18[1];
27871
+ var _useState19 = useState(false),
27872
+ _useState20 = _slicedToArray(_useState19, 2),
27873
+ isEditingMcp = _useState20[0],
27874
+ setIsEditingMcp = _useState20[1];
27684
27875
 
27685
27876
  // Row ID counter for env/header rows in MCP edit mode
27686
27877
  var nextRowIdRef = useRef(0);
@@ -27955,6 +28146,10 @@ var ProvidersSection = function ProvidersSection(_ref) {
27955
28146
  }
27956
28147
  });
27957
28148
  } else if (selectedName && selectedProvider) {
28149
+ // Look up authCommand from the catalog for this provider type
28150
+ var catalogEntry = catalog.find(function (entry) {
28151
+ return entry.id === selectedProvider.type;
28152
+ });
27958
28153
  detailContent = /*#__PURE__*/jsx(ProviderDetail, {
27959
28154
  providerName: selectedName,
27960
28155
  provider: selectedProvider,
@@ -27970,7 +28165,8 @@ var ProvidersSection = function ProvidersSection(_ref) {
27970
28165
  onStartEdit: handleStartEdit,
27971
28166
  onDelete: function onDelete(name) {
27972
28167
  return setDeleteTarget(name);
27973
- }
28168
+ },
28169
+ catalogAuthCommand: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.authCommand) || null
27974
28170
  });
27975
28171
  }
27976
28172
  return /*#__PURE__*/jsxs(Fragment, {
@@ -33759,5 +33955,5 @@ var WorkspaceMenu = function WorkspaceMenu(_ref) {
33759
33955
 
33760
33956
  ComponentManager.registerContainerTypes(LayoutContainer, LayoutGridContainer);
33761
33957
 
33762
- export { ALGOLIA_ANALYTICS_FOR_QUERY, ALGOLIA_ANALYTICS_FOR_QUERY_COMPLETE, ALGOLIA_ANALYTICS_FOR_QUERY_ERROR, ALGOLIA_LIST_INDICES, ALGOLIA_LIST_INDICES_COMPLETE, ALGOLIA_LIST_INDICES_ERROR, AVAILABLE_COLORS, AddMenuItemModal, AdvancedMcpConfig, AppContext, AppSettingsModal, AppThemeScope, AppWrapper, CHOOSE_FILE, CHOOSE_FILE_COMPLETE, CHOOSE_FILE_ERROR, ColorModel, ComponentConfigModel, ComponentManager, ContextModel, DATA_JSON_TO_CSV_FILE, DATA_JSON_TO_CSV_FILE_COMPLETE, DATA_JSON_TO_CSV_FILE_ERROR, DATA_JSON_TO_CSV_STRING, DATA_JSON_TO_CSV_STRING_COMPLETE, DATA_JSON_TO_CSV_STRING_ERROR, DATA_READ_FROM_FILE, DATA_READ_FROM_FILE_COMPLETE, DATA_READ_FROM_FILE_ERROR, DATA_SAVE_TO_FILE, DATA_SAVE_TO_FILE_COMPLETE, DATA_SAVE_TO_FILE_ERROR, DashCommandPalette, DashNavbar, DashSidebar, DashTabBar, DashboardStage as Dashboard, DashboardApi, DashboardContext, DashboardFooter, DashboardHeader, DashboardMenuItem, DashboardModel, DashboardMonitor, DashboardPublisher, DashboardStage, DashboardThemeProvider, DashboardWrapper, ElectronDashboardApi, ErrorBoundary, ExternalWidget, GRID_CELL_WIDGET_TYPE, HARMONY_STRATEGIES, LAYOUT_LIST, LAYOUT_LIST_COMPLETE, LAYOUT_LIST_ERROR, LAYOUT_SAVE, LAYOUT_SAVE_COMPLETE, LAYOUT_SAVE_ERROR, Layout, LayoutBuilder, LayoutBuilderAddItemModal, LayoutBuilderConfigContainerMenuItem, LayoutBuilderConfigMenuItem, LayoutBuilderConfigModal, LayoutBuilderEditItemModal, LayoutBuilderEventModal, LayoutBuilderGridItem, LayoutContainer, LayoutDragBuilder, LayoutDragBuilderEdit, LayoutGridContainer, LayoutManagerModal, LayoutModel, LayoutQuickAddMenu, MCP_CALL_TOOL_COMPLETE, MCP_CALL_TOOL_ERROR, MCP_GET_CATALOG_COMPLETE, MCP_GET_CATALOG_ERROR, MCP_LIST_RESOURCES_COMPLETE, MCP_LIST_RESOURCES_ERROR, MCP_LIST_TOOLS_COMPLETE, MCP_LIST_TOOLS_ERROR, MCP_READ_RESOURCE_COMPLETE, MCP_READ_RESOURCE_ERROR, MCP_SERVER_STATUS_COMPLETE, MCP_SERVER_STATUS_ERROR, MCP_START_SERVER_COMPLETE, MCP_START_SERVER_ERROR, MCP_STOP_SERVER_COMPLETE, MCP_STOP_SERVER_ERROR, MENU_ITEMS_DELETE, MENU_ITEMS_DELETE_COMPLETE, MENU_ITEMS_DELETE_ERROR, MENU_ITEMS_LIST, MENU_ITEMS_LIST_COMPLETE, MENU_ITEMS_LIST_ERROR, MENU_ITEMS_SAVE, MENU_ITEMS_SAVE_COMPLETE, MENU_ITEMS_SAVE_ERROR, MainMenu, MainMenuItem, MainMenuSection, McpServerPicker, MenuItemModel, MenuSlideOverlay, MergeCellsModal, MissingProviderPrompt, MockDashboardApi, PROVIDER_DELETE_COMPLETE, PROVIDER_DELETE_ERROR, PROVIDER_GET_COMPLETE, PROVIDER_GET_ERROR, PROVIDER_LIST_COMPLETE, PROVIDER_LIST_ERROR, PROVIDER_SAVE_COMPLETE, PROVIDER_SAVE_ERROR, PanelCode, PanelEditItem, PanelEditItemHandlers, ProviderContext, ProviderErrorBoundary, ProviderForm, ProviderSelector, SECURE_STORAGE_ENCRYPT_STRING, SECURE_STORAGE_ENCRYPT_STRING_COMPLETE, SECURE_STORAGE_ENCRYPT_STRING_ERROR, SECURE_STORE_ENCRYPTION_CHECK, SECURE_STORE_ENCRYPTION_CHECK_COMPLETE, SECURE_STORE_ENCRYPTION_CHECK_ERROR, SECURE_STORE_GET_DATA, SECURE_STORE_GET_DATA_COMPLETE, SECURE_STORE_GET_DATA_ERROR, SECURE_STORE_SET_DATA, SECURE_STORE_SET_DATA_COMPLETE, SECURE_STORE_SET_DATA_ERROR, SETTINGS_GET, SETTINGS_GET_COMPLETE, SETTINGS_GET_ERROR, SETTINGS_SAVE, SETTINGS_SAVE_COMPLETE, SETTINGS_SAVE_ERROR, SIDEBAR_WIDGET_TYPE, SettingsModel, SideMenu, SplitCellModal, THEME_DELETE, THEME_DELETE_COMPLETE, THEME_DELETE_ERROR, THEME_LIST, THEME_LIST_COMPLETE, THEME_LIST_ERROR, THEME_SAVE, THEME_SAVE_COMPLETE, THEME_SAVE_ERROR, ThemeApi, ThemeManagerModal, ThemeModel, ThemeWrapper, WORKSPACE_DELETE, WORKSPACE_DELETE_COMPLETE, WORKSPACE_DELETE_ERROR, WORKSPACE_LIST, WORKSPACE_LIST_COMPLETE, WORKSPACE_LIST_ERROR, WORKSPACE_SAVE, WORKSPACE_SAVE_COMPLETE, WORKSPACE_SAVE_ERROR, WebDashboardApi, Widget, WidgetApi, WidgetConfigPanel, WidgetContext, WidgetFactory, WidgetPopoutStage, WidgetProviderWrapper, WidgetSidebar, Workspace, WorkspaceContext, WorkspaceFooter, WorkspaceMenu, WorkspaceModel, addChildToLayoutItem, addItemToItemLayout, buildMcpConfigFromOverrides, canHaveChildren, changeDirectionForLayoutItem, createProviderRegistry, deriveFormFields, envMappingToRows, evaluateBundle, extractWidgetConfigs, formStateToMcpJson, formatFieldName, generateCustomTheme, generateHarmonyTheme, generateRandomTheme, generateThemeName, getBorderStyle, getChildrenForLayoutItem, getComponentInLayout, getContainerBorderColor, getContainerColor, getIndexOfLayoutChildrenForItem, getIndexOfLayoutItem, getLayoutItemById, getLayoutItemForWorkspace, getNearestParentWorkspace, getNextHighestId, getNextHighestItemInLayout, getNextHighestOrder, getNextHighestParentId, getNextLowestItemInLayout, getParentForLayoutItem, getParentWorkspaceForItem, getThemePresets, getWidgetsForWorkspace, getWorkspacesForWorkspace, headerTemplateToRows, isContainer, isLikelySecret, isMaxOrderForItem, isMinOrderForItem, isWidget, isWidgetResolvable, isWorkspace, layoutItemHasWorkspaceAsChild, loadWidgetBundle, mcpJsonToFormState, numChildrenForLayout, removeItemFromLayout, renderComponent, renderGridLayout, renderGridLayoutFlow, _renderLayout as renderLayout, renderLayoutMenu, replaceItemInLayout, resolveIcon, setHostModules, traverseParentTree, updateLayoutItem, updateParentForItem, useDashboard, useMcpProvider, useProvider, useProviderClient, useWidgetEvents, useWidgetProviders, validateCellMerge, validateGridCell, validateGridPlacement, validateWidgetPlacement, withProviderDetection };
33958
+ export { ALGOLIA_ANALYTICS_FOR_QUERY, ALGOLIA_ANALYTICS_FOR_QUERY_COMPLETE, ALGOLIA_ANALYTICS_FOR_QUERY_ERROR, ALGOLIA_LIST_INDICES, ALGOLIA_LIST_INDICES_COMPLETE, ALGOLIA_LIST_INDICES_ERROR, AVAILABLE_COLORS, AddMenuItemModal, AdvancedMcpConfig, AppContext, AppSettingsModal, AppThemeScope, AppWrapper, CHOOSE_FILE, CHOOSE_FILE_COMPLETE, CHOOSE_FILE_ERROR, ColorModel, ComponentConfigModel, ComponentManager, ContextModel, DATA_JSON_TO_CSV_FILE, DATA_JSON_TO_CSV_FILE_COMPLETE, DATA_JSON_TO_CSV_FILE_ERROR, DATA_JSON_TO_CSV_STRING, DATA_JSON_TO_CSV_STRING_COMPLETE, DATA_JSON_TO_CSV_STRING_ERROR, DATA_READ_FROM_FILE, DATA_READ_FROM_FILE_COMPLETE, DATA_READ_FROM_FILE_ERROR, DATA_SAVE_TO_FILE, DATA_SAVE_TO_FILE_COMPLETE, DATA_SAVE_TO_FILE_ERROR, DashCommandPalette, DashNavbar, DashSidebar, DashTabBar, DashboardStage as Dashboard, DashboardApi, DashboardContext, DashboardFooter, DashboardHeader, DashboardMenuItem, DashboardModel, DashboardMonitor, DashboardPublisher, DashboardStage, DashboardThemeProvider, DashboardWrapper, ElectronDashboardApi, ErrorBoundary, ExternalWidget, GRID_CELL_WIDGET_TYPE, HARMONY_STRATEGIES, LAYOUT_LIST, LAYOUT_LIST_COMPLETE, LAYOUT_LIST_ERROR, LAYOUT_SAVE, LAYOUT_SAVE_COMPLETE, LAYOUT_SAVE_ERROR, Layout, LayoutBuilder, LayoutBuilderAddItemModal, LayoutBuilderConfigContainerMenuItem, LayoutBuilderConfigMenuItem, LayoutBuilderConfigModal, LayoutBuilderEditItemModal, LayoutBuilderEventModal, LayoutBuilderGridItem, LayoutContainer, LayoutDragBuilder, LayoutDragBuilderEdit, LayoutGridContainer, LayoutManagerModal, LayoutModel, LayoutQuickAddMenu, MCP_CALL_TOOL_COMPLETE, MCP_CALL_TOOL_ERROR, MCP_GET_CATALOG_COMPLETE, MCP_GET_CATALOG_ERROR, MCP_LIST_RESOURCES_COMPLETE, MCP_LIST_RESOURCES_ERROR, MCP_LIST_TOOLS_COMPLETE, MCP_LIST_TOOLS_ERROR, MCP_READ_RESOURCE_COMPLETE, MCP_READ_RESOURCE_ERROR, MCP_RUN_AUTH_COMPLETE, MCP_RUN_AUTH_ERROR, MCP_SERVER_STATUS_COMPLETE, MCP_SERVER_STATUS_ERROR, MCP_START_SERVER_COMPLETE, MCP_START_SERVER_ERROR, MCP_STOP_SERVER_COMPLETE, MCP_STOP_SERVER_ERROR, MENU_ITEMS_DELETE, MENU_ITEMS_DELETE_COMPLETE, MENU_ITEMS_DELETE_ERROR, MENU_ITEMS_LIST, MENU_ITEMS_LIST_COMPLETE, MENU_ITEMS_LIST_ERROR, MENU_ITEMS_SAVE, MENU_ITEMS_SAVE_COMPLETE, MENU_ITEMS_SAVE_ERROR, MainMenu, MainMenuItem, MainMenuSection, McpServerPicker, MenuItemModel, MenuSlideOverlay, MergeCellsModal, MissingProviderPrompt, MockDashboardApi, PROVIDER_DELETE_COMPLETE, PROVIDER_DELETE_ERROR, PROVIDER_GET_COMPLETE, PROVIDER_GET_ERROR, PROVIDER_LIST_COMPLETE, PROVIDER_LIST_ERROR, PROVIDER_SAVE_COMPLETE, PROVIDER_SAVE_ERROR, PanelCode, PanelEditItem, PanelEditItemHandlers, ProviderContext, ProviderErrorBoundary, ProviderForm, ProviderSelector, SECURE_STORAGE_ENCRYPT_STRING, SECURE_STORAGE_ENCRYPT_STRING_COMPLETE, SECURE_STORAGE_ENCRYPT_STRING_ERROR, SECURE_STORE_ENCRYPTION_CHECK, SECURE_STORE_ENCRYPTION_CHECK_COMPLETE, SECURE_STORE_ENCRYPTION_CHECK_ERROR, SECURE_STORE_GET_DATA, SECURE_STORE_GET_DATA_COMPLETE, SECURE_STORE_GET_DATA_ERROR, SECURE_STORE_SET_DATA, SECURE_STORE_SET_DATA_COMPLETE, SECURE_STORE_SET_DATA_ERROR, SETTINGS_GET, SETTINGS_GET_COMPLETE, SETTINGS_GET_ERROR, SETTINGS_SAVE, SETTINGS_SAVE_COMPLETE, SETTINGS_SAVE_ERROR, SIDEBAR_WIDGET_TYPE, SettingsModel, SideMenu, SplitCellModal, THEME_DELETE, THEME_DELETE_COMPLETE, THEME_DELETE_ERROR, THEME_LIST, THEME_LIST_COMPLETE, THEME_LIST_ERROR, THEME_SAVE, THEME_SAVE_COMPLETE, THEME_SAVE_ERROR, ThemeApi, ThemeManagerModal, ThemeModel, ThemeWrapper, WORKSPACE_DELETE, WORKSPACE_DELETE_COMPLETE, WORKSPACE_DELETE_ERROR, WORKSPACE_LIST, WORKSPACE_LIST_COMPLETE, WORKSPACE_LIST_ERROR, WORKSPACE_SAVE, WORKSPACE_SAVE_COMPLETE, WORKSPACE_SAVE_ERROR, WebDashboardApi, Widget, WidgetApi, WidgetConfigPanel, WidgetContext, WidgetFactory, WidgetPopoutStage, WidgetProviderWrapper, WidgetSidebar, Workspace, WorkspaceContext, WorkspaceFooter, WorkspaceMenu, WorkspaceModel, addChildToLayoutItem, addItemToItemLayout, buildMcpConfigFromOverrides, canHaveChildren, changeDirectionForLayoutItem, createProviderRegistry, deriveFormFields, envMappingToRows, evaluateBundle, extractWidgetConfigs, formStateToMcpJson, formatFieldName, generateCustomTheme, generateHarmonyTheme, generateRandomTheme, generateThemeName, getBorderStyle, getChildrenForLayoutItem, getComponentInLayout, getContainerBorderColor, getContainerColor, getIndexOfLayoutChildrenForItem, getIndexOfLayoutItem, getLayoutItemById, getLayoutItemForWorkspace, getNearestParentWorkspace, getNextHighestId, getNextHighestItemInLayout, getNextHighestOrder, getNextHighestParentId, getNextLowestItemInLayout, getParentForLayoutItem, getParentWorkspaceForItem, getThemePresets, getWidgetsForWorkspace, getWorkspacesForWorkspace, headerTemplateToRows, isContainer, isLikelySecret, isMaxOrderForItem, isMinOrderForItem, isWidget, isWidgetResolvable, isWorkspace, layoutItemHasWorkspaceAsChild, loadWidgetBundle, mcpJsonToFormState, numChildrenForLayout, removeItemFromLayout, renderComponent, renderGridLayout, renderGridLayoutFlow, _renderLayout as renderLayout, renderLayoutMenu, replaceItemInLayout, resolveIcon, setHostModules, traverseParentTree, updateLayoutItem, updateParentForItem, useDashboard, useMcpProvider, useProvider, useProviderClient, useWidgetEvents, useWidgetProviders, validateCellMerge, validateGridCell, validateGridPlacement, validateWidgetPlacement, withProviderDetection };
33763
33959
  //# sourceMappingURL=index.esm.js.map