@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.js CHANGED
@@ -691,6 +691,8 @@ var MCP_SERVER_STATUS_COMPLETE = "mcp:server-status:complete";
691
691
  var MCP_SERVER_STATUS_ERROR = "mcp:server-status:error";
692
692
  var MCP_GET_CATALOG_COMPLETE = "mcp:get-catalog:complete";
693
693
  var MCP_GET_CATALOG_ERROR = "mcp:get-catalog:error";
694
+ var MCP_RUN_AUTH_COMPLETE = "mcp:run-auth:complete";
695
+ var MCP_RUN_AUTH_ERROR = "mcp:run-auth:error";
694
696
 
695
697
  var DATA_JSON_TO_CSV_FILE = "data-json-to-csv-file";
696
698
  var DATA_JSON_TO_CSV_FILE_COMPLETE = "data-json-to-csv-file-complete";
@@ -799,6 +801,8 @@ var apiEvents = /*#__PURE__*/Object.freeze({
799
801
  MCP_LIST_TOOLS_ERROR: MCP_LIST_TOOLS_ERROR,
800
802
  MCP_READ_RESOURCE_COMPLETE: MCP_READ_RESOURCE_COMPLETE,
801
803
  MCP_READ_RESOURCE_ERROR: MCP_READ_RESOURCE_ERROR,
804
+ MCP_RUN_AUTH_COMPLETE: MCP_RUN_AUTH_COMPLETE,
805
+ MCP_RUN_AUTH_ERROR: MCP_RUN_AUTH_ERROR,
802
806
  MCP_SERVER_STATUS_COMPLETE: MCP_SERVER_STATUS_COMPLETE,
803
807
  MCP_SERVER_STATUS_ERROR: MCP_SERVER_STATUS_ERROR,
804
808
  MCP_START_SERVER_COMPLETE: MCP_START_SERVER_COMPLETE,
@@ -1497,6 +1501,27 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
1497
1501
  return false;
1498
1502
  }
1499
1503
  }
1504
+ }, {
1505
+ key: "mcpRunAuth",
1506
+ value: function mcpRunAuth(mcpConfig, credentials, authCommand, onSuccess, onError) {
1507
+ var _this26 = this;
1508
+ if (this.api !== null) {
1509
+ try {
1510
+ this.api.mcp.runAuth(mcpConfig, credentials, authCommand).then(function (result) {
1511
+ onSuccess(_this26.events.MCP_RUN_AUTH_COMPLETE, result);
1512
+ })["catch"](function (error) {
1513
+ onError(_this26.events.MCP_RUN_AUTH_ERROR, error);
1514
+ });
1515
+ return true;
1516
+ } catch (e) {
1517
+ onError(this.events.MCP_RUN_AUTH_ERROR, e);
1518
+ return false;
1519
+ }
1520
+ } else {
1521
+ onError(this.events.MCP_RUN_AUTH_ERROR, new Error("No Api found"));
1522
+ return false;
1523
+ }
1524
+ }
1500
1525
  }]);
1501
1526
  }();
1502
1527
 
@@ -19501,7 +19526,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
19501
19526
  * even when multiple hook instances call connect() simultaneously.
19502
19527
  */
19503
19528
  var connect = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
19504
- var cached, result, state, connectPromise, _result, _t, _t2;
19529
+ var cached, statusResult, result, state, connectPromise, _result, _t2, _t3;
19505
19530
  return _regeneratorRuntime.wrap(function (_context) {
19506
19531
  while (1) switch (_context.prev = _context.next) {
19507
19532
  case 0:
@@ -19532,65 +19557,90 @@ var useMcpProvider = function useMcpProvider(providerType) {
19532
19557
  setError("Provider \"".concat(selectedProviderName, "\" has no MCP configuration"));
19533
19558
  return _context.abrupt("return");
19534
19559
  case 4:
19535
- // 1. Already connected at module level? Apply cached result, skip IPC
19560
+ // 1. Already connected at module level? Verify with main process before trusting cache.
19561
+ // The server may have been stopped externally (e.g., Test Connection in settings).
19536
19562
  cached = serverStates.get(selectedProviderName);
19537
19563
  if (!(cached && cached.status === "connected")) {
19538
- _context.next = 5;
19564
+ _context.next = 9;
19565
+ break;
19566
+ }
19567
+ _context.prev = 5;
19568
+ _context.next = 6;
19569
+ return new Promise(function (resolve, reject) {
19570
+ dashApi.mcpGetServerStatus(selectedProviderName, function (event, result) {
19571
+ return resolve(result);
19572
+ }, function (event, err) {
19573
+ return reject(err);
19574
+ });
19575
+ });
19576
+ case 6:
19577
+ statusResult = _context.sent;
19578
+ if (!((statusResult === null || statusResult === void 0 ? void 0 : statusResult.status) === "connected")) {
19579
+ _context.next = 7;
19539
19580
  break;
19540
19581
  }
19541
19582
  cached.consumerCount++;
19542
19583
  applyResult(cached);
19543
19584
  return _context.abrupt("return");
19544
- case 5:
19585
+ case 7:
19586
+ // Server was stopped externally — clear stale cache and reconnect
19587
+ serverStates["delete"](selectedProviderName);
19588
+ _context.next = 9;
19589
+ break;
19590
+ case 8:
19591
+ _context.prev = 8;
19592
+ _context["catch"](5);
19593
+ serverStates["delete"](selectedProviderName);
19594
+ case 9:
19545
19595
  setIsConnecting(true);
19546
19596
  setError(null);
19547
19597
 
19548
19598
  // 2. Another hook instance already connecting? Piggyback on its promise
19549
19599
  if (!pendingConnects.has(selectedProviderName)) {
19550
- _context.next = 13;
19600
+ _context.next = 17;
19551
19601
  break;
19552
19602
  }
19553
- _context.prev = 6;
19554
- _context.next = 7;
19603
+ _context.prev = 10;
19604
+ _context.next = 11;
19555
19605
  return pendingConnects.get(selectedProviderName);
19556
- case 7:
19606
+ case 11:
19557
19607
  result = _context.sent;
19558
19608
  if (mountedRef.current) {
19559
- _context.next = 8;
19609
+ _context.next = 12;
19560
19610
  break;
19561
19611
  }
19562
19612
  return _context.abrupt("return");
19563
- case 8:
19613
+ case 12:
19564
19614
  if (!result.error) {
19565
- _context.next = 9;
19615
+ _context.next = 13;
19566
19616
  break;
19567
19617
  }
19568
19618
  setError(result.message);
19569
19619
  setIsConnecting(false);
19570
19620
  setStatus("error");
19571
19621
  return _context.abrupt("return");
19572
- case 9:
19622
+ case 13:
19573
19623
  // Increment consumer count and apply
19574
19624
  state = serverStates.get(selectedProviderName);
19575
19625
  if (state) state.consumerCount++;
19576
19626
  applyResult(result);
19577
- _context.next = 12;
19627
+ _context.next = 16;
19578
19628
  break;
19579
- case 10:
19580
- _context.prev = 10;
19581
- _t = _context["catch"](6);
19629
+ case 14:
19630
+ _context.prev = 14;
19631
+ _t2 = _context["catch"](10);
19582
19632
  if (mountedRef.current) {
19583
- _context.next = 11;
19633
+ _context.next = 15;
19584
19634
  break;
19585
19635
  }
19586
19636
  return _context.abrupt("return");
19587
- case 11:
19588
- setError((_t === null || _t === void 0 ? void 0 : _t.message) || "Failed to connect to MCP server");
19637
+ case 15:
19638
+ setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || "Failed to connect to MCP server");
19589
19639
  setIsConnecting(false);
19590
19640
  setStatus("error");
19591
- case 12:
19641
+ case 16:
19592
19642
  return _context.abrupt("return");
19593
- case 13:
19643
+ case 17:
19594
19644
  // 3. First caller — fire the IPC call and share the promise
19595
19645
  connectPromise = new Promise(function (resolve, reject) {
19596
19646
  dashApi.mcpStartServer(selectedProviderName, provider.mcpConfig, provider.credentials, function (event, result) {
@@ -19626,46 +19676,46 @@ var useMcpProvider = function useMcpProvider(providerType) {
19626
19676
  });
19627
19677
  });
19628
19678
  pendingConnects.set(selectedProviderName, connectPromise);
19629
- _context.prev = 14;
19630
- _context.next = 15;
19679
+ _context.prev = 18;
19680
+ _context.next = 19;
19631
19681
  return connectPromise;
19632
- case 15:
19682
+ case 19:
19633
19683
  _result = _context.sent;
19634
19684
  if (mountedRef.current) {
19635
- _context.next = 16;
19685
+ _context.next = 20;
19636
19686
  break;
19637
19687
  }
19638
19688
  return _context.abrupt("return");
19639
- case 16:
19689
+ case 20:
19640
19690
  if (!_result.error) {
19641
- _context.next = 17;
19691
+ _context.next = 21;
19642
19692
  break;
19643
19693
  }
19644
19694
  setError(_result.message);
19645
19695
  setIsConnecting(false);
19646
19696
  setStatus("error");
19647
19697
  return _context.abrupt("return");
19648
- case 17:
19698
+ case 21:
19649
19699
  applyResult(_result);
19650
- _context.next = 20;
19700
+ _context.next = 24;
19651
19701
  break;
19652
- case 18:
19653
- _context.prev = 18;
19654
- _t2 = _context["catch"](14);
19702
+ case 22:
19703
+ _context.prev = 22;
19704
+ _t3 = _context["catch"](18);
19655
19705
  if (mountedRef.current) {
19656
- _context.next = 19;
19706
+ _context.next = 23;
19657
19707
  break;
19658
19708
  }
19659
19709
  return _context.abrupt("return");
19660
- case 19:
19661
- setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || "Failed to connect to MCP server");
19710
+ case 23:
19711
+ setError((_t3 === null || _t3 === void 0 ? void 0 : _t3.message) || "Failed to connect to MCP server");
19662
19712
  setIsConnecting(false);
19663
19713
  setStatus("error");
19664
- case 20:
19714
+ case 24:
19665
19715
  case "end":
19666
19716
  return _context.stop();
19667
19717
  }
19668
- }, _callee, null, [[6, 10], [14, 18]]);
19718
+ }, _callee, null, [[5, 8], [10, 14], [18, 22]]);
19669
19719
  })), [dashApi, provider, providerType, selectedProviderName, applyResult]);
19670
19720
 
19671
19721
  /**
@@ -25868,7 +25918,7 @@ var FoldersSection = function FoldersSection(_ref) {
25868
25918
  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; }
25869
25919
  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; }
25870
25920
  var ProviderDetail = function ProviderDetail(_ref) {
25871
- var _testResult$tools;
25921
+ var _provider$mcpConfig, _testResult$tools;
25872
25922
  var _ref$providerName = _ref.providerName,
25873
25923
  providerName = _ref$providerName === void 0 ? null : _ref$providerName,
25874
25924
  _ref$provider = _ref.provider,
@@ -25890,7 +25940,9 @@ var ProviderDetail = function ProviderDetail(_ref) {
25890
25940
  onCancelEdit = _ref.onCancelEdit,
25891
25941
  onStartEdit = _ref.onStartEdit,
25892
25942
  onCreate = _ref.onCreate,
25893
- onDelete = _ref.onDelete;
25943
+ onDelete = _ref.onDelete,
25944
+ _ref$catalogAuthComma = _ref.catalogAuthCommand,
25945
+ catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma;
25894
25946
  var appContext = React.useContext(AppContext);
25895
25947
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
25896
25948
  var isMcp = (provider === null || provider === void 0 ? void 0 : provider.providerClass) === "mcp";
@@ -25905,6 +25957,19 @@ var ProviderDetail = function ProviderDetail(_ref) {
25905
25957
  testResult = _useState4[0],
25906
25958
  setTestResult = _useState4[1];
25907
25959
 
25960
+ // MCP auth state
25961
+ var _useState5 = React.useState(false),
25962
+ _useState6 = _slicedToArray(_useState5, 2),
25963
+ isAuthorizing = _useState6[0],
25964
+ setIsAuthorizing = _useState6[1];
25965
+ var _useState7 = React.useState(null),
25966
+ _useState8 = _slicedToArray(_useState7, 2),
25967
+ authResult = _useState8[0],
25968
+ setAuthResult = _useState8[1];
25969
+
25970
+ // Resolve authCommand: provider.mcpConfig.authCommand > catalogAuthCommand prop
25971
+ var resolvedAuthCommand = (provider === null || provider === void 0 || (_provider$mcpConfig = provider.mcpConfig) === null || _provider$mcpConfig === void 0 ? void 0 : _provider$mcpConfig.authCommand) || catalogAuthCommand || null;
25972
+
25908
25973
  // Derive credential fields for MCP providers in edit mode
25909
25974
  var mcpFormFields = React.useMemo(function () {
25910
25975
  if (!isMcp || !(provider !== null && provider !== void 0 && provider.mcpConfig)) return [];
@@ -25918,14 +25983,14 @@ var ProviderDetail = function ProviderDetail(_ref) {
25918
25983
  }, [isMcp, provider]);
25919
25984
 
25920
25985
  // Dynamic credential fields for create mode
25921
- var _useState5 = React.useState(isCreating ? [{
25986
+ var _useState9 = React.useState(isCreating ? [{
25922
25987
  id: "default_apiKey",
25923
25988
  key: "apiKey",
25924
25989
  secret: true
25925
25990
  }] : []),
25926
- _useState6 = _slicedToArray(_useState5, 2),
25927
- credentialFields = _useState6[0],
25928
- setCredentialFields = _useState6[1];
25991
+ _useState0 = _slicedToArray(_useState9, 2),
25992
+ credentialFields = _useState0[0],
25993
+ setCredentialFields = _useState0[1];
25929
25994
  var fieldIdRef = React.useRef(0);
25930
25995
  var handleFieldKeyChange = function handleFieldKeyChange(id, newKey) {
25931
25996
  setCredentialFields(function (prev) {
@@ -26028,6 +26093,31 @@ var ProviderDetail = function ProviderDetail(_ref) {
26028
26093
  setIsTesting(false);
26029
26094
  });
26030
26095
  };
26096
+ var handleAuthorize = function handleAuthorize() {
26097
+ if (!dashApi || !(provider !== null && provider !== void 0 && provider.mcpConfig) || !resolvedAuthCommand) return;
26098
+ setIsAuthorizing(true);
26099
+ setAuthResult(null);
26100
+ dashApi.mcpRunAuth(provider.mcpConfig, provider.credentials, resolvedAuthCommand, function (event, result) {
26101
+ if (result.error) {
26102
+ setAuthResult({
26103
+ success: false,
26104
+ message: result.message
26105
+ });
26106
+ } else {
26107
+ setAuthResult({
26108
+ success: true,
26109
+ message: "Authorized!"
26110
+ });
26111
+ }
26112
+ setIsAuthorizing(false);
26113
+ }, function (event, err) {
26114
+ setAuthResult({
26115
+ success: false,
26116
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Authorization failed"
26117
+ });
26118
+ setIsAuthorizing(false);
26119
+ });
26120
+ };
26031
26121
  var isFormMode = isEditing || isCreating;
26032
26122
 
26033
26123
  // ── MCP config info block (shared between read-only view and edit form) ──
@@ -26081,7 +26171,7 @@ var ProviderDetail = function ProviderDetail(_ref) {
26081
26171
 
26082
26172
  // ── Edit / Create form ──
26083
26173
  if (isFormMode) {
26084
- var _provider$mcpConfig;
26174
+ var _provider$mcpConfig2;
26085
26175
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
26086
26176
  className: "flex flex-col flex-1 min-h-0",
26087
26177
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -26178,7 +26268,7 @@ var ProviderDetail = function ProviderDetail(_ref) {
26178
26268
  className: "border-t border-white/10 pt-4",
26179
26269
  children: /*#__PURE__*/jsxRuntime.jsx("p", {
26180
26270
  className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
26181
- children: ((_provider$mcpConfig = provider.mcpConfig) === null || _provider$mcpConfig === void 0 ? void 0 : _provider$mcpConfig.transport) === "streamable_http" ? "Server Configuration" : "Authentication"
26271
+ children: ((_provider$mcpConfig2 = provider.mcpConfig) === null || _provider$mcpConfig2 === void 0 ? void 0 : _provider$mcpConfig2.transport) === "streamable_http" ? "Server Configuration" : "Authentication"
26182
26272
  })
26183
26273
  }), mcpFormFields.map(function (field) {
26184
26274
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -26189,13 +26279,38 @@ var ProviderDetail = function ProviderDetail(_ref) {
26189
26279
  }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
26190
26280
  className: "text-sm opacity-50",
26191
26281
  children: field.instructions
26192
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26193
- type: field.secret ? "password" : "text",
26194
- value: formCredentials[field.key] || "",
26195
- onChange: function onChange(value) {
26196
- return handleCredentialChange(field.key, value);
26197
- },
26198
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
26282
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26283
+ className: "flex gap-2",
26284
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26285
+ className: "flex-1",
26286
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26287
+ type: field.secret ? "password" : "text",
26288
+ value: formCredentials[field.key] || "",
26289
+ onChange: function onChange(value) {
26290
+ return handleCredentialChange(field.key, value);
26291
+ },
26292
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
26293
+ })
26294
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
26295
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26296
+ var filepath;
26297
+ return _regeneratorRuntime.wrap(function (_context) {
26298
+ while (1) switch (_context.prev = _context.next) {
26299
+ case 0:
26300
+ _context.next = 1;
26301
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
26302
+ case 1:
26303
+ filepath = _context.sent;
26304
+ if (filepath) handleCredentialChange(field.key, filepath);
26305
+ case 2:
26306
+ case "end":
26307
+ return _context.stop();
26308
+ }
26309
+ }, _callee);
26310
+ })),
26311
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
26312
+ children: "Browse"
26313
+ })]
26199
26314
  })]
26200
26315
  }, field.key);
26201
26316
  })]
@@ -26315,6 +26430,16 @@ var ProviderDetail = function ProviderDetail(_ref) {
26315
26430
  })]
26316
26431
  })]
26317
26432
  })]
26433
+ }), authResult && /*#__PURE__*/jsxRuntime.jsx("div", {
26434
+ 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"),
26435
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26436
+ className: "flex items-center gap-2",
26437
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26438
+ icon: authResult.success ? "circle-check" : "circle-exclamation"
26439
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26440
+ children: authResult.message
26441
+ })]
26442
+ })
26318
26443
  }), testResult && /*#__PURE__*/jsxRuntime.jsxs("div", {
26319
26444
  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"),
26320
26445
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -26343,7 +26468,11 @@ var ProviderDetail = function ProviderDetail(_ref) {
26343
26468
  })]
26344
26469
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26345
26470
  className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
26346
- children: [isMcp && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
26471
+ children: [isMcp && resolvedAuthCommand && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
26472
+ title: isAuthorizing ? "Authorizing..." : "Authorize",
26473
+ onClick: handleAuthorize,
26474
+ size: "sm"
26475
+ }), isMcp && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
26347
26476
  title: isTesting ? "Testing..." : "Test Connection",
26348
26477
  onClick: handleTestConnection,
26349
26478
  size: "sm"
@@ -27074,13 +27203,38 @@ var CustomMcpServerForm = function CustomMcpServerForm(_ref2) {
27074
27203
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
27075
27204
  label: field.displayName,
27076
27205
  required: field.required
27077
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27078
- type: field.secret ? "password" : "text",
27079
- value: credentialData[field.key] || "",
27080
- onChange: function onChange(value) {
27081
- return handleCredentialChange(field.key, value);
27082
- },
27083
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
27206
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27207
+ className: "flex gap-2",
27208
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27209
+ className: "flex-1",
27210
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27211
+ type: field.secret ? "password" : "text",
27212
+ value: credentialData[field.key] || "",
27213
+ onChange: function onChange(value) {
27214
+ return handleCredentialChange(field.key, value);
27215
+ },
27216
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
27217
+ })
27218
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
27219
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27220
+ var filepath;
27221
+ return _regeneratorRuntime.wrap(function (_context) {
27222
+ while (1) switch (_context.prev = _context.next) {
27223
+ case 0:
27224
+ _context.next = 1;
27225
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
27226
+ case 1:
27227
+ filepath = _context.sent;
27228
+ if (filepath) handleCredentialChange(field.key, filepath);
27229
+ case 2:
27230
+ case "end":
27231
+ return _context.stop();
27232
+ }
27233
+ }, _callee);
27234
+ })),
27235
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27236
+ children: "Browse"
27237
+ })]
27084
27238
  }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
27085
27239
  className: "text-sm text-red-400",
27086
27240
  children: formErrors[field.key]
@@ -27515,13 +27669,38 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
27515
27669
  }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
27516
27670
  className: "text-sm opacity-50",
27517
27671
  children: field.instructions
27518
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27519
- type: field.secret ? "password" : "text",
27520
- value: credentialData[field.key] || "",
27521
- onChange: function onChange(value) {
27522
- return handleCredentialChange(field.key, value);
27523
- },
27524
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
27672
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27673
+ className: "flex gap-2",
27674
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27675
+ className: "flex-1",
27676
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27677
+ type: field.secret ? "password" : "text",
27678
+ value: credentialData[field.key] || "",
27679
+ onChange: function onChange(value) {
27680
+ return handleCredentialChange(field.key, value);
27681
+ },
27682
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
27683
+ })
27684
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
27685
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27686
+ var filepath;
27687
+ return _regeneratorRuntime.wrap(function (_context) {
27688
+ while (1) switch (_context.prev = _context.next) {
27689
+ case 0:
27690
+ _context.next = 1;
27691
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
27692
+ case 1:
27693
+ filepath = _context.sent;
27694
+ if (filepath) handleCredentialChange(field.key, filepath);
27695
+ case 2:
27696
+ case "end":
27697
+ return _context.stop();
27698
+ }
27699
+ }, _callee);
27700
+ })),
27701
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
27702
+ children: "Browse"
27703
+ })]
27525
27704
  }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
27526
27705
  className: "text-sm text-red-400",
27527
27706
  children: formErrors[field.key]
@@ -27660,46 +27839,58 @@ var ProvidersSection = function ProvidersSection(_ref) {
27660
27839
  var appContext = React.useContext(AppContext);
27661
27840
  var providers = (appContext === null || appContext === void 0 ? void 0 : appContext.providers) || {};
27662
27841
  var refreshProviders = appContext === null || appContext === void 0 ? void 0 : appContext.refreshProviders;
27663
- var _useState = React.useState("credentials"),
27842
+
27843
+ // Load MCP catalog for authCommand lookups
27844
+ var _useState = React.useState([]),
27664
27845
  _useState2 = _slicedToArray(_useState, 2),
27665
- providerTab = _useState2[0],
27666
- setProviderTab = _useState2[1];
27667
- var _useState3 = React.useState(null),
27846
+ catalog = _useState2[0],
27847
+ setCatalog = _useState2[1];
27848
+ React.useEffect(function () {
27849
+ if (!dashApi) return;
27850
+ dashApi.mcpGetCatalog(function (event, result) {
27851
+ if (result !== null && result !== void 0 && result.catalog) setCatalog(result.catalog);
27852
+ }, function () {});
27853
+ }, [dashApi]);
27854
+ var _useState3 = React.useState("credentials"),
27668
27855
  _useState4 = _slicedToArray(_useState3, 2),
27669
- selectedName = _useState4[0],
27670
- setSelectedName = _useState4[1];
27671
- var _useState5 = React.useState(false),
27856
+ providerTab = _useState4[0],
27857
+ setProviderTab = _useState4[1];
27858
+ var _useState5 = React.useState(null),
27672
27859
  _useState6 = _slicedToArray(_useState5, 2),
27673
- isCreating = _useState6[0],
27674
- setIsCreating = _useState6[1];
27860
+ selectedName = _useState6[0],
27861
+ setSelectedName = _useState6[1];
27675
27862
  var _useState7 = React.useState(false),
27676
27863
  _useState8 = _slicedToArray(_useState7, 2),
27677
- isEditing = _useState8[0],
27678
- setIsEditing = _useState8[1];
27679
- var _useState9 = React.useState(""),
27864
+ isCreating = _useState8[0],
27865
+ setIsCreating = _useState8[1];
27866
+ var _useState9 = React.useState(false),
27680
27867
  _useState0 = _slicedToArray(_useState9, 2),
27681
- formName = _useState0[0],
27682
- setFormName = _useState0[1];
27868
+ isEditing = _useState0[0],
27869
+ setIsEditing = _useState0[1];
27683
27870
  var _useState1 = React.useState(""),
27684
27871
  _useState10 = _slicedToArray(_useState1, 2),
27685
- formType = _useState10[0],
27686
- setFormType = _useState10[1];
27687
- var _useState11 = React.useState({}),
27872
+ formName = _useState10[0],
27873
+ setFormName = _useState10[1];
27874
+ var _useState11 = React.useState(""),
27688
27875
  _useState12 = _slicedToArray(_useState11, 2),
27689
- formCredentials = _useState12[0],
27690
- setFormCredentials = _useState12[1];
27691
- var _useState13 = React.useState(null),
27876
+ formType = _useState12[0],
27877
+ setFormType = _useState12[1];
27878
+ var _useState13 = React.useState({}),
27692
27879
  _useState14 = _slicedToArray(_useState13, 2),
27693
- deleteTarget = _useState14[0],
27694
- setDeleteTarget = _useState14[1];
27695
- var _useState15 = React.useState(false),
27880
+ formCredentials = _useState14[0],
27881
+ setFormCredentials = _useState14[1];
27882
+ var _useState15 = React.useState(null),
27696
27883
  _useState16 = _slicedToArray(_useState15, 2),
27697
- isAddingMcp = _useState16[0],
27698
- setIsAddingMcp = _useState16[1];
27884
+ deleteTarget = _useState16[0],
27885
+ setDeleteTarget = _useState16[1];
27699
27886
  var _useState17 = React.useState(false),
27700
27887
  _useState18 = _slicedToArray(_useState17, 2),
27701
- isEditingMcp = _useState18[0],
27702
- setIsEditingMcp = _useState18[1];
27888
+ isAddingMcp = _useState18[0],
27889
+ setIsAddingMcp = _useState18[1];
27890
+ var _useState19 = React.useState(false),
27891
+ _useState20 = _slicedToArray(_useState19, 2),
27892
+ isEditingMcp = _useState20[0],
27893
+ setIsEditingMcp = _useState20[1];
27703
27894
 
27704
27895
  // Row ID counter for env/header rows in MCP edit mode
27705
27896
  var nextRowIdRef = React.useRef(0);
@@ -27974,6 +28165,10 @@ var ProvidersSection = function ProvidersSection(_ref) {
27974
28165
  }
27975
28166
  });
27976
28167
  } else if (selectedName && selectedProvider) {
28168
+ // Look up authCommand from the catalog for this provider type
28169
+ var catalogEntry = catalog.find(function (entry) {
28170
+ return entry.id === selectedProvider.type;
28171
+ });
27977
28172
  detailContent = /*#__PURE__*/jsxRuntime.jsx(ProviderDetail, {
27978
28173
  providerName: selectedName,
27979
28174
  provider: selectedProvider,
@@ -27989,7 +28184,8 @@ var ProvidersSection = function ProvidersSection(_ref) {
27989
28184
  onStartEdit: handleStartEdit,
27990
28185
  onDelete: function onDelete(name) {
27991
28186
  return setDeleteTarget(name);
27992
- }
28187
+ },
28188
+ catalogAuthCommand: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.authCommand) || null
27993
28189
  });
27994
28190
  }
27995
28191
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
@@ -33867,6 +34063,8 @@ exports.MCP_LIST_TOOLS_COMPLETE = MCP_LIST_TOOLS_COMPLETE;
33867
34063
  exports.MCP_LIST_TOOLS_ERROR = MCP_LIST_TOOLS_ERROR;
33868
34064
  exports.MCP_READ_RESOURCE_COMPLETE = MCP_READ_RESOURCE_COMPLETE;
33869
34065
  exports.MCP_READ_RESOURCE_ERROR = MCP_READ_RESOURCE_ERROR;
34066
+ exports.MCP_RUN_AUTH_COMPLETE = MCP_RUN_AUTH_COMPLETE;
34067
+ exports.MCP_RUN_AUTH_ERROR = MCP_RUN_AUTH_ERROR;
33870
34068
  exports.MCP_SERVER_STATUS_COMPLETE = MCP_SERVER_STATUS_COMPLETE;
33871
34069
  exports.MCP_SERVER_STATUS_ERROR = MCP_SERVER_STATUS_ERROR;
33872
34070
  exports.MCP_START_SERVER_COMPLETE = MCP_START_SERVER_COMPLETE;