@trops/dash-core 0.1.69 → 0.1.71

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
@@ -7338,195 +7338,710 @@ var ProviderForm = function ProviderForm(_ref) {
7338
7338
  });
7339
7339
  };
7340
7340
 
7341
- function _createForOfIteratorHelper$8(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$8(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
7342
- function _unsupportedIterableToArray$8(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$8(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$8(r, a) : void 0; } }
7343
- function _arrayLikeToArray$8(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7341
+ var ToolSelector = function ToolSelector(_ref) {
7342
+ var _ref$tools = _ref.tools,
7343
+ tools = _ref$tools === void 0 ? [] : _ref$tools,
7344
+ _ref$selectedTools = _ref.selectedTools,
7345
+ selectedTools = _ref$selectedTools === void 0 ? [] : _ref$selectedTools,
7346
+ onSelectionChange = _ref.onSelectionChange;
7347
+ if (!tools || tools.length === 0) return null;
7348
+ var allSelected = selectedTools.length === tools.length;
7349
+ var handleToggleAll = function handleToggleAll() {
7350
+ if (allSelected) {
7351
+ onSelectionChange([]);
7352
+ } else {
7353
+ onSelectionChange(tools.map(function (t) {
7354
+ return t.name;
7355
+ }));
7356
+ }
7357
+ };
7358
+ var handleToggle = function handleToggle(toolName) {
7359
+ if (selectedTools.includes(toolName)) {
7360
+ onSelectionChange(selectedTools.filter(function (t) {
7361
+ return t !== toolName;
7362
+ }));
7363
+ } else {
7364
+ onSelectionChange([].concat(_toConsumableArray(selectedTools), [toolName]));
7365
+ }
7366
+ };
7367
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
7368
+ className: "space-y-2 flex-1 flex flex-col min-h-0",
7369
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7370
+ className: "flex items-center justify-between",
7371
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
7372
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
7373
+ children: "Allowed Tools"
7374
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
7375
+ onClick: handleToggleAll,
7376
+ className: "text-xs text-blue-400 hover:text-blue-300 transition-colors",
7377
+ children: allSelected ? "Deselect All" : "Select All"
7378
+ })]
7379
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
7380
+ className: "text-sm opacity-50",
7381
+ children: "Choose which tools this provider can expose to widgets"
7382
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
7383
+ className: "space-y-1 flex-1 min-h-0 overflow-y-auto",
7384
+ children: tools.map(function (tool) {
7385
+ var checked = selectedTools.includes(tool.name);
7386
+ return /*#__PURE__*/jsxRuntime.jsxs("label", {
7387
+ className: "flex items-start gap-2 p-1.5 rounded hover:bg-white/5 cursor-pointer",
7388
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
7389
+ type: "checkbox",
7390
+ checked: checked,
7391
+ onChange: function onChange() {
7392
+ return handleToggle(tool.name);
7393
+ },
7394
+ className: "mt-0.5 rounded border-white/20 bg-white/5 text-blue-500 focus:ring-blue-500/30"
7395
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7396
+ className: "flex-1 min-w-0",
7397
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7398
+ className: "text-xs font-mono",
7399
+ children: tool.name
7400
+ }), tool.description && /*#__PURE__*/jsxRuntime.jsxs("span", {
7401
+ className: "text-xs opacity-50 ml-2",
7402
+ children: ["\u2014 ", tool.description]
7403
+ })]
7404
+ })]
7405
+ }, tool.name);
7406
+ })
7407
+ }), /*#__PURE__*/jsxRuntime.jsxs("p", {
7408
+ className: "text-xs opacity-40",
7409
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7410
+ icon: "shield-halved",
7411
+ className: "mr-1"
7412
+ }), selectedTools.length, " of ", tools.length, " tools selected"]
7413
+ })]
7414
+ });
7415
+ };
7416
+
7344
7417
  function ownKeys$r(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; }
7345
7418
  function _objectSpread$r(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$r(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$r(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7346
- var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7347
- var isOpen = _ref.isOpen,
7348
- onClose = _ref.onClose,
7349
- onSelectWidget = _ref.onSelectWidget;
7350
- _ref.workspaceType;
7351
- var _useContext = React.useContext(DashReact.ThemeContext),
7352
- currentTheme = _useContext.currentTheme;
7353
- var _useContext2 = React.useContext(AppContext),
7354
- _useContext2$provider = _useContext2.providers,
7355
- availableProviders = _useContext2$provider === void 0 ? {} : _useContext2$provider,
7356
- dashApi = _useContext2.dashApi,
7357
- credentials = _useContext2.credentials,
7358
- refreshProviders = _useContext2.refreshProviders;
7419
+ /**
7420
+ * Shared MCP utility functions.
7421
+ *
7422
+ * Extracted from McpServerPicker so ProviderDetail (and any future consumer)
7423
+ * can reuse the same field-derivation logic.
7424
+ */
7359
7425
 
7360
- // State management
7361
- var _useState = React.useState("Installed"),
7362
- _useState2 = _slicedToArray(_useState, 2),
7363
- selectedSource = _useState2[0],
7364
- setSelectedSource = _useState2[1]; // "Installed" | "Discover"
7365
- var _useState3 = React.useState(null),
7366
- _useState4 = _slicedToArray(_useState3, 2),
7367
- selectedWidget = _useState4[0],
7368
- setSelectedWidget = _useState4[1];
7369
- var _useState5 = React.useState([]),
7370
- _useState6 = _slicedToArray(_useState5, 2),
7371
- widgets = _useState6[0],
7372
- setWidgets = _useState6[1];
7426
+ /**
7427
+ * Derive required form fields from an mcpConfig, using credentialSchema
7428
+ * as optional enrichment for display names, instructions, and secret flags.
7429
+ *
7430
+ * For streamable_http: extracts {{placeholder}} fields from url and headerTemplate.
7431
+ * For stdio: extracts credential field names from envMapping values.
7432
+ *
7433
+ * @param {object} mcpConfig - The MCP server configuration
7434
+ * @param {object} credentialSchema - Optional metadata for field labels/instructions
7435
+ * @returns {Array<{ key, displayName, required, secret, instructions, type }>}
7436
+ */
7437
+ function deriveFormFields(mcpConfig) {
7438
+ var credentialSchema = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7439
+ var fieldKeys = new Set();
7440
+ if (mcpConfig.transport === "streamable_http") {
7441
+ // Extract {{field}} placeholders from url
7442
+ if (mcpConfig.url) {
7443
+ var urlMatches = mcpConfig.url.match(/\{\{(\w+)\}\}/g) || [];
7444
+ urlMatches.forEach(function (m) {
7445
+ return fieldKeys.add(m.slice(2, -2));
7446
+ });
7447
+ }
7448
+ // Extract {{field}} placeholders from headerTemplate values
7449
+ if (mcpConfig.headerTemplate) {
7450
+ Object.values(mcpConfig.headerTemplate).forEach(function (template) {
7451
+ var matches = template.match(/\{\{(\w+)\}\}/g) || [];
7452
+ matches.forEach(function (m) {
7453
+ return fieldKeys.add(m.slice(2, -2));
7454
+ });
7455
+ });
7456
+ }
7457
+ } else {
7458
+ // stdio: extract credential field names from envMapping values
7459
+ if (mcpConfig.envMapping) {
7460
+ Object.values(mcpConfig.envMapping).forEach(function (credField) {
7461
+ fieldKeys.add(credField);
7462
+ });
7463
+ }
7464
+ }
7373
7465
 
7374
- // Filter state
7375
- var _useState7 = React.useState(""),
7376
- _useState8 = _slicedToArray(_useState7, 2),
7377
- searchQuery = _useState8[0],
7378
- setSearchQuery = _useState8[1];
7379
- var _useState9 = React.useState("all"),
7380
- _useState0 = _slicedToArray(_useState9, 2),
7381
- selectedAuthor = _useState0[0],
7382
- setSelectedAuthor = _useState0[1];
7383
- var _useState1 = React.useState("all"),
7384
- _useState10 = _slicedToArray(_useState1, 2),
7385
- selectedProvider = _useState10[0],
7386
- setSelectedProvider = _useState10[1];
7466
+ // Also include any fields defined in credentialSchema that aren't already derived
7467
+ if (credentialSchema) {
7468
+ Object.keys(credentialSchema).forEach(function (key) {
7469
+ return fieldKeys.add(key);
7470
+ });
7471
+ }
7387
7472
 
7388
- // Phase 2: Provider and userConfig state
7389
- var _useState11 = React.useState({}),
7390
- _useState12 = _slicedToArray(_useState11, 2),
7391
- selectedProviders = _useState12[0],
7392
- setSelectedProviders = _useState12[1];
7393
- var _useState13 = React.useState({}),
7394
- _useState14 = _slicedToArray(_useState13, 2),
7395
- userConfigValues = _useState14[0],
7396
- setUserConfigValues = _useState14[1];
7473
+ // Build the field list with metadata from credentialSchema or auto-generated defaults
7474
+ return Array.from(fieldKeys).map(function (key) {
7475
+ var schemaMeta = credentialSchema[key];
7476
+ if (schemaMeta) {
7477
+ return {
7478
+ key: key,
7479
+ displayName: schemaMeta.displayName || formatFieldName(key),
7480
+ required: schemaMeta.required === true,
7481
+ secret: schemaMeta.secret || false,
7482
+ instructions: schemaMeta.instructions || null,
7483
+ type: schemaMeta.type || "text"
7484
+ };
7485
+ }
7397
7486
 
7398
- // Phase 3: Recent widgets state
7399
- var _useState15 = React.useState([]),
7400
- _useState16 = _slicedToArray(_useState15, 2),
7401
- recentWidgets = _useState16[0],
7402
- setRecentWidgets = _useState16[1];
7487
+ // Auto-generate defaults from the field name
7488
+ return {
7489
+ key: key,
7490
+ displayName: formatFieldName(key),
7491
+ required: false,
7492
+ secret: isLikelySecret(key),
7493
+ instructions: null,
7494
+ type: "text"
7495
+ };
7496
+ });
7497
+ }
7403
7498
 
7404
- // Inline provider creation state
7405
- var _useState17 = React.useState(null),
7406
- _useState18 = _slicedToArray(_useState17, 2),
7407
- inlineCreateType = _useState18[0],
7408
- setInlineCreateType = _useState18[1];
7409
- var _useState19 = React.useState({}),
7410
- _useState20 = _slicedToArray(_useState19, 2),
7411
- inlineCreateSchema = _useState20[0],
7412
- setInlineCreateSchema = _useState20[1];
7413
- var _useState21 = React.useState(null),
7414
- _useState22 = _slicedToArray(_useState21, 2),
7415
- inlineCreateError = _useState22[0],
7416
- setInlineCreateError = _useState22[1];
7417
- var _useState23 = React.useState(false),
7418
- _useState24 = _slicedToArray(_useState23, 2),
7419
- isCreatingProvider = _useState24[0],
7420
- setIsCreatingProvider = _useState24[1];
7499
+ /**
7500
+ * Convert a camelCase field name to a human-readable title.
7501
+ * e.g., "apiKey" → "API Key", "url" → "URL", "botToken" → "Bot Token"
7502
+ */
7503
+ function formatFieldName(name) {
7504
+ var acronyms = {
7505
+ url: "URL",
7506
+ api: "API",
7507
+ id: "ID",
7508
+ mcp: "MCP"
7509
+ };
7510
+ return name.replace(/([A-Z])/g, " $1").replace(/^./, function (s) {
7511
+ return s.toUpperCase();
7512
+ }).trim().split(" ").map(function (word) {
7513
+ return acronyms[word.toLowerCase()] || word;
7514
+ }).join(" ");
7515
+ }
7421
7516
 
7422
- // Installed widget grouping
7423
- var _useState25 = React.useState(new Set()),
7424
- _useState26 = _slicedToArray(_useState25, 2),
7425
- expandedGroups = _useState26[0],
7426
- setExpandedGroups = _useState26[1];
7517
+ /**
7518
+ * Heuristic: does this field name likely contain a secret value?
7519
+ */
7520
+ function isLikelySecret(name) {
7521
+ var lower = name.toLowerCase();
7522
+ return /key|token|secret|password|credential|auth/.test(lower);
7523
+ }
7427
7524
 
7428
- // Registry state
7429
- var _useState27 = React.useState(false),
7430
- _useState28 = _slicedToArray(_useState27, 2),
7431
- isLoadingRegistry = _useState28[0],
7432
- setIsLoadingRegistry = _useState28[1];
7433
- var _useState29 = React.useState(null),
7434
- _useState30 = _slicedToArray(_useState29, 2),
7435
- registryError = _useState30[0],
7436
- setRegistryError = _useState30[1];
7437
- var _useState31 = React.useState([]),
7438
- _useState32 = _slicedToArray(_useState31, 2),
7439
- registryPackages = _useState32[0],
7440
- setRegistryPackages = _useState32[1];
7441
- var _useState33 = React.useState("packages"),
7442
- _useState34 = _slicedToArray(_useState33, 2),
7443
- registryViewMode = _useState34[0],
7444
- setRegistryViewMode = _useState34[1]; // "packages" | "widgets"
7445
- var _useState35 = React.useState(new Set()),
7446
- _useState36 = _slicedToArray(_useState35, 2),
7447
- expandedPackages = _useState36[0],
7448
- setExpandedPackages = _useState36[1];
7449
- var _useState37 = React.useState(null),
7450
- _useState38 = _slicedToArray(_useState37, 2),
7451
- selectedPackage = _useState38[0],
7452
- setSelectedPackage = _useState38[1];
7453
- var _useState39 = React.useState(false),
7454
- _useState40 = _slicedToArray(_useState39, 2),
7455
- isInstalling = _useState40[0],
7456
- setIsInstalling = _useState40[1];
7457
- var _useState41 = React.useState(null),
7458
- _useState42 = _slicedToArray(_useState41, 2),
7459
- installError = _useState42[0],
7460
- setInstallError = _useState42[1];
7461
-
7462
- // Phase 3: Recent Widgets - localStorage functions
7463
- var loadRecentWidgets = function loadRecentWidgets() {
7464
- try {
7465
- var stored = localStorage.getItem("recentWidgets");
7466
- var recentData = stored ? JSON.parse(stored) : [];
7467
-
7468
- // Get widget details from ComponentManager
7469
- var allWidgets = ComponentManager.map();
7470
- var enrichedRecent = recentData.slice(0, 5) // Show top 5
7471
- .map(function (entry) {
7472
- var widget = allWidgets[entry.widgetKey];
7473
- if (!widget) return null; // Widget no longer exists
7474
- return _objectSpread$r(_objectSpread$r({
7475
- key: entry.widgetKey
7476
- }, widget), {}, {
7477
- savedProviders: entry.providers || {},
7478
- savedUserConfig: entry.userConfig || {},
7479
- timestamp: entry.timestamp
7480
- });
7481
- }).filter(Boolean); // Remove null entries
7525
+ /**
7526
+ * Build an mcpConfig by overlaying advanced-section rows onto a catalog base config.
7527
+ *
7528
+ * For stdio: replaces `envMapping` with the rows from the advanced section.
7529
+ * For streamable_http: replaces `headerTemplate` with the rows from the advanced section.
7530
+ *
7531
+ * @param {object} baseMcpConfig - The catalog's original mcpConfig
7532
+ * @param {Array<{ envVar: string, credField: string }>} envMappingRows - Current env var rows
7533
+ * @param {Array<{ headerName: string, headerValue: string }>} headerRows - Current header rows
7534
+ * @returns {object} A new mcpConfig with overridden envMapping or headerTemplate
7535
+ */
7536
+ function buildMcpConfigFromOverrides(baseMcpConfig, envMappingRows, headerRows) {
7537
+ if (baseMcpConfig.transport === "streamable_http") {
7538
+ var headerTemplate = {};
7539
+ headerRows.forEach(function (row) {
7540
+ var name = row.headerName.trim();
7541
+ var value = row.headerValue.trim();
7542
+ if (name && value) {
7543
+ headerTemplate[name] = value;
7544
+ }
7545
+ });
7546
+ var config = _objectSpread$r({}, baseMcpConfig);
7547
+ if (Object.keys(headerTemplate).length > 0) {
7548
+ config.headerTemplate = headerTemplate;
7549
+ } else {
7550
+ delete config.headerTemplate;
7551
+ }
7552
+ return config;
7553
+ }
7482
7554
 
7483
- setRecentWidgets(enrichedRecent);
7484
- } catch (error) {
7485
- setRecentWidgets([]);
7555
+ // stdio
7556
+ var envMapping = {};
7557
+ envMappingRows.forEach(function (row) {
7558
+ var env = row.envVar.trim();
7559
+ var cred = row.credField.trim();
7560
+ if (env && cred) {
7561
+ envMapping[env] = cred;
7486
7562
  }
7487
- };
7488
- var saveToRecent = function saveToRecent(widget, providers, userConfig) {
7489
- try {
7490
- var stored = localStorage.getItem("recentWidgets");
7491
- var recent = stored ? JSON.parse(stored) : [];
7563
+ });
7564
+ return _objectSpread$r(_objectSpread$r({}, baseMcpConfig), {}, {
7565
+ envMapping: envMapping
7566
+ });
7567
+ }
7492
7568
 
7493
- // Create new entry
7494
- var newEntry = {
7495
- widgetKey: widget.key,
7496
- timestamp: Date.now(),
7497
- providers: providers || {},
7498
- userConfig: userConfig || {}
7499
- };
7569
+ /**
7570
+ * Convert an envMapping object into row state for the advanced config UI.
7571
+ *
7572
+ * @param {object} envMapping - e.g. { SLACK_BOT_TOKEN: "botToken" }
7573
+ * @param {Function} nextRowId - Function that returns a unique row ID
7574
+ * @returns {Array<{ id: string, envVar: string, credField: string }>}
7575
+ */
7576
+ function envMappingToRows(envMapping, nextRowId) {
7577
+ if (!envMapping) return [];
7578
+ return Object.entries(envMapping).map(function (_ref) {
7579
+ var _ref2 = _slicedToArray(_ref, 2),
7580
+ envVar = _ref2[0],
7581
+ credField = _ref2[1];
7582
+ return {
7583
+ id: nextRowId(),
7584
+ envVar: envVar,
7585
+ credField: credField
7586
+ };
7587
+ });
7588
+ }
7500
7589
 
7501
- // Remove existing entry for this widget (if any) and add new one at front
7502
- var updated = [newEntry].concat(_toConsumableArray(recent.filter(function (r) {
7503
- return r.widgetKey !== widget.key;
7504
- }))).slice(0, 10); // Keep max 10
7590
+ /**
7591
+ * Convert a headerTemplate object into row state for the advanced config UI.
7592
+ *
7593
+ * @param {object} headerTemplate - e.g. { "Authorization": "Bearer {{apiKey}}" }
7594
+ * @param {Function} nextRowId - Function that returns a unique row ID
7595
+ * @returns {Array<{ id: string, headerName: string, headerValue: string }>}
7596
+ */
7597
+ function headerTemplateToRows(headerTemplate, nextRowId) {
7598
+ if (!headerTemplate) return [];
7599
+ return Object.entries(headerTemplate).map(function (_ref3) {
7600
+ var _ref4 = _slicedToArray(_ref3, 2),
7601
+ headerName = _ref4[0],
7602
+ headerValue = _ref4[1];
7603
+ return {
7604
+ id: nextRowId(),
7605
+ headerName: headerName,
7606
+ headerValue: headerValue
7607
+ };
7608
+ });
7609
+ }
7505
7610
 
7506
- localStorage.setItem("recentWidgets", JSON.stringify(updated));
7611
+ /**
7612
+ * Serialize the current form state into a bare MCP JSON config string.
7613
+ *
7614
+ * Output format (stdio):
7615
+ * {
7616
+ * "type": "stdio",
7617
+ * "command": "npx",
7618
+ * "args": ["-y", "package-name"],
7619
+ * "env": { "API_KEY": "${API_KEY}" }
7620
+ * }
7621
+ *
7622
+ * Output format (HTTP):
7623
+ * {
7624
+ * "type": "streamable_http",
7625
+ * "url": "https://example.com/mcp",
7626
+ * "headerTemplate": { "Authorization": "Bearer {{apiKey}}" }
7627
+ * }
7628
+ *
7629
+ * Credential values are NOT embedded — env values use ${FIELD_NAME} syntax
7630
+ * to reference credential fields entered separately in the form.
7631
+ *
7632
+ * @param {string} name - The provider name (unused in output, kept for API compat)
7633
+ * @param {string} transport - "stdio" or "streamable_http"
7634
+ * @param {object} fields - { command, args, envMappingRows, url, headerRows }
7635
+ * @returns {string} Formatted JSON string
7636
+ */
7637
+ function formStateToMcpJson(name, transport, fields) {
7638
+ var _fields$command = fields.command,
7639
+ command = _fields$command === void 0 ? "" : _fields$command,
7640
+ _fields$args = fields.args,
7641
+ args = _fields$args === void 0 ? "" : _fields$args,
7642
+ _fields$envMappingRow = fields.envMappingRows,
7643
+ envMappingRows = _fields$envMappingRow === void 0 ? [] : _fields$envMappingRow,
7644
+ _fields$url = fields.url,
7645
+ url = _fields$url === void 0 ? "" : _fields$url,
7646
+ _fields$headerRows = fields.headerRows,
7647
+ headerRows = _fields$headerRows === void 0 ? [] : _fields$headerRows;
7648
+ var serverConfig;
7649
+ if (transport === "stdio") {
7650
+ var argsArray = args.trim().split(/\s+/).filter(Boolean);
7651
+ var env = {};
7652
+ envMappingRows.forEach(function (row) {
7653
+ var envVar = row.envVar.trim();
7654
+ var credField = row.credField.trim();
7655
+ if (envVar && credField) {
7656
+ env[envVar] = "${".concat(credField, "}");
7657
+ }
7658
+ });
7659
+ serverConfig = {
7660
+ type: "stdio",
7661
+ command: command.trim()
7662
+ };
7663
+ if (argsArray.length > 0) serverConfig.args = argsArray;
7664
+ if (Object.keys(env).length > 0) serverConfig.env = env;
7665
+ } else {
7666
+ // streamable_http
7667
+ serverConfig = {
7668
+ type: "streamable_http",
7669
+ url: url.trim()
7670
+ };
7671
+ var headerTemplate = {};
7672
+ headerRows.forEach(function (row) {
7673
+ var hName = row.headerName.trim();
7674
+ var hValue = row.headerValue.trim();
7675
+ if (hName && hValue) {
7676
+ headerTemplate[hName] = hValue;
7677
+ }
7678
+ });
7679
+ if (Object.keys(headerTemplate).length > 0) serverConfig.headerTemplate = headerTemplate;
7680
+ }
7681
+ return JSON.stringify(serverConfig, null, 2);
7682
+ }
7507
7683
 
7508
- // Reload recent widgets to update UI
7509
- loadRecentWidgets();
7510
- } catch (error) {
7684
+ /**
7685
+ * Parse an MCP JSON config string back into form state.
7686
+ *
7687
+ * Accepts multiple input formats:
7688
+ * - Bare config: { "command": ..., "args": [...], "env": { "KEY": "${FIELD}" } }
7689
+ * - Wrapped: { "mcpServers": { "name": { ... } } } — unwraps and uses key as providerName
7690
+ *
7691
+ * Transport detection:
7692
+ * - Explicit `type` or `transport` field
7693
+ * - Inferred: `url` present → streamable_http, `command` present → stdio
7694
+ *
7695
+ * stdio env value parsing:
7696
+ * - "${FIELD_NAME}" → envVar = key, credField = FIELD_NAME (reference syntax)
7697
+ * - "literal-value" → envVar = key, credField = key, credentialData[key] = value
7698
+ *
7699
+ * @param {string} jsonString - The JSON to parse
7700
+ * @param {Function} nextRowId - Function that returns a unique row ID
7701
+ * @returns {{ providerName, transport, command, args, envMappingRows, url, headerRows, credentialData, error }}
7702
+ */
7703
+ function mcpJsonToFormState(jsonString, nextRowId) {
7704
+ var parsed;
7705
+ try {
7706
+ parsed = JSON.parse(jsonString);
7707
+ } catch (e) {
7708
+ return {
7709
+ error: "Invalid JSON: ".concat(e.message)
7710
+ };
7711
+ }
7712
+ var providerName = "";
7713
+ var serverConfig;
7714
+ if (parsed.mcpServers && _typeof(parsed.mcpServers) === "object") {
7715
+ var entries = Object.entries(parsed.mcpServers);
7716
+ if (entries.length === 0) {
7717
+ return {
7718
+ error: "No server found in mcpServers"
7719
+ };
7511
7720
  }
7512
- };
7513
- var handleRecentClick = function handleRecentClick(recentWidget) {
7514
- setSelectedWidget(recentWidget);
7515
- setSelectedProviders(recentWidget.savedProviders || {});
7516
- setUserConfigValues(recentWidget.savedUserConfig || {});
7517
- // Reset inline provider creation form
7518
- setInlineCreateType(null);
7519
- setInlineCreateSchema({});
7520
- setInlineCreateError(null);
7521
- };
7522
-
7523
- // Fetch widgets when modal opens
7524
- React.useEffect(function () {
7525
- if (isOpen) {
7526
- loadWidgets();
7527
- loadRecentWidgets(); // Phase 3: Load recent widgets
7528
- // Reset filters when modal opens
7529
- setSearchQuery("");
7721
+ var _entries$ = _slicedToArray(entries[0], 2);
7722
+ providerName = _entries$[0];
7723
+ serverConfig = _entries$[1];
7724
+ } else if (parsed.command || parsed.url || parsed.type || parsed.transport) {
7725
+ serverConfig = parsed;
7726
+ } else {
7727
+ return {
7728
+ error: "Unrecognized format: expected a server config with command, url, or type"
7729
+ };
7730
+ }
7731
+
7732
+ // Determine transport from type/transport field or infer from contents
7733
+ var explicitType = serverConfig.type || serverConfig.transport;
7734
+ var transport;
7735
+ if (explicitType) {
7736
+ transport = explicitType === "stdio" ? "stdio" : "streamable_http";
7737
+ } else {
7738
+ transport = serverConfig.url ? "streamable_http" : "stdio";
7739
+ }
7740
+ var result = {
7741
+ providerName: providerName,
7742
+ transport: transport,
7743
+ command: "",
7744
+ args: "",
7745
+ envMappingRows: [],
7746
+ url: "",
7747
+ headerRows: [],
7748
+ credentialData: {},
7749
+ error: null
7750
+ };
7751
+ if (transport === "stdio") {
7752
+ result.command = serverConfig.command || "";
7753
+ result.args = (serverConfig.args || []).join(" ");
7754
+ if (serverConfig.env && _typeof(serverConfig.env) === "object") {
7755
+ Object.entries(serverConfig.env).forEach(function (_ref5) {
7756
+ var _ref6 = _slicedToArray(_ref5, 2),
7757
+ envVar = _ref6[0],
7758
+ value = _ref6[1];
7759
+ // Check for ${FIELD_NAME} reference syntax
7760
+ var refMatch = typeof value === "string" && value.match(/^\$\{(.+)\}$/);
7761
+ if (refMatch) {
7762
+ // Reference syntax — credField is the extracted name, no credential value
7763
+ result.envMappingRows.push({
7764
+ id: nextRowId(),
7765
+ envVar: envVar,
7766
+ credField: refMatch[1]
7767
+ });
7768
+ } else {
7769
+ // Literal value — use envVar as credField and store the value
7770
+ result.envMappingRows.push({
7771
+ id: nextRowId(),
7772
+ envVar: envVar,
7773
+ credField: envVar
7774
+ });
7775
+ result.credentialData[envVar] = value || "";
7776
+ }
7777
+ });
7778
+ }
7779
+ } else {
7780
+ result.url = serverConfig.url || "";
7781
+ var headers = serverConfig.headers || serverConfig.headerTemplate || {};
7782
+ if (_typeof(headers) === "object") {
7783
+ Object.entries(headers).forEach(function (_ref7) {
7784
+ var _ref8 = _slicedToArray(_ref7, 2),
7785
+ headerName = _ref8[0],
7786
+ headerValue = _ref8[1];
7787
+ result.headerRows.push({
7788
+ id: nextRowId(),
7789
+ headerName: headerName,
7790
+ headerValue: headerValue
7791
+ });
7792
+ });
7793
+ }
7794
+ }
7795
+ return result;
7796
+ }
7797
+
7798
+ function _createForOfIteratorHelper$8(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$8(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
7799
+ function _unsupportedIterableToArray$8(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$8(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$8(r, a) : void 0; } }
7800
+ function _arrayLikeToArray$8(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7801
+ function ownKeys$q(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; }
7802
+ function _objectSpread$q(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$q(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$q(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7803
+ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7804
+ var isOpen = _ref.isOpen,
7805
+ onClose = _ref.onClose,
7806
+ onSelectWidget = _ref.onSelectWidget;
7807
+ _ref.workspaceType;
7808
+ var _useContext = React.useContext(DashReact.ThemeContext),
7809
+ currentTheme = _useContext.currentTheme;
7810
+ var _useContext2 = React.useContext(AppContext),
7811
+ _useContext2$provider = _useContext2.providers,
7812
+ availableProviders = _useContext2$provider === void 0 ? {} : _useContext2$provider,
7813
+ dashApi = _useContext2.dashApi,
7814
+ credentials = _useContext2.credentials,
7815
+ refreshProviders = _useContext2.refreshProviders;
7816
+
7817
+ // State management
7818
+ var _useState = React.useState("Installed"),
7819
+ _useState2 = _slicedToArray(_useState, 2),
7820
+ selectedSource = _useState2[0],
7821
+ setSelectedSource = _useState2[1]; // "Installed" | "Discover"
7822
+ var _useState3 = React.useState(null),
7823
+ _useState4 = _slicedToArray(_useState3, 2),
7824
+ selectedWidget = _useState4[0],
7825
+ setSelectedWidget = _useState4[1];
7826
+ var _useState5 = React.useState([]),
7827
+ _useState6 = _slicedToArray(_useState5, 2),
7828
+ widgets = _useState6[0],
7829
+ setWidgets = _useState6[1];
7830
+
7831
+ // Filter state
7832
+ var _useState7 = React.useState(""),
7833
+ _useState8 = _slicedToArray(_useState7, 2),
7834
+ searchQuery = _useState8[0],
7835
+ setSearchQuery = _useState8[1];
7836
+ var _useState9 = React.useState("all"),
7837
+ _useState0 = _slicedToArray(_useState9, 2),
7838
+ selectedAuthor = _useState0[0],
7839
+ setSelectedAuthor = _useState0[1];
7840
+ var _useState1 = React.useState("all"),
7841
+ _useState10 = _slicedToArray(_useState1, 2),
7842
+ selectedProvider = _useState10[0],
7843
+ setSelectedProvider = _useState10[1];
7844
+
7845
+ // Phase 2: Provider and userConfig state
7846
+ var _useState11 = React.useState({}),
7847
+ _useState12 = _slicedToArray(_useState11, 2),
7848
+ selectedProviders = _useState12[0],
7849
+ setSelectedProviders = _useState12[1];
7850
+ var _useState13 = React.useState({}),
7851
+ _useState14 = _slicedToArray(_useState13, 2),
7852
+ userConfigValues = _useState14[0],
7853
+ setUserConfigValues = _useState14[1];
7854
+
7855
+ // Phase 3: Recent widgets state
7856
+ var _useState15 = React.useState([]),
7857
+ _useState16 = _slicedToArray(_useState15, 2),
7858
+ recentWidgets = _useState16[0],
7859
+ setRecentWidgets = _useState16[1];
7860
+
7861
+ // Inline provider creation state
7862
+ var _useState17 = React.useState(null),
7863
+ _useState18 = _slicedToArray(_useState17, 2),
7864
+ inlineCreateType = _useState18[0],
7865
+ setInlineCreateType = _useState18[1];
7866
+ var _useState19 = React.useState({}),
7867
+ _useState20 = _slicedToArray(_useState19, 2),
7868
+ inlineCreateSchema = _useState20[0],
7869
+ setInlineCreateSchema = _useState20[1];
7870
+ var _useState21 = React.useState(null),
7871
+ _useState22 = _slicedToArray(_useState21, 2),
7872
+ inlineCreateError = _useState22[0],
7873
+ setInlineCreateError = _useState22[1];
7874
+ var _useState23 = React.useState(false),
7875
+ _useState24 = _slicedToArray(_useState23, 2),
7876
+ isCreatingProvider = _useState24[0],
7877
+ setIsCreatingProvider = _useState24[1];
7878
+
7879
+ // MCP catalog for inline stepper creation
7880
+ var _useState25 = React.useState([]),
7881
+ _useState26 = _slicedToArray(_useState25, 2),
7882
+ mcpCatalog = _useState26[0],
7883
+ setMcpCatalog = _useState26[1];
7884
+ var _useState27 = React.useState(null),
7885
+ _useState28 = _slicedToArray(_useState27, 2),
7886
+ inlineCatalogEntry = _useState28[0],
7887
+ setInlineCatalogEntry = _useState28[1];
7888
+
7889
+ // Inline MCP stepper state
7890
+ var _useState29 = React.useState(0),
7891
+ _useState30 = _slicedToArray(_useState29, 2),
7892
+ inlineWizardStep = _useState30[0],
7893
+ setInlineWizardStep = _useState30[1];
7894
+ var _useState31 = React.useState({}),
7895
+ _useState32 = _slicedToArray(_useState31, 2),
7896
+ inlineCredentialData = _useState32[0],
7897
+ setInlineCredentialData = _useState32[1];
7898
+ var _useState33 = React.useState(""),
7899
+ _useState34 = _slicedToArray(_useState33, 2),
7900
+ inlineProviderName = _useState34[0],
7901
+ setInlineProviderName = _useState34[1];
7902
+ var _useState35 = React.useState({}),
7903
+ _useState36 = _slicedToArray(_useState35, 2),
7904
+ inlineFormErrors = _useState36[0],
7905
+ setInlineFormErrors = _useState36[1];
7906
+ var _useState37 = React.useState(null),
7907
+ _useState38 = _slicedToArray(_useState37, 2),
7908
+ inlineTestResult = _useState38[0],
7909
+ setInlineTestResult = _useState38[1];
7910
+ var _useState39 = React.useState(false),
7911
+ _useState40 = _slicedToArray(_useState39, 2),
7912
+ inlineIsTesting = _useState40[0],
7913
+ setInlineIsTesting = _useState40[1];
7914
+ var _useState41 = React.useState(null),
7915
+ _useState42 = _slicedToArray(_useState41, 2),
7916
+ inlineAuthResult = _useState42[0],
7917
+ setInlineAuthResult = _useState42[1];
7918
+ var _useState43 = React.useState(false),
7919
+ _useState44 = _slicedToArray(_useState43, 2),
7920
+ inlineIsAuthorizing = _useState44[0],
7921
+ setInlineIsAuthorizing = _useState44[1];
7922
+ var _useState45 = React.useState(null),
7923
+ _useState46 = _slicedToArray(_useState45, 2),
7924
+ inlineSelectedTools = _useState46[0],
7925
+ setInlineSelectedTools = _useState46[1];
7926
+
7927
+ // Installed widget grouping
7928
+ var _useState47 = React.useState(new Set()),
7929
+ _useState48 = _slicedToArray(_useState47, 2),
7930
+ expandedGroups = _useState48[0],
7931
+ setExpandedGroups = _useState48[1];
7932
+
7933
+ // Registry state
7934
+ var _useState49 = React.useState(false),
7935
+ _useState50 = _slicedToArray(_useState49, 2),
7936
+ isLoadingRegistry = _useState50[0],
7937
+ setIsLoadingRegistry = _useState50[1];
7938
+ var _useState51 = React.useState(null),
7939
+ _useState52 = _slicedToArray(_useState51, 2),
7940
+ registryError = _useState52[0],
7941
+ setRegistryError = _useState52[1];
7942
+ var _useState53 = React.useState([]),
7943
+ _useState54 = _slicedToArray(_useState53, 2),
7944
+ registryPackages = _useState54[0],
7945
+ setRegistryPackages = _useState54[1];
7946
+ var _useState55 = React.useState("packages"),
7947
+ _useState56 = _slicedToArray(_useState55, 2),
7948
+ registryViewMode = _useState56[0],
7949
+ setRegistryViewMode = _useState56[1]; // "packages" | "widgets"
7950
+ var _useState57 = React.useState(new Set()),
7951
+ _useState58 = _slicedToArray(_useState57, 2),
7952
+ expandedPackages = _useState58[0],
7953
+ setExpandedPackages = _useState58[1];
7954
+ var _useState59 = React.useState(null),
7955
+ _useState60 = _slicedToArray(_useState59, 2),
7956
+ selectedPackage = _useState60[0],
7957
+ setSelectedPackage = _useState60[1];
7958
+ var _useState61 = React.useState(false),
7959
+ _useState62 = _slicedToArray(_useState61, 2),
7960
+ isInstalling = _useState62[0],
7961
+ setIsInstalling = _useState62[1];
7962
+ var _useState63 = React.useState(null),
7963
+ _useState64 = _slicedToArray(_useState63, 2),
7964
+ installError = _useState64[0],
7965
+ setInstallError = _useState64[1];
7966
+
7967
+ // Phase 3: Recent Widgets - localStorage functions
7968
+ var loadRecentWidgets = function loadRecentWidgets() {
7969
+ try {
7970
+ var stored = localStorage.getItem("recentWidgets");
7971
+ var recentData = stored ? JSON.parse(stored) : [];
7972
+
7973
+ // Get widget details from ComponentManager
7974
+ var allWidgets = ComponentManager.map();
7975
+ var enrichedRecent = recentData.slice(0, 5) // Show top 5
7976
+ .map(function (entry) {
7977
+ var widget = allWidgets[entry.widgetKey];
7978
+ if (!widget) return null; // Widget no longer exists
7979
+ return _objectSpread$q(_objectSpread$q({
7980
+ key: entry.widgetKey
7981
+ }, widget), {}, {
7982
+ savedProviders: entry.providers || {},
7983
+ savedUserConfig: entry.userConfig || {},
7984
+ timestamp: entry.timestamp
7985
+ });
7986
+ }).filter(Boolean); // Remove null entries
7987
+
7988
+ setRecentWidgets(enrichedRecent);
7989
+ } catch (error) {
7990
+ setRecentWidgets([]);
7991
+ }
7992
+ };
7993
+ var saveToRecent = function saveToRecent(widget, providers, userConfig) {
7994
+ try {
7995
+ var stored = localStorage.getItem("recentWidgets");
7996
+ var recent = stored ? JSON.parse(stored) : [];
7997
+
7998
+ // Create new entry
7999
+ var newEntry = {
8000
+ widgetKey: widget.key,
8001
+ timestamp: Date.now(),
8002
+ providers: providers || {},
8003
+ userConfig: userConfig || {}
8004
+ };
8005
+
8006
+ // Remove existing entry for this widget (if any) and add new one at front
8007
+ var updated = [newEntry].concat(_toConsumableArray(recent.filter(function (r) {
8008
+ return r.widgetKey !== widget.key;
8009
+ }))).slice(0, 10); // Keep max 10
8010
+
8011
+ localStorage.setItem("recentWidgets", JSON.stringify(updated));
8012
+
8013
+ // Reload recent widgets to update UI
8014
+ loadRecentWidgets();
8015
+ } catch (error) {
8016
+ }
8017
+ };
8018
+ var handleRecentClick = function handleRecentClick(recentWidget) {
8019
+ setSelectedWidget(recentWidget);
8020
+ setSelectedProviders(recentWidget.savedProviders || {});
8021
+ setUserConfigValues(recentWidget.savedUserConfig || {});
8022
+ // Reset inline provider creation form
8023
+ setInlineCreateType(null);
8024
+ setInlineCreateSchema({});
8025
+ setInlineCreateError(null);
8026
+ };
8027
+
8028
+ // Fetch MCP catalog for inline stepper creation
8029
+ React.useEffect(function () {
8030
+ if (isOpen && dashApi && mcpCatalog.length === 0) {
8031
+ dashApi.mcpGetCatalog(function (event, result) {
8032
+ return setMcpCatalog((result === null || result === void 0 ? void 0 : result.catalog) || []);
8033
+ }, function () {});
8034
+ }
8035
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8036
+ }, [isOpen, dashApi]);
8037
+
8038
+ // Fetch widgets when modal opens
8039
+ React.useEffect(function () {
8040
+ if (isOpen) {
8041
+ loadWidgets();
8042
+ loadRecentWidgets(); // Phase 3: Load recent widgets
8043
+ // Reset filters when modal opens
8044
+ setSearchQuery("");
7530
8045
  setSelectedAuthor("all");
7531
8046
  setSelectedProvider("all");
7532
8047
  setExpandedGroups(new Set()); // Start with all groups collapsed
@@ -7612,7 +8127,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7612
8127
  // Get widgets from ComponentManager
7613
8128
  var allWidgets = ComponentManager.map();
7614
8129
  var widgetList = Object.keys(allWidgets).map(function (key) {
7615
- return _objectSpread$r({
8130
+ return _objectSpread$q({
7616
8131
  key: key
7617
8132
  }, allWidgets[key]);
7618
8133
  }).filter(function (widget) {
@@ -7812,21 +8327,37 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7812
8327
  };
7813
8328
  var handleProviderSelect = function handleProviderSelect(providerType, providerName) {
7814
8329
  if (providerName === "__create_new__") {
7815
- // Find credential schema for this provider type
7816
8330
  var providerReq = selectedWidget.providers.find(function (p) {
7817
8331
  return p.type === providerType;
7818
8332
  });
7819
8333
 
7820
- // Show inline creation form
8334
+ // Look up full catalog entry for MCP providers
8335
+ var catalogEntry = mcpCatalog.find(function (s) {
8336
+ return s.id === providerType;
8337
+ });
7821
8338
  setInlineCreateType(providerType);
7822
- setInlineCreateSchema((providerReq === null || providerReq === void 0 ? void 0 : providerReq.credentialSchema) || {});
8339
+ setInlineCreateSchema((catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.credentialSchema) || (providerReq === null || providerReq === void 0 ? void 0 : providerReq.credentialSchema) || {});
7823
8340
  setInlineCreateError(null);
8341
+
8342
+ // Initialize stepper state for MCP providers
8343
+ if (catalogEntry) {
8344
+ setInlineCatalogEntry(catalogEntry);
8345
+ setInlineProviderName(catalogEntry.name);
8346
+ setInlineCredentialData({});
8347
+ setInlineFormErrors({});
8348
+ setInlineWizardStep(0);
8349
+ setInlineTestResult(null);
8350
+ setInlineAuthResult(null);
8351
+ setInlineSelectedTools(null);
8352
+ } else {
8353
+ setInlineCatalogEntry(null);
8354
+ }
7824
8355
  } else {
7825
8356
  // Normal provider selection - also close any open inline form
7826
8357
  setInlineCreateType(null);
7827
8358
  setInlineCreateSchema({});
7828
8359
  setInlineCreateError(null);
7829
- setSelectedProviders(_objectSpread$r(_objectSpread$r({}, selectedProviders), {}, _defineProperty({}, providerType, providerName)));
8360
+ setSelectedProviders(_objectSpread$q(_objectSpread$q({}, selectedProviders), {}, _defineProperty({}, providerType, providerName)));
7830
8361
  }
7831
8362
  };
7832
8363
  var handleInlineProviderSubmit = function handleInlineProviderSubmit(formData) {
@@ -7847,7 +8378,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7847
8378
 
7848
8379
  // Auto-select the newly created provider
7849
8380
  setSelectedProviders(function (prev) {
7850
- return _objectSpread$r(_objectSpread$r({}, prev), {}, _defineProperty({}, providerType, providerName));
8381
+ return _objectSpread$q(_objectSpread$q({}, prev), {}, _defineProperty({}, providerType, providerName));
7851
8382
  });
7852
8383
 
7853
8384
  // Collapse the inline form
@@ -7863,9 +8394,163 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7863
8394
  setInlineCreateType(null);
7864
8395
  setInlineCreateSchema({});
7865
8396
  setInlineCreateError(null);
8397
+ setInlineCatalogEntry(null);
8398
+ setInlineWizardStep(0);
8399
+ setInlineCredentialData({});
8400
+ setInlineProviderName("");
8401
+ setInlineFormErrors({});
8402
+ setInlineTestResult(null);
8403
+ setInlineAuthResult(null);
8404
+ setInlineSelectedTools(null);
8405
+ setInlineIsTesting(false);
8406
+ setInlineIsAuthorizing(false);
7866
8407
  };
7867
- var handleConfigChange = function handleConfigChange(key, value) {
7868
- setUserConfigValues(_objectSpread$r(_objectSpread$r({}, userConfigValues), {}, _defineProperty({}, key, value)));
8408
+
8409
+ // ── Inline MCP Stepper Handlers ──
8410
+
8411
+ var inlineFormFields = React.useMemo(function () {
8412
+ if (!(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.mcpConfig)) return [];
8413
+ return deriveFormFields(inlineCatalogEntry.mcpConfig, inlineCatalogEntry.credentialSchema || {});
8414
+ }, [inlineCatalogEntry]);
8415
+ var inlineHasAuth = !!(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.authCommand);
8416
+ var inlineWizardSteps = inlineHasAuth ? ["configure", "authorize", "testTools"] : ["configure", "testTools"];
8417
+ var inlineTotalSteps = inlineWizardSteps.length;
8418
+ var inlineCurrentStepType = inlineWizardSteps[inlineWizardStep];
8419
+ var inlineValidateForm = function inlineValidateForm() {
8420
+ var errors = {};
8421
+ if (!(inlineProviderName !== null && inlineProviderName !== void 0 && inlineProviderName.trim())) {
8422
+ errors.providerName = "Provider name is required";
8423
+ }
8424
+ inlineFormFields.forEach(function (field) {
8425
+ var _inlineCredentialData;
8426
+ if (field.required && !((_inlineCredentialData = inlineCredentialData[field.key]) !== null && _inlineCredentialData !== void 0 && _inlineCredentialData.trim())) {
8427
+ errors[field.key] = "".concat(field.displayName, " is required");
8428
+ }
8429
+ });
8430
+ setInlineFormErrors(errors);
8431
+ return Object.keys(errors).length === 0;
8432
+ };
8433
+ var inlineHandleCredentialChange = function inlineHandleCredentialChange(fieldName, value) {
8434
+ setInlineCredentialData(function (prev) {
8435
+ return _objectSpread$q(_objectSpread$q({}, prev), {}, _defineProperty({}, fieldName, value));
8436
+ });
8437
+ if (inlineFormErrors[fieldName] && value !== null && value !== void 0 && value.trim()) {
8438
+ setInlineFormErrors(function (prev) {
8439
+ var next = _objectSpread$q({}, prev);
8440
+ delete next[fieldName];
8441
+ return next;
8442
+ });
8443
+ }
8444
+ };
8445
+ var inlineHandleWizardStepChange = function inlineHandleWizardStepChange(newStep) {
8446
+ if (newStep < inlineWizardStep) {
8447
+ setInlineWizardStep(newStep);
8448
+ return;
8449
+ }
8450
+ if (inlineCurrentStepType === "configure" && newStep > inlineWizardStep) {
8451
+ if (!inlineValidateForm()) return;
8452
+ }
8453
+ if (inlineCurrentStepType === "authorize" && newStep > inlineWizardStep) {
8454
+ if (!(inlineAuthResult !== null && inlineAuthResult !== void 0 && inlineAuthResult.success)) return;
8455
+ }
8456
+ setInlineWizardStep(newStep);
8457
+ };
8458
+ var inlineHandleTestConnection = function inlineHandleTestConnection() {
8459
+ if (!dashApi || !(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.mcpConfig)) return;
8460
+ setInlineIsTesting(true);
8461
+ setInlineTestResult(null);
8462
+ var testName = "__test__".concat(inlineCatalogEntry.id);
8463
+ dashApi.mcpStartServer(testName, inlineCatalogEntry.mcpConfig, inlineCredentialData, function (event, result) {
8464
+ if (result.error) {
8465
+ setInlineTestResult({
8466
+ success: false,
8467
+ message: result.message
8468
+ });
8469
+ setInlineIsTesting(false);
8470
+ return;
8471
+ }
8472
+ setInlineTestResult({
8473
+ success: true,
8474
+ tools: result.tools || [],
8475
+ message: "Connected! Found ".concat((result.tools || []).length, " tools.")
8476
+ });
8477
+ setInlineSelectedTools((result.tools || []).map(function (t) {
8478
+ return t.name;
8479
+ }));
8480
+ dashApi.mcpStopServer(testName, function () {}, function () {});
8481
+ setInlineIsTesting(false);
8482
+ }, function (event, err) {
8483
+ setInlineTestResult({
8484
+ success: false,
8485
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Connection failed"
8486
+ });
8487
+ setInlineIsTesting(false);
8488
+ });
8489
+ };
8490
+ var inlineHandleAuthorize = function inlineHandleAuthorize() {
8491
+ if (!dashApi || !(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.mcpConfig) || !(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.authCommand)) return;
8492
+ setInlineIsAuthorizing(true);
8493
+ setInlineAuthResult(null);
8494
+ dashApi.mcpRunAuth(inlineCatalogEntry.mcpConfig, inlineCredentialData, inlineCatalogEntry.authCommand, function (event, result) {
8495
+ if (result.error) {
8496
+ setInlineAuthResult({
8497
+ success: false,
8498
+ message: result.message
8499
+ });
8500
+ } else {
8501
+ setInlineAuthResult({
8502
+ success: true,
8503
+ message: "Authorized!"
8504
+ });
8505
+ }
8506
+ setInlineIsAuthorizing(false);
8507
+ }, function (event, err) {
8508
+ setInlineAuthResult({
8509
+ success: false,
8510
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Authorization failed"
8511
+ });
8512
+ setInlineIsAuthorizing(false);
8513
+ });
8514
+ };
8515
+ var inlineHandleSave = function inlineHandleSave() {
8516
+ if (!inlineCatalogEntry || !inlineValidateForm()) return;
8517
+ var providerType = inlineCreateType;
8518
+ var providerName = inlineProviderName.trim();
8519
+ setIsCreatingProvider(true);
8520
+ setInlineCreateError(null);
8521
+ dashApi.saveProvider(credentials.appId, providerName, {
8522
+ providerType: providerType,
8523
+ credentials: inlineCredentialData,
8524
+ providerClass: "mcp",
8525
+ mcpConfig: inlineCatalogEntry.mcpConfig,
8526
+ allowedTools: inlineSelectedTools
8527
+ }, function (event, result) {
8528
+ if (refreshProviders) {
8529
+ refreshProviders();
8530
+ }
8531
+ setSelectedProviders(function (prev) {
8532
+ return _objectSpread$q(_objectSpread$q({}, prev), {}, _defineProperty({}, providerType, providerName));
8533
+ });
8534
+
8535
+ // Reset stepper state
8536
+ setInlineCreateType(null);
8537
+ setInlineCreateSchema({});
8538
+ setInlineCatalogEntry(null);
8539
+ setIsCreatingProvider(false);
8540
+ setInlineWizardStep(0);
8541
+ setInlineCredentialData({});
8542
+ setInlineProviderName("");
8543
+ setInlineFormErrors({});
8544
+ setInlineTestResult(null);
8545
+ setInlineAuthResult(null);
8546
+ setInlineSelectedTools(null);
8547
+ }, function (event, error) {
8548
+ setInlineCreateError("Failed to create provider: ".concat((error === null || error === void 0 ? void 0 : error.message) || "Unknown error"));
8549
+ setIsCreatingProvider(false);
8550
+ });
8551
+ };
8552
+ var handleConfigChange = function handleConfigChange(key, value) {
8553
+ setUserConfigValues(_objectSpread$q(_objectSpread$q({}, userConfigValues), {}, _defineProperty({}, key, value)));
7869
8554
  };
7870
8555
 
7871
8556
  // Install a package from the registry
@@ -7955,7 +8640,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7955
8640
 
7956
8641
  // Phase 3: Save to recent widgets
7957
8642
  saveToRecent(selectedWidget, selectedProviders, userConfigValues);
7958
- onSelectWidget(_objectSpread$r(_objectSpread$r({}, selectedWidget), {}, {
8643
+ onSelectWidget(_objectSpread$q(_objectSpread$q({}, selectedWidget), {}, {
7959
8644
  selectedProviders: selectedProviders,
7960
8645
  // Pass to parent
7961
8646
  userConfigValues: userConfigValues // Pass to parent
@@ -8496,6 +9181,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
8496
9181
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
8497
9182
  className: "space-y-2",
8498
9183
  children: selectedWidget.providers.map(function (providerReq, idx) {
9184
+ var _inlineCatalogEntry$m, _inlineCatalogEntry$m2, _inlineCatalogEntry$m3, _inlineCatalogEntry$m4, _inlineCatalogEntry$m5, _inlineTestResult$too;
8499
9185
  // Get available providers of this type
8500
9186
  var providersOfType = Object.values(availableProviders).filter(function (p) {
8501
9187
  return p.type === providerReq.type;
@@ -8540,7 +9226,227 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
8540
9226
  className: "text-xs text-red-400",
8541
9227
  children: inlineCreateError
8542
9228
  })
8543
- }), /*#__PURE__*/jsxRuntime.jsx(ProviderForm, {
9229
+ }), inlineCatalogEntry ?
9230
+ /*#__PURE__*/
9231
+ /* MCP Provider: Stepper-based creation */
9232
+ jsxRuntime.jsxs("div", {
9233
+ className: "space-y-3",
9234
+ children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
9235
+ activeStep: inlineWizardStep,
9236
+ onStepChange: inlineHandleWizardStepChange,
9237
+ showNavigation: false,
9238
+ className: "flex-1 min-h-0 flex flex-col",
9239
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
9240
+ label: "Configure",
9241
+ description: "Name & credentials",
9242
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
9243
+ className: "space-y-4 pb-2",
9244
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9245
+ className: "bg-white/5 border border-white/10 rounded-lg p-3 space-y-2",
9246
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
9247
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
9248
+ children: "MCP Server Connection"
9249
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9250
+ className: "space-y-1 text-sm",
9251
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9252
+ className: "flex gap-2",
9253
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
9254
+ className: "opacity-50 w-20 shrink-0",
9255
+ children: "Transport:"
9256
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
9257
+ text: ((_inlineCatalogEntry$m = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m === void 0 ? void 0 : _inlineCatalogEntry$m.transport) === "streamable_http" ? "Streamable HTTP" : "stdio"
9258
+ })]
9259
+ }), ((_inlineCatalogEntry$m2 = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m2 === void 0 ? void 0 : _inlineCatalogEntry$m2.transport) !== "streamable_http" && /*#__PURE__*/jsxRuntime.jsxs("div", {
9260
+ className: "flex gap-2",
9261
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
9262
+ className: "opacity-50 w-20 shrink-0",
9263
+ children: "Command:"
9264
+ }), /*#__PURE__*/jsxRuntime.jsxs("code", {
9265
+ className: "text-xs bg-white/5 px-2 py-0.5 rounded",
9266
+ children: [(_inlineCatalogEntry$m3 = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m3 === void 0 ? void 0 : _inlineCatalogEntry$m3.command, " ", (((_inlineCatalogEntry$m4 = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m4 === void 0 ? void 0 : _inlineCatalogEntry$m4.args) || []).join(" ")]
9267
+ })]
9268
+ })]
9269
+ })]
9270
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9271
+ className: "flex flex-col gap-1",
9272
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
9273
+ label: "Provider Name",
9274
+ required: true
9275
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
9276
+ value: inlineProviderName,
9277
+ onChange: function onChange(value) {
9278
+ setInlineProviderName(value);
9279
+ if (inlineFormErrors.providerName && value !== null && value !== void 0 && value.trim()) {
9280
+ setInlineFormErrors(function (prev) {
9281
+ var next = _objectSpread$q({}, prev);
9282
+ delete next.providerName;
9283
+ return next;
9284
+ });
9285
+ }
9286
+ },
9287
+ placeholder: "Enter provider name"
9288
+ }), inlineFormErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
9289
+ className: "text-xs text-red-400",
9290
+ children: inlineFormErrors.providerName
9291
+ })]
9292
+ }), inlineFormFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
9293
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
9294
+ className: "border-t border-white/10 pt-3",
9295
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
9296
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
9297
+ children: ((_inlineCatalogEntry$m5 = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m5 === void 0 ? void 0 : _inlineCatalogEntry$m5.transport) === "streamable_http" ? "Server Configuration" : "Authentication"
9298
+ })
9299
+ }), inlineFormFields.map(function (field) {
9300
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
9301
+ className: "flex flex-col gap-1",
9302
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
9303
+ label: field.displayName,
9304
+ required: field.required
9305
+ }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
9306
+ className: "text-xs opacity-50",
9307
+ children: field.instructions
9308
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9309
+ className: "flex gap-2",
9310
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
9311
+ className: "flex-1",
9312
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
9313
+ type: field.secret ? "password" : "text",
9314
+ value: inlineCredentialData[field.key] || "",
9315
+ onChange: function onChange(value) {
9316
+ return inlineHandleCredentialChange(field.key, value);
9317
+ },
9318
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
9319
+ })
9320
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
9321
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
9322
+ var filepath;
9323
+ return _regeneratorRuntime.wrap(function (_context3) {
9324
+ while (1) switch (_context3.prev = _context3.next) {
9325
+ case 0:
9326
+ _context3.next = 1;
9327
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
9328
+ case 1:
9329
+ filepath = _context3.sent;
9330
+ if (filepath) inlineHandleCredentialChange(field.key, filepath);
9331
+ case 2:
9332
+ case "end":
9333
+ return _context3.stop();
9334
+ }
9335
+ }, _callee3);
9336
+ })),
9337
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
9338
+ children: "Browse"
9339
+ })]
9340
+ }), inlineFormErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
9341
+ className: "text-xs text-red-400",
9342
+ children: inlineFormErrors[field.key]
9343
+ })]
9344
+ }, field.key);
9345
+ })]
9346
+ })]
9347
+ })
9348
+ }), inlineHasAuth && /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
9349
+ label: "Authorize",
9350
+ description: "OAuth authentication",
9351
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
9352
+ className: "space-y-4 pb-2",
9353
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9354
+ className: "flex flex-col items-center justify-center py-6 space-y-3",
9355
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
9356
+ className: "text-sm opacity-60 text-center max-w-md",
9357
+ children: "This server requires OAuth authorization. Click the button below to open a browser window and complete the authentication flow."
9358
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9359
+ title: inlineIsAuthorizing ? "Authorizing..." : "Authorize",
9360
+ onClick: inlineHandleAuthorize,
9361
+ size: "sm"
9362
+ })]
9363
+ }), inlineAuthResult && /*#__PURE__*/jsxRuntime.jsx("div", {
9364
+ className: "p-3 rounded-lg text-sm ".concat(inlineAuthResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
9365
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
9366
+ className: "flex items-center gap-2",
9367
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
9368
+ icon: inlineAuthResult.success ? "circle-check" : "circle-exclamation"
9369
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
9370
+ children: inlineAuthResult.message
9371
+ })]
9372
+ })
9373
+ })]
9374
+ })
9375
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
9376
+ label: "Test & Tools",
9377
+ description: "Verify & select tools",
9378
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
9379
+ className: "space-y-3 pb-2",
9380
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9381
+ className: "flex items-center gap-3",
9382
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9383
+ title: inlineIsTesting ? "Fetching..." : "Fetch Tools",
9384
+ onClick: inlineHandleTestConnection,
9385
+ size: "sm"
9386
+ }), inlineTestResult && /*#__PURE__*/jsxRuntime.jsxs("span", {
9387
+ className: "text-sm ".concat(inlineTestResult.success ? "text-green-400" : "text-red-400"),
9388
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
9389
+ icon: inlineTestResult.success ? "circle-check" : "circle-exclamation",
9390
+ className: "mr-1"
9391
+ }), inlineTestResult.message]
9392
+ })]
9393
+ }), (inlineTestResult === null || inlineTestResult === void 0 ? void 0 : inlineTestResult.success) && ((_inlineTestResult$too = inlineTestResult.tools) === null || _inlineTestResult$too === void 0 ? void 0 : _inlineTestResult$too.length) > 0 && inlineSelectedTools && /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
9394
+ tools: inlineTestResult.tools,
9395
+ selectedTools: inlineSelectedTools,
9396
+ onSelectionChange: setInlineSelectedTools
9397
+ }), !inlineTestResult && /*#__PURE__*/jsxRuntime.jsx("div", {
9398
+ className: "text-center py-6 opacity-50 text-sm",
9399
+ children: "Click \"Fetch Tools\" to test the connection and discover available tools."
9400
+ })]
9401
+ })
9402
+ })]
9403
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9404
+ className: "flex flex-row items-center pt-3 border-t border-white/10",
9405
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9406
+ className: "flex flex-row gap-2",
9407
+ children: [inlineWizardStep === 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9408
+ title: "Cancel",
9409
+ onClick: handleInlineProviderCancel,
9410
+ size: "sm"
9411
+ }), inlineWizardStep > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9412
+ title: "Back",
9413
+ onClick: function onClick() {
9414
+ return setInlineWizardStep(inlineWizardStep - 1);
9415
+ },
9416
+ size: "sm"
9417
+ })]
9418
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
9419
+ className: "flex-1 text-center",
9420
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
9421
+ className: "text-xs opacity-40",
9422
+ children: ["Step ", inlineWizardStep + 1, " of ", inlineTotalSteps]
9423
+ })
9424
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9425
+ className: "flex flex-row gap-2",
9426
+ children: [inlineCurrentStepType === "configure" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9427
+ title: "Next",
9428
+ onClick: function onClick() {
9429
+ return inlineHandleWizardStepChange(inlineWizardStep + 1);
9430
+ },
9431
+ size: "sm"
9432
+ }), inlineCurrentStepType === "authorize" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9433
+ title: "Next",
9434
+ onClick: function onClick() {
9435
+ return inlineHandleWizardStepChange(inlineWizardStep + 1);
9436
+ },
9437
+ disabled: !(inlineAuthResult !== null && inlineAuthResult !== void 0 && inlineAuthResult.success),
9438
+ size: "sm"
9439
+ }), inlineCurrentStepType === "testTools" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9440
+ title: isCreatingProvider ? "Saving..." : "Save MCP Server",
9441
+ onClick: inlineHandleSave,
9442
+ size: "sm"
9443
+ })]
9444
+ })]
9445
+ })]
9446
+ }) :
9447
+ /*#__PURE__*/
9448
+ /* Credential Provider: flat form fallback */
9449
+ jsxRuntime.jsx(ProviderForm, {
8544
9450
  credentialSchema: inlineCreateSchema,
8545
9451
  onSubmit: handleInlineProviderSubmit,
8546
9452
  onCancel: handleInlineProviderCancel,
@@ -8559,10 +9465,10 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
8559
9465
  children: "CONFIGURATION"
8560
9466
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
8561
9467
  className: "space-y-2",
8562
- children: Object.entries(selectedWidget.userConfig).map(function (_ref8) {
8563
- var _ref9 = _slicedToArray(_ref8, 2),
8564
- key = _ref9[0],
8565
- config = _ref9[1];
9468
+ children: Object.entries(selectedWidget.userConfig).map(function (_ref9) {
9469
+ var _ref0 = _slicedToArray(_ref9, 2),
9470
+ key = _ref0[0],
9471
+ config = _ref0[1];
8566
9472
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
8567
9473
  className: "space-y-1",
8568
9474
  children: [/*#__PURE__*/jsxRuntime.jsxs("label", {
@@ -9027,768 +9933,387 @@ var WidgetCardHeader = function WidgetCardHeader(_ref) {
9027
9933
  return onMoreOptions(widget);
9028
9934
  },
9029
9935
  title: "More options",
9030
- theme: false
9031
- })]
9032
- }) : overflowActions.length > 0 ? /*#__PURE__*/jsxRuntime.jsxs("div", {
9033
- className: "relative",
9034
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon2, {
9035
- icon: "chevron-down",
9036
- onClick: function onClick() {
9037
- setShowProviderDropdown(null);
9038
- setShowOverflowMenu(!showOverflowMenu);
9039
- },
9040
- title: "Actions",
9041
- theme: false
9042
- }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.DropdownPanel, {
9043
- isOpen: showOverflowMenu,
9044
- onClose: function onClose() {
9045
- return setShowOverflowMenu(false);
9046
- },
9047
- position: "absolute top-full right-0 mt-1",
9048
- portal: true,
9049
- align: "right",
9050
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.DropdownPanel.Header, {
9051
- children: "Actions"
9052
- }), overflowActions.map(function (action) {
9053
- return /*#__PURE__*/jsxRuntime.jsxs(DashReact.MenuItem2, {
9054
- onClick: action.onClick,
9055
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
9056
- icon: action.icon,
9057
- className: "w-4 text-center opacity-60"
9058
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
9059
- children: action.label
9060
- })]
9061
- }, action.label);
9062
- })]
9063
- })]
9064
- }) : null
9065
- })]
9066
- });
9067
- };
9068
-
9069
- /**
9070
- * WidgetCard
9071
- *
9072
- * Wrapper component for widgets that provides:
9073
- * - Header with drag handle, provider controls, actions (edit mode only)
9074
- * - Body with padding around widget content (edit mode only)
9075
- * - Footer for future features (edit mode only)
9076
- *
9077
- * In preview mode (preview === true):
9078
- * - Only renders the widget content without any wrapper
9079
- *
9080
- * In edit mode (preview === false):
9081
- * - Renders header + padded content + optional footer
9082
- */
9083
-
9084
- var WidgetCardContext = /*#__PURE__*/React.createContext({
9085
- preview: false
9086
- });
9087
-
9088
- /**
9089
- * WidgetCard.Header - Header section with controls
9090
- * Only renders in edit mode (preview === false)
9091
- */
9092
- var WidgetCardHeader_Component = function WidgetCardHeader_Component(_ref) {
9093
- var item = _ref.item,
9094
- _ref$cellNumber = _ref.cellNumber,
9095
- cellNumber = _ref$cellNumber === void 0 ? null : _ref$cellNumber,
9096
- _ref$providers = _ref.providers,
9097
- providers = _ref$providers === void 0 ? [] : _ref$providers,
9098
- _ref$selectedProvider = _ref.selectedProviders,
9099
- selectedProviders = _ref$selectedProvider === void 0 ? {} : _ref$selectedProvider,
9100
- onProviderChange = _ref.onProviderChange,
9101
- onConfigure = _ref.onConfigure,
9102
- onDelete = _ref.onDelete,
9103
- _ref$onSplitHorizonta = _ref.onSplitHorizontal,
9104
- onSplitHorizontal = _ref$onSplitHorizonta === void 0 ? null : _ref$onSplitHorizonta,
9105
- _ref$onSplitVertical = _ref.onSplitVertical,
9106
- onSplitVertical = _ref$onSplitVertical === void 0 ? null : _ref$onSplitVertical,
9107
- _ref$isSelected = _ref.isSelected,
9108
- isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
9109
- _ref$isSelectable = _ref.isSelectable,
9110
- isSelectable = _ref$isSelectable === void 0 ? true : _ref$isSelectable,
9111
- _ref$onToggleSelect = _ref.onToggleSelect,
9112
- onToggleSelect = _ref$onToggleSelect === void 0 ? null : _ref$onToggleSelect;
9113
- var _React$useContext = React.useContext(WidgetCardContext),
9114
- preview = _React$useContext.preview;
9115
-
9116
- // Don't render header in preview mode
9117
- if (preview === true) {
9118
- return null;
9119
- }
9120
- return /*#__PURE__*/jsxRuntime.jsx(WidgetCardHeader, {
9121
- item: item,
9122
- cellNumber: cellNumber,
9123
- providers: providers,
9124
- selectedProviders: selectedProviders,
9125
- onProviderChange: onProviderChange,
9126
- onConfigure: onConfigure,
9127
- onDelete: onDelete,
9128
- onSplitHorizontal: onSplitHorizontal,
9129
- onSplitVertical: onSplitVertical,
9130
- isSelected: isSelected,
9131
- isSelectable: isSelectable,
9132
- onToggleSelect: onToggleSelect
9133
- });
9134
- };
9135
-
9136
- /**
9137
- * WidgetCard.Body - Body section with widget content
9138
- * In edit mode: adds padding around content
9139
- * In preview mode: renders content without padding
9140
- */
9141
- var WidgetCardBody = function WidgetCardBody(_ref2) {
9142
- var children = _ref2.children,
9143
- _ref2$padding = _ref2.padding,
9144
- padding = _ref2$padding === void 0 ? "p-2" : _ref2$padding,
9145
- _ref2$className = _ref2.className,
9146
- className = _ref2$className === void 0 ? "" : _ref2$className;
9147
- var _React$useContext2 = React.useContext(WidgetCardContext),
9148
- preview = _React$useContext2.preview;
9149
-
9150
- // In preview mode, render children without padding wrapper
9151
- if (preview === true) {
9152
- return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
9153
- children: children
9154
- });
9155
- }
9156
-
9157
- // In edit mode, render with padding
9158
- return /*#__PURE__*/jsxRuntime.jsx("div", {
9159
- className: "flex-1 min-h-0 overflow-auto ".concat(padding, " ").concat(className),
9160
- children: children
9161
- });
9162
- };
9163
-
9164
- /**
9165
- * WidgetCard.Footer - Footer section with handler warnings
9166
- * Only renders in edit mode (preview === false)
9167
- * Shows amber warning when widget has eventHandlers that lack listener connections
9168
- */
9169
- var WidgetCardFooter = function WidgetCardFooter(_ref3) {
9170
- var children = _ref3.children,
9171
- _ref3$item = _ref3.item,
9172
- item = _ref3$item === void 0 ? null : _ref3$item,
9173
- _ref3$onConfigure = _ref3.onConfigure,
9174
- onConfigure = _ref3$onConfigure === void 0 ? null : _ref3$onConfigure,
9175
- _ref3$className = _ref3.className,
9176
- className = _ref3$className === void 0 ? "" : _ref3$className;
9177
- var _React$useContext3 = React.useContext(WidgetCardContext),
9178
- preview = _React$useContext3.preview;
9179
- if (preview === true) return null;
9180
-
9181
- // Compute unconfigured handlers
9182
- var widgetConfig = item !== null && item !== void 0 && item.component ? ComponentManager.config(item.component, item) : null;
9183
- var eventHandlers = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.eventHandlers) || [];
9184
- var listeners = (item === null || item === void 0 ? void 0 : item.listeners) || {};
9185
- var unconfiguredCount = eventHandlers.filter(function (h) {
9186
- return !listeners[h] || listeners[h].length === 0;
9187
- }).length;
9188
-
9189
- // Don't render if no children AND no warnings
9190
- if (!children && unconfiguredCount === 0) return null;
9191
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
9192
- className: "border-t border-gray-700 px-3 py-1.5 bg-transparent ".concat(className),
9193
- children: [children, unconfiguredCount > 0 && /*#__PURE__*/jsxRuntime.jsxs("button", {
9194
- type: "button",
9195
- onClick: function onClick() {
9196
- return onConfigure && onConfigure(item, "handlers");
9197
- },
9198
- className: "inline-flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium border bg-amber-900/20 border-amber-700/50 text-amber-400 hover:bg-amber-900/30 hover:border-amber-600/50 transition-all cursor-pointer",
9199
- title: "Click to configure listeners",
9200
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
9201
- icon: "phone",
9202
- className: "text-[10px]"
9203
- }), /*#__PURE__*/jsxRuntime.jsxs("span", {
9204
- children: [unconfiguredCount, " listener", unconfiguredCount > 1 ? "s" : "", " not connected"]
9205
- })]
9206
- })]
9207
- });
9208
- };
9209
-
9210
- /**
9211
- * WidgetCard - Main wrapper component
9212
- *
9213
- * In preview mode: renders children without any wrapper
9214
- * In edit mode: wraps children in a container
9215
- */
9216
- var WidgetCard = function WidgetCard(_ref4) {
9217
- var _ref4$preview = _ref4.preview,
9218
- preview = _ref4$preview === void 0 ? false : _ref4$preview,
9219
- children = _ref4.children,
9220
- _ref4$className = _ref4.className,
9221
- className = _ref4$className === void 0 ? "" : _ref4$className;
9222
- // In preview mode, render children without wrapper
9223
- if (preview === true) {
9224
- return /*#__PURE__*/jsxRuntime.jsx(WidgetCardContext.Provider, {
9225
- value: {
9226
- preview: preview
9227
- },
9228
- children: children
9229
- });
9230
- }
9231
-
9232
- // In edit mode, render with wrapper (no padding - Body handles padding)
9233
- return /*#__PURE__*/jsxRuntime.jsx(WidgetCardContext.Provider, {
9234
- value: {
9235
- preview: preview
9236
- },
9237
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
9238
- className: "flex flex-col w-full h-full min-h-0 overflow-hidden rounded border border-dashed border-gray-700 ".concat(className),
9239
- children: children
9240
- })
9241
- });
9242
- };
9243
-
9244
- // Attach subcomponents
9245
- WidgetCard.Header = WidgetCardHeader_Component;
9246
- WidgetCard.Body = WidgetCardBody;
9247
- WidgetCard.Footer = WidgetCardFooter;
9248
-
9249
- var ProviderSelector = function ProviderSelector(_ref) {
9250
- var isOpen = _ref.isOpen,
9251
- setIsOpen = _ref.setIsOpen,
9252
- providerType = _ref.providerType,
9253
- _ref$existingProvider = _ref.existingProviders,
9254
- existingProviders = _ref$existingProvider === void 0 ? [] : _ref$existingProvider,
9255
- _ref$credentialSchema = _ref.credentialSchema,
9256
- credentialSchema = _ref$credentialSchema === void 0 ? {} : _ref$credentialSchema,
9257
- onSelect = _ref.onSelect,
9258
- onCreate = _ref.onCreate;
9259
- var _useState = React.useState("select"),
9260
- _useState2 = _slicedToArray(_useState, 2),
9261
- activeTab = _useState2[0],
9262
- setActiveTab = _useState2[1]; // "select" or "create"
9263
-
9264
- /**
9265
- * Filter providers by type
9266
- */
9267
- var filteredProviders = existingProviders.filter(function (p) {
9268
- return p.type === providerType;
9269
- });
9270
-
9271
- /**
9272
- * Handle provider selection
9273
- */
9274
- var handleSelectProvider = function handleSelectProvider(providerName) {
9275
- onSelect(providerName);
9276
- setIsOpen(false);
9277
- };
9278
-
9279
- /**
9280
- * Handle new provider creation
9281
- */
9282
- var handleCreateProvider = function handleCreateProvider(formData) {
9283
- // formData now contains { name, credentials }
9284
- var providerName = formData.name,
9285
- credentials = formData.credentials;
9286
- onCreate(providerName, credentials);
9287
- setIsOpen(false);
9288
- };
9289
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
9290
- isOpen: isOpen,
9291
- setIsOpen: setIsOpen,
9292
- width: "w-11/12 xl:w-5/6",
9293
- height: "h-5/6",
9294
- children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Panel, {
9295
- border: true,
9296
- padding: false,
9297
- backgroundColor: "bg-gray-800",
9298
- borderColor: "border-gray-700",
9299
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Header, {
9300
- border: true,
9301
- borderColor: "border-gray-700",
9302
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
9303
- className: "flex flex-col w-full space-y-4",
9304
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9305
- className: "flex flex-row justify-between items-start",
9306
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9307
- className: "flex-1",
9308
- children: [/*#__PURE__*/jsxRuntime.jsx("h2", {
9309
- className: "text-2xl font-bold text-gray-100",
9310
- children: providerType ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
9311
- children: ["Manage ", /*#__PURE__*/jsxRuntime.jsx("span", {
9312
- className: "capitalize",
9313
- children: providerType
9314
- }), " ", "Providers"]
9315
- }) : "Select Provider"
9316
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
9317
- className: "text-sm text-gray-400 mt-1",
9318
- children: activeTab === "select" ? "Select an existing ".concat(providerType, " provider or create a new one") : "Create a new ".concat(providerType, " provider")
9319
- })]
9320
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
9321
- onClick: function onClick() {
9322
- return setIsOpen(false);
9323
- },
9324
- className: "ml-4 text-gray-400 hover:text-gray-200 transition-colors",
9325
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
9326
- icon: "times",
9327
- className: "text-xl"
9328
- })
9329
- })]
9330
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9331
- className: "flex gap-2",
9332
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9333
- title: "Select Existing (".concat(filteredProviders.length, ")"),
9334
- onClick: function onClick() {
9335
- return setActiveTab("select");
9336
- },
9337
- backgroundColor: activeTab === "select" ? "bg-blue-600" : "bg-gray-700",
9338
- hoverBackgroundColor: activeTab === "select" ? "hover:bg-blue-700" : "hover:bg-gray-600",
9339
- padding: "px-4 py-2",
9340
- textSize: "text-sm"
9341
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
9342
- title: "Create New",
9343
- onClick: function onClick() {
9344
- return setActiveTab("create");
9345
- },
9346
- backgroundColor: activeTab === "create" ? "bg-blue-600" : "bg-gray-700",
9347
- hoverBackgroundColor: activeTab === "create" ? "hover:bg-blue-700" : "hover:bg-gray-600",
9348
- padding: "px-4 py-2",
9349
- textSize: "text-sm"
9350
- })]
9351
- })]
9352
- })
9353
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Body, {
9354
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
9355
- className: "h-full overflow-y-auto",
9356
- children: activeTab === "select" ?
9357
- /*#__PURE__*/
9358
- // Select Tab
9359
- jsxRuntime.jsx("div", {
9360
- className: "p-6",
9361
- children: filteredProviders.length > 0 ? /*#__PURE__*/jsxRuntime.jsx("div", {
9362
- className: "space-y-3",
9363
- children: filteredProviders.map(function (provider) {
9364
- return /*#__PURE__*/jsxRuntime.jsxs("button", {
9365
- onClick: function onClick() {
9366
- return handleSelectProvider(provider.name);
9367
- },
9368
- className: "w-full text-left p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:border-blue-400 dark:hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-all",
9369
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
9370
- className: "font-semibold",
9371
- children: provider.name
9372
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
9373
- className: "text-sm opacity-70 mt-1",
9374
- children: ["Type:", " ", /*#__PURE__*/jsxRuntime.jsx("span", {
9375
- className: "capitalize",
9376
- children: provider.type
9377
- })]
9378
- }), provider.credentials && Object.keys(provider.credentials).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
9379
- className: "text-xs opacity-50 mt-2",
9380
- children: ["Fields:", " ", Object.keys(provider.credentials).join(", ")]
9381
- })]
9382
- }, provider.name);
9383
- })
9384
- }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
9385
- className: "text-center py-12",
9386
- children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.SubHeading3, {
9387
- className: "opacity-50",
9388
- children: ["No ", providerType, " providers found"]
9389
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
9390
- className: "mt-2 opacity-70",
9391
- children: "Create one using the \"Create New\" tab"
9936
+ theme: false
9937
+ })]
9938
+ }) : overflowActions.length > 0 ? /*#__PURE__*/jsxRuntime.jsxs("div", {
9939
+ className: "relative",
9940
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon2, {
9941
+ icon: "chevron-down",
9942
+ onClick: function onClick() {
9943
+ setShowProviderDropdown(null);
9944
+ setShowOverflowMenu(!showOverflowMenu);
9945
+ },
9946
+ title: "Actions",
9947
+ theme: false
9948
+ }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.DropdownPanel, {
9949
+ isOpen: showOverflowMenu,
9950
+ onClose: function onClose() {
9951
+ return setShowOverflowMenu(false);
9952
+ },
9953
+ position: "absolute top-full right-0 mt-1",
9954
+ portal: true,
9955
+ align: "right",
9956
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.DropdownPanel.Header, {
9957
+ children: "Actions"
9958
+ }), overflowActions.map(function (action) {
9959
+ return /*#__PURE__*/jsxRuntime.jsxs(DashReact.MenuItem2, {
9960
+ onClick: action.onClick,
9961
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
9962
+ icon: action.icon,
9963
+ className: "w-4 text-center opacity-60"
9964
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
9965
+ children: action.label
9392
9966
  })]
9393
- })
9394
- }) :
9395
- /*#__PURE__*/
9396
- // Create Tab
9397
- jsxRuntime.jsx(ProviderForm, {
9398
- credentialSchema: credentialSchema,
9399
- onSubmit: handleCreateProvider,
9400
- onCancel: function onCancel() {
9401
- return setIsOpen(false);
9402
- },
9403
- submitLabel: "Create Provider",
9404
- providerType: providerType
9405
- })
9406
- })
9407
- })]
9408
- })
9967
+ }, action.label);
9968
+ })]
9969
+ })]
9970
+ }) : null
9971
+ })]
9409
9972
  });
9410
9973
  };
9411
9974
 
9412
- function ownKeys$q(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; }
9413
- function _objectSpread$q(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$q(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$q(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9414
9975
  /**
9415
- * Shared MCP utility functions.
9976
+ * WidgetCard
9416
9977
  *
9417
- * Extracted from McpServerPicker so ProviderDetail (and any future consumer)
9418
- * can reuse the same field-derivation logic.
9419
- */
9420
-
9421
- /**
9422
- * Derive required form fields from an mcpConfig, using credentialSchema
9423
- * as optional enrichment for display names, instructions, and secret flags.
9978
+ * Wrapper component for widgets that provides:
9979
+ * - Header with drag handle, provider controls, actions (edit mode only)
9980
+ * - Body with padding around widget content (edit mode only)
9981
+ * - Footer for future features (edit mode only)
9424
9982
  *
9425
- * For streamable_http: extracts {{placeholder}} fields from url and headerTemplate.
9426
- * For stdio: extracts credential field names from envMapping values.
9983
+ * In preview mode (preview === true):
9984
+ * - Only renders the widget content without any wrapper
9427
9985
  *
9428
- * @param {object} mcpConfig - The MCP server configuration
9429
- * @param {object} credentialSchema - Optional metadata for field labels/instructions
9430
- * @returns {Array<{ key, displayName, required, secret, instructions, type }>}
9986
+ * In edit mode (preview === false):
9987
+ * - Renders header + padded content + optional footer
9431
9988
  */
9432
- function deriveFormFields(mcpConfig) {
9433
- var credentialSchema = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9434
- var fieldKeys = new Set();
9435
- if (mcpConfig.transport === "streamable_http") {
9436
- // Extract {{field}} placeholders from url
9437
- if (mcpConfig.url) {
9438
- var urlMatches = mcpConfig.url.match(/\{\{(\w+)\}\}/g) || [];
9439
- urlMatches.forEach(function (m) {
9440
- return fieldKeys.add(m.slice(2, -2));
9441
- });
9442
- }
9443
- // Extract {{field}} placeholders from headerTemplate values
9444
- if (mcpConfig.headerTemplate) {
9445
- Object.values(mcpConfig.headerTemplate).forEach(function (template) {
9446
- var matches = template.match(/\{\{(\w+)\}\}/g) || [];
9447
- matches.forEach(function (m) {
9448
- return fieldKeys.add(m.slice(2, -2));
9449
- });
9450
- });
9451
- }
9452
- } else {
9453
- // stdio: extract credential field names from envMapping values
9454
- if (mcpConfig.envMapping) {
9455
- Object.values(mcpConfig.envMapping).forEach(function (credField) {
9456
- fieldKeys.add(credField);
9457
- });
9458
- }
9459
- }
9460
-
9461
- // Also include any fields defined in credentialSchema that aren't already derived
9462
- if (credentialSchema) {
9463
- Object.keys(credentialSchema).forEach(function (key) {
9464
- return fieldKeys.add(key);
9465
- });
9466
- }
9467
-
9468
- // Build the field list with metadata from credentialSchema or auto-generated defaults
9469
- return Array.from(fieldKeys).map(function (key) {
9470
- var schemaMeta = credentialSchema[key];
9471
- if (schemaMeta) {
9472
- return {
9473
- key: key,
9474
- displayName: schemaMeta.displayName || formatFieldName(key),
9475
- required: schemaMeta.required === true,
9476
- secret: schemaMeta.secret || false,
9477
- instructions: schemaMeta.instructions || null,
9478
- type: schemaMeta.type || "text"
9479
- };
9480
- }
9481
9989
 
9482
- // Auto-generate defaults from the field name
9483
- return {
9484
- key: key,
9485
- displayName: formatFieldName(key),
9486
- required: false,
9487
- secret: isLikelySecret(key),
9488
- instructions: null,
9489
- type: "text"
9490
- };
9491
- });
9492
- }
9990
+ var WidgetCardContext = /*#__PURE__*/React.createContext({
9991
+ preview: false
9992
+ });
9493
9993
 
9494
9994
  /**
9495
- * Convert a camelCase field name to a human-readable title.
9496
- * e.g., "apiKey" "API Key", "url" "URL", "botToken" → "Bot Token"
9995
+ * WidgetCard.Header - Header section with controls
9996
+ * Only renders in edit mode (preview === false)
9497
9997
  */
9498
- function formatFieldName(name) {
9499
- var acronyms = {
9500
- url: "URL",
9501
- api: "API",
9502
- id: "ID",
9503
- mcp: "MCP"
9504
- };
9505
- return name.replace(/([A-Z])/g, " $1").replace(/^./, function (s) {
9506
- return s.toUpperCase();
9507
- }).trim().split(" ").map(function (word) {
9508
- return acronyms[word.toLowerCase()] || word;
9509
- }).join(" ");
9510
- }
9998
+ var WidgetCardHeader_Component = function WidgetCardHeader_Component(_ref) {
9999
+ var item = _ref.item,
10000
+ _ref$cellNumber = _ref.cellNumber,
10001
+ cellNumber = _ref$cellNumber === void 0 ? null : _ref$cellNumber,
10002
+ _ref$providers = _ref.providers,
10003
+ providers = _ref$providers === void 0 ? [] : _ref$providers,
10004
+ _ref$selectedProvider = _ref.selectedProviders,
10005
+ selectedProviders = _ref$selectedProvider === void 0 ? {} : _ref$selectedProvider,
10006
+ onProviderChange = _ref.onProviderChange,
10007
+ onConfigure = _ref.onConfigure,
10008
+ onDelete = _ref.onDelete,
10009
+ _ref$onSplitHorizonta = _ref.onSplitHorizontal,
10010
+ onSplitHorizontal = _ref$onSplitHorizonta === void 0 ? null : _ref$onSplitHorizonta,
10011
+ _ref$onSplitVertical = _ref.onSplitVertical,
10012
+ onSplitVertical = _ref$onSplitVertical === void 0 ? null : _ref$onSplitVertical,
10013
+ _ref$isSelected = _ref.isSelected,
10014
+ isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
10015
+ _ref$isSelectable = _ref.isSelectable,
10016
+ isSelectable = _ref$isSelectable === void 0 ? true : _ref$isSelectable,
10017
+ _ref$onToggleSelect = _ref.onToggleSelect,
10018
+ onToggleSelect = _ref$onToggleSelect === void 0 ? null : _ref$onToggleSelect;
10019
+ var _React$useContext = React.useContext(WidgetCardContext),
10020
+ preview = _React$useContext.preview;
9511
10021
 
9512
- /**
9513
- * Heuristic: does this field name likely contain a secret value?
9514
- */
9515
- function isLikelySecret(name) {
9516
- var lower = name.toLowerCase();
9517
- return /key|token|secret|password|credential|auth/.test(lower);
9518
- }
10022
+ // Don't render header in preview mode
10023
+ if (preview === true) {
10024
+ return null;
10025
+ }
10026
+ return /*#__PURE__*/jsxRuntime.jsx(WidgetCardHeader, {
10027
+ item: item,
10028
+ cellNumber: cellNumber,
10029
+ providers: providers,
10030
+ selectedProviders: selectedProviders,
10031
+ onProviderChange: onProviderChange,
10032
+ onConfigure: onConfigure,
10033
+ onDelete: onDelete,
10034
+ onSplitHorizontal: onSplitHorizontal,
10035
+ onSplitVertical: onSplitVertical,
10036
+ isSelected: isSelected,
10037
+ isSelectable: isSelectable,
10038
+ onToggleSelect: onToggleSelect
10039
+ });
10040
+ };
9519
10041
 
9520
10042
  /**
9521
- * Build an mcpConfig by overlaying advanced-section rows onto a catalog base config.
9522
- *
9523
- * For stdio: replaces `envMapping` with the rows from the advanced section.
9524
- * For streamable_http: replaces `headerTemplate` with the rows from the advanced section.
9525
- *
9526
- * @param {object} baseMcpConfig - The catalog's original mcpConfig
9527
- * @param {Array<{ envVar: string, credField: string }>} envMappingRows - Current env var rows
9528
- * @param {Array<{ headerName: string, headerValue: string }>} headerRows - Current header rows
9529
- * @returns {object} A new mcpConfig with overridden envMapping or headerTemplate
10043
+ * WidgetCard.Body - Body section with widget content
10044
+ * In edit mode: adds padding around content
10045
+ * In preview mode: renders content without padding
9530
10046
  */
9531
- function buildMcpConfigFromOverrides(baseMcpConfig, envMappingRows, headerRows) {
9532
- if (baseMcpConfig.transport === "streamable_http") {
9533
- var headerTemplate = {};
9534
- headerRows.forEach(function (row) {
9535
- var name = row.headerName.trim();
9536
- var value = row.headerValue.trim();
9537
- if (name && value) {
9538
- headerTemplate[name] = value;
9539
- }
9540
- });
9541
- var config = _objectSpread$q({}, baseMcpConfig);
9542
- if (Object.keys(headerTemplate).length > 0) {
9543
- config.headerTemplate = headerTemplate;
9544
- } else {
9545
- delete config.headerTemplate;
9546
- }
9547
- return config;
9548
- }
10047
+ var WidgetCardBody = function WidgetCardBody(_ref2) {
10048
+ var children = _ref2.children,
10049
+ _ref2$padding = _ref2.padding,
10050
+ padding = _ref2$padding === void 0 ? "p-2" : _ref2$padding,
10051
+ _ref2$className = _ref2.className,
10052
+ className = _ref2$className === void 0 ? "" : _ref2$className;
10053
+ var _React$useContext2 = React.useContext(WidgetCardContext),
10054
+ preview = _React$useContext2.preview;
9549
10055
 
9550
- // stdio
9551
- var envMapping = {};
9552
- envMappingRows.forEach(function (row) {
9553
- var env = row.envVar.trim();
9554
- var cred = row.credField.trim();
9555
- if (env && cred) {
9556
- envMapping[env] = cred;
9557
- }
9558
- });
9559
- return _objectSpread$q(_objectSpread$q({}, baseMcpConfig), {}, {
9560
- envMapping: envMapping
9561
- });
9562
- }
10056
+ // In preview mode, render children without padding wrapper
10057
+ if (preview === true) {
10058
+ return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
10059
+ children: children
10060
+ });
10061
+ }
9563
10062
 
9564
- /**
9565
- * Convert an envMapping object into row state for the advanced config UI.
9566
- *
9567
- * @param {object} envMapping - e.g. { SLACK_BOT_TOKEN: "botToken" }
9568
- * @param {Function} nextRowId - Function that returns a unique row ID
9569
- * @returns {Array<{ id: string, envVar: string, credField: string }>}
9570
- */
9571
- function envMappingToRows(envMapping, nextRowId) {
9572
- if (!envMapping) return [];
9573
- return Object.entries(envMapping).map(function (_ref) {
9574
- var _ref2 = _slicedToArray(_ref, 2),
9575
- envVar = _ref2[0],
9576
- credField = _ref2[1];
9577
- return {
9578
- id: nextRowId(),
9579
- envVar: envVar,
9580
- credField: credField
9581
- };
10063
+ // In edit mode, render with padding
10064
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
10065
+ className: "flex-1 min-h-0 overflow-auto ".concat(padding, " ").concat(className),
10066
+ children: children
9582
10067
  });
9583
- }
10068
+ };
9584
10069
 
9585
10070
  /**
9586
- * Convert a headerTemplate object into row state for the advanced config UI.
9587
- *
9588
- * @param {object} headerTemplate - e.g. { "Authorization": "Bearer {{apiKey}}" }
9589
- * @param {Function} nextRowId - Function that returns a unique row ID
9590
- * @returns {Array<{ id: string, headerName: string, headerValue: string }>}
10071
+ * WidgetCard.Footer - Footer section with handler warnings
10072
+ * Only renders in edit mode (preview === false)
10073
+ * Shows amber warning when widget has eventHandlers that lack listener connections
9591
10074
  */
9592
- function headerTemplateToRows(headerTemplate, nextRowId) {
9593
- if (!headerTemplate) return [];
9594
- return Object.entries(headerTemplate).map(function (_ref3) {
9595
- var _ref4 = _slicedToArray(_ref3, 2),
9596
- headerName = _ref4[0],
9597
- headerValue = _ref4[1];
9598
- return {
9599
- id: nextRowId(),
9600
- headerName: headerName,
9601
- headerValue: headerValue
9602
- };
10075
+ var WidgetCardFooter = function WidgetCardFooter(_ref3) {
10076
+ var children = _ref3.children,
10077
+ _ref3$item = _ref3.item,
10078
+ item = _ref3$item === void 0 ? null : _ref3$item,
10079
+ _ref3$onConfigure = _ref3.onConfigure,
10080
+ onConfigure = _ref3$onConfigure === void 0 ? null : _ref3$onConfigure,
10081
+ _ref3$className = _ref3.className,
10082
+ className = _ref3$className === void 0 ? "" : _ref3$className;
10083
+ var _React$useContext3 = React.useContext(WidgetCardContext),
10084
+ preview = _React$useContext3.preview;
10085
+ if (preview === true) return null;
10086
+
10087
+ // Compute unconfigured handlers
10088
+ var widgetConfig = item !== null && item !== void 0 && item.component ? ComponentManager.config(item.component, item) : null;
10089
+ var eventHandlers = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.eventHandlers) || [];
10090
+ var listeners = (item === null || item === void 0 ? void 0 : item.listeners) || {};
10091
+ var unconfiguredCount = eventHandlers.filter(function (h) {
10092
+ return !listeners[h] || listeners[h].length === 0;
10093
+ }).length;
10094
+
10095
+ // Don't render if no children AND no warnings
10096
+ if (!children && unconfiguredCount === 0) return null;
10097
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
10098
+ className: "border-t border-gray-700 px-3 py-1.5 bg-transparent ".concat(className),
10099
+ children: [children, unconfiguredCount > 0 && /*#__PURE__*/jsxRuntime.jsxs("button", {
10100
+ type: "button",
10101
+ onClick: function onClick() {
10102
+ return onConfigure && onConfigure(item, "handlers");
10103
+ },
10104
+ className: "inline-flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium border bg-amber-900/20 border-amber-700/50 text-amber-400 hover:bg-amber-900/30 hover:border-amber-600/50 transition-all cursor-pointer",
10105
+ title: "Click to configure listeners",
10106
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
10107
+ icon: "phone",
10108
+ className: "text-[10px]"
10109
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
10110
+ children: [unconfiguredCount, " listener", unconfiguredCount > 1 ? "s" : "", " not connected"]
10111
+ })]
10112
+ })]
9603
10113
  });
9604
- }
10114
+ };
9605
10115
 
9606
10116
  /**
9607
- * Serialize the current form state into a bare MCP JSON config string.
9608
- *
9609
- * Output format (stdio):
9610
- * {
9611
- * "type": "stdio",
9612
- * "command": "npx",
9613
- * "args": ["-y", "package-name"],
9614
- * "env": { "API_KEY": "${API_KEY}" }
9615
- * }
9616
- *
9617
- * Output format (HTTP):
9618
- * {
9619
- * "type": "streamable_http",
9620
- * "url": "https://example.com/mcp",
9621
- * "headerTemplate": { "Authorization": "Bearer {{apiKey}}" }
9622
- * }
9623
- *
9624
- * Credential values are NOT embedded — env values use ${FIELD_NAME} syntax
9625
- * to reference credential fields entered separately in the form.
10117
+ * WidgetCard - Main wrapper component
9626
10118
  *
9627
- * @param {string} name - The provider name (unused in output, kept for API compat)
9628
- * @param {string} transport - "stdio" or "streamable_http"
9629
- * @param {object} fields - { command, args, envMappingRows, url, headerRows }
9630
- * @returns {string} Formatted JSON string
10119
+ * In preview mode: renders children without any wrapper
10120
+ * In edit mode: wraps children in a container
9631
10121
  */
9632
- function formStateToMcpJson(name, transport, fields) {
9633
- var _fields$command = fields.command,
9634
- command = _fields$command === void 0 ? "" : _fields$command,
9635
- _fields$args = fields.args,
9636
- args = _fields$args === void 0 ? "" : _fields$args,
9637
- _fields$envMappingRow = fields.envMappingRows,
9638
- envMappingRows = _fields$envMappingRow === void 0 ? [] : _fields$envMappingRow,
9639
- _fields$url = fields.url,
9640
- url = _fields$url === void 0 ? "" : _fields$url,
9641
- _fields$headerRows = fields.headerRows,
9642
- headerRows = _fields$headerRows === void 0 ? [] : _fields$headerRows;
9643
- var serverConfig;
9644
- if (transport === "stdio") {
9645
- var argsArray = args.trim().split(/\s+/).filter(Boolean);
9646
- var env = {};
9647
- envMappingRows.forEach(function (row) {
9648
- var envVar = row.envVar.trim();
9649
- var credField = row.credField.trim();
9650
- if (envVar && credField) {
9651
- env[envVar] = "${".concat(credField, "}");
9652
- }
9653
- });
9654
- serverConfig = {
9655
- type: "stdio",
9656
- command: command.trim()
9657
- };
9658
- if (argsArray.length > 0) serverConfig.args = argsArray;
9659
- if (Object.keys(env).length > 0) serverConfig.env = env;
9660
- } else {
9661
- // streamable_http
9662
- serverConfig = {
9663
- type: "streamable_http",
9664
- url: url.trim()
9665
- };
9666
- var headerTemplate = {};
9667
- headerRows.forEach(function (row) {
9668
- var hName = row.headerName.trim();
9669
- var hValue = row.headerValue.trim();
9670
- if (hName && hValue) {
9671
- headerTemplate[hName] = hValue;
9672
- }
10122
+ var WidgetCard = function WidgetCard(_ref4) {
10123
+ var _ref4$preview = _ref4.preview,
10124
+ preview = _ref4$preview === void 0 ? false : _ref4$preview,
10125
+ children = _ref4.children,
10126
+ _ref4$className = _ref4.className,
10127
+ className = _ref4$className === void 0 ? "" : _ref4$className;
10128
+ // In preview mode, render children without wrapper
10129
+ if (preview === true) {
10130
+ return /*#__PURE__*/jsxRuntime.jsx(WidgetCardContext.Provider, {
10131
+ value: {
10132
+ preview: preview
10133
+ },
10134
+ children: children
9673
10135
  });
9674
- if (Object.keys(headerTemplate).length > 0) serverConfig.headerTemplate = headerTemplate;
9675
10136
  }
9676
- return JSON.stringify(serverConfig, null, 2);
9677
- }
9678
10137
 
9679
- /**
9680
- * Parse an MCP JSON config string back into form state.
9681
- *
9682
- * Accepts multiple input formats:
9683
- * - Bare config: { "command": ..., "args": [...], "env": { "KEY": "${FIELD}" } }
9684
- * - Wrapped: { "mcpServers": { "name": { ... } } } — unwraps and uses key as providerName
9685
- *
9686
- * Transport detection:
9687
- * - Explicit `type` or `transport` field
9688
- * - Inferred: `url` present → streamable_http, `command` present → stdio
9689
- *
9690
- * stdio env value parsing:
9691
- * - "${FIELD_NAME}" → envVar = key, credField = FIELD_NAME (reference syntax)
9692
- * - "literal-value" → envVar = key, credField = key, credentialData[key] = value
9693
- *
9694
- * @param {string} jsonString - The JSON to parse
9695
- * @param {Function} nextRowId - Function that returns a unique row ID
9696
- * @returns {{ providerName, transport, command, args, envMappingRows, url, headerRows, credentialData, error }}
9697
- */
9698
- function mcpJsonToFormState(jsonString, nextRowId) {
9699
- var parsed;
9700
- try {
9701
- parsed = JSON.parse(jsonString);
9702
- } catch (e) {
9703
- return {
9704
- error: "Invalid JSON: ".concat(e.message)
9705
- };
9706
- }
9707
- var providerName = "";
9708
- var serverConfig;
9709
- if (parsed.mcpServers && _typeof(parsed.mcpServers) === "object") {
9710
- var entries = Object.entries(parsed.mcpServers);
9711
- if (entries.length === 0) {
9712
- return {
9713
- error: "No server found in mcpServers"
9714
- };
9715
- }
9716
- var _entries$ = _slicedToArray(entries[0], 2);
9717
- providerName = _entries$[0];
9718
- serverConfig = _entries$[1];
9719
- } else if (parsed.command || parsed.url || parsed.type || parsed.transport) {
9720
- serverConfig = parsed;
9721
- } else {
9722
- return {
9723
- error: "Unrecognized format: expected a server config with command, url, or type"
9724
- };
9725
- }
10138
+ // In edit mode, render with wrapper (no padding - Body handles padding)
10139
+ return /*#__PURE__*/jsxRuntime.jsx(WidgetCardContext.Provider, {
10140
+ value: {
10141
+ preview: preview
10142
+ },
10143
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
10144
+ className: "flex flex-col w-full h-full min-h-0 overflow-hidden rounded border border-dashed border-gray-700 ".concat(className),
10145
+ children: children
10146
+ })
10147
+ });
10148
+ };
10149
+
10150
+ // Attach subcomponents
10151
+ WidgetCard.Header = WidgetCardHeader_Component;
10152
+ WidgetCard.Body = WidgetCardBody;
10153
+ WidgetCard.Footer = WidgetCardFooter;
10154
+
10155
+ var ProviderSelector = function ProviderSelector(_ref) {
10156
+ var isOpen = _ref.isOpen,
10157
+ setIsOpen = _ref.setIsOpen,
10158
+ providerType = _ref.providerType,
10159
+ _ref$existingProvider = _ref.existingProviders,
10160
+ existingProviders = _ref$existingProvider === void 0 ? [] : _ref$existingProvider,
10161
+ _ref$credentialSchema = _ref.credentialSchema,
10162
+ credentialSchema = _ref$credentialSchema === void 0 ? {} : _ref$credentialSchema,
10163
+ onSelect = _ref.onSelect,
10164
+ onCreate = _ref.onCreate;
10165
+ var _useState = React.useState("select"),
10166
+ _useState2 = _slicedToArray(_useState, 2),
10167
+ activeTab = _useState2[0],
10168
+ setActiveTab = _useState2[1]; // "select" or "create"
10169
+
10170
+ /**
10171
+ * Filter providers by type
10172
+ */
10173
+ var filteredProviders = existingProviders.filter(function (p) {
10174
+ return p.type === providerType;
10175
+ });
10176
+
10177
+ /**
10178
+ * Handle provider selection
10179
+ */
10180
+ var handleSelectProvider = function handleSelectProvider(providerName) {
10181
+ onSelect(providerName);
10182
+ setIsOpen(false);
10183
+ };
9726
10184
 
9727
- // Determine transport from type/transport field or infer from contents
9728
- var explicitType = serverConfig.type || serverConfig.transport;
9729
- var transport;
9730
- if (explicitType) {
9731
- transport = explicitType === "stdio" ? "stdio" : "streamable_http";
9732
- } else {
9733
- transport = serverConfig.url ? "streamable_http" : "stdio";
9734
- }
9735
- var result = {
9736
- providerName: providerName,
9737
- transport: transport,
9738
- command: "",
9739
- args: "",
9740
- envMappingRows: [],
9741
- url: "",
9742
- headerRows: [],
9743
- credentialData: {},
9744
- error: null
10185
+ /**
10186
+ * Handle new provider creation
10187
+ */
10188
+ var handleCreateProvider = function handleCreateProvider(formData) {
10189
+ // formData now contains { name, credentials }
10190
+ var providerName = formData.name,
10191
+ credentials = formData.credentials;
10192
+ onCreate(providerName, credentials);
10193
+ setIsOpen(false);
9745
10194
  };
9746
- if (transport === "stdio") {
9747
- result.command = serverConfig.command || "";
9748
- result.args = (serverConfig.args || []).join(" ");
9749
- if (serverConfig.env && _typeof(serverConfig.env) === "object") {
9750
- Object.entries(serverConfig.env).forEach(function (_ref5) {
9751
- var _ref6 = _slicedToArray(_ref5, 2),
9752
- envVar = _ref6[0],
9753
- value = _ref6[1];
9754
- // Check for ${FIELD_NAME} reference syntax
9755
- var refMatch = typeof value === "string" && value.match(/^\$\{(.+)\}$/);
9756
- if (refMatch) {
9757
- // Reference syntax — credField is the extracted name, no credential value
9758
- result.envMappingRows.push({
9759
- id: nextRowId(),
9760
- envVar: envVar,
9761
- credField: refMatch[1]
9762
- });
9763
- } else {
9764
- // Literal value — use envVar as credField and store the value
9765
- result.envMappingRows.push({
9766
- id: nextRowId(),
9767
- envVar: envVar,
9768
- credField: envVar
9769
- });
9770
- result.credentialData[envVar] = value || "";
9771
- }
9772
- });
9773
- }
9774
- } else {
9775
- result.url = serverConfig.url || "";
9776
- var headers = serverConfig.headers || serverConfig.headerTemplate || {};
9777
- if (_typeof(headers) === "object") {
9778
- Object.entries(headers).forEach(function (_ref7) {
9779
- var _ref8 = _slicedToArray(_ref7, 2),
9780
- headerName = _ref8[0],
9781
- headerValue = _ref8[1];
9782
- result.headerRows.push({
9783
- id: nextRowId(),
9784
- headerName: headerName,
9785
- headerValue: headerValue
9786
- });
9787
- });
9788
- }
9789
- }
9790
- return result;
9791
- }
10195
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
10196
+ isOpen: isOpen,
10197
+ setIsOpen: setIsOpen,
10198
+ width: "w-11/12 xl:w-5/6",
10199
+ height: "h-5/6",
10200
+ children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Panel, {
10201
+ border: true,
10202
+ padding: false,
10203
+ backgroundColor: "bg-gray-800",
10204
+ borderColor: "border-gray-700",
10205
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Header, {
10206
+ border: true,
10207
+ borderColor: "border-gray-700",
10208
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
10209
+ className: "flex flex-col w-full space-y-4",
10210
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10211
+ className: "flex flex-row justify-between items-start",
10212
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10213
+ className: "flex-1",
10214
+ children: [/*#__PURE__*/jsxRuntime.jsx("h2", {
10215
+ className: "text-2xl font-bold text-gray-100",
10216
+ children: providerType ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
10217
+ children: ["Manage ", /*#__PURE__*/jsxRuntime.jsx("span", {
10218
+ className: "capitalize",
10219
+ children: providerType
10220
+ }), " ", "Providers"]
10221
+ }) : "Select Provider"
10222
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
10223
+ className: "text-sm text-gray-400 mt-1",
10224
+ children: activeTab === "select" ? "Select an existing ".concat(providerType, " provider or create a new one") : "Create a new ".concat(providerType, " provider")
10225
+ })]
10226
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
10227
+ onClick: function onClick() {
10228
+ return setIsOpen(false);
10229
+ },
10230
+ className: "ml-4 text-gray-400 hover:text-gray-200 transition-colors",
10231
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
10232
+ icon: "times",
10233
+ className: "text-xl"
10234
+ })
10235
+ })]
10236
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
10237
+ className: "flex gap-2",
10238
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
10239
+ title: "Select Existing (".concat(filteredProviders.length, ")"),
10240
+ onClick: function onClick() {
10241
+ return setActiveTab("select");
10242
+ },
10243
+ backgroundColor: activeTab === "select" ? "bg-blue-600" : "bg-gray-700",
10244
+ hoverBackgroundColor: activeTab === "select" ? "hover:bg-blue-700" : "hover:bg-gray-600",
10245
+ padding: "px-4 py-2",
10246
+ textSize: "text-sm"
10247
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
10248
+ title: "Create New",
10249
+ onClick: function onClick() {
10250
+ return setActiveTab("create");
10251
+ },
10252
+ backgroundColor: activeTab === "create" ? "bg-blue-600" : "bg-gray-700",
10253
+ hoverBackgroundColor: activeTab === "create" ? "hover:bg-blue-700" : "hover:bg-gray-600",
10254
+ padding: "px-4 py-2",
10255
+ textSize: "text-sm"
10256
+ })]
10257
+ })]
10258
+ })
10259
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Body, {
10260
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
10261
+ className: "h-full overflow-y-auto",
10262
+ children: activeTab === "select" ?
10263
+ /*#__PURE__*/
10264
+ // Select Tab
10265
+ jsxRuntime.jsx("div", {
10266
+ className: "p-6",
10267
+ children: filteredProviders.length > 0 ? /*#__PURE__*/jsxRuntime.jsx("div", {
10268
+ className: "space-y-3",
10269
+ children: filteredProviders.map(function (provider) {
10270
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
10271
+ onClick: function onClick() {
10272
+ return handleSelectProvider(provider.name);
10273
+ },
10274
+ className: "w-full text-left p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:border-blue-400 dark:hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-all",
10275
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
10276
+ className: "font-semibold",
10277
+ children: provider.name
10278
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
10279
+ className: "text-sm opacity-70 mt-1",
10280
+ children: ["Type:", " ", /*#__PURE__*/jsxRuntime.jsx("span", {
10281
+ className: "capitalize",
10282
+ children: provider.type
10283
+ })]
10284
+ }), provider.credentials && Object.keys(provider.credentials).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
10285
+ className: "text-xs opacity-50 mt-2",
10286
+ children: ["Fields:", " ", Object.keys(provider.credentials).join(", ")]
10287
+ })]
10288
+ }, provider.name);
10289
+ })
10290
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
10291
+ className: "text-center py-12",
10292
+ children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.SubHeading3, {
10293
+ className: "opacity-50",
10294
+ children: ["No ", providerType, " providers found"]
10295
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
10296
+ className: "mt-2 opacity-70",
10297
+ children: "Create one using the \"Create New\" tab"
10298
+ })]
10299
+ })
10300
+ }) :
10301
+ /*#__PURE__*/
10302
+ // Create Tab
10303
+ jsxRuntime.jsx(ProviderForm, {
10304
+ credentialSchema: credentialSchema,
10305
+ onSubmit: handleCreateProvider,
10306
+ onCancel: function onCancel() {
10307
+ return setIsOpen(false);
10308
+ },
10309
+ submitLabel: "Create Provider",
10310
+ providerType: providerType
10311
+ })
10312
+ })
10313
+ })]
10314
+ })
10315
+ });
10316
+ };
9792
10317
 
9793
10318
  function ownKeys$p(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; }
9794
10319
  function _objectSpread$p(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$p(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$p(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -10000,7 +10525,8 @@ var McpServerPicker = function McpServerPicker(_ref) {
10000
10525
  var _testResult$tools;
10001
10526
  var isOpen = _ref.isOpen,
10002
10527
  setIsOpen = _ref.setIsOpen,
10003
- onSave = _ref.onSave;
10528
+ onSave = _ref.onSave,
10529
+ autoSelectId = _ref.autoSelectId;
10004
10530
  var appContext = React.useContext(AppContext);
10005
10531
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
10006
10532
  var _useState = React.useState([]),
@@ -10032,29 +10558,47 @@ var McpServerPicker = function McpServerPicker(_ref) {
10032
10558
  isLoadingCatalog = _useState12[0],
10033
10559
  setIsLoadingCatalog = _useState12[1];
10034
10560
 
10035
- // Configuration form state
10036
- var _useState13 = React.useState(""),
10561
+ // Stepper state
10562
+ var _useState13 = React.useState(0),
10037
10563
  _useState14 = _slicedToArray(_useState13, 2),
10038
- providerName = _useState14[0],
10039
- setProviderName = _useState14[1];
10040
- var _useState15 = React.useState({}),
10564
+ wizardStep = _useState14[0],
10565
+ setWizardStep = _useState14[1];
10566
+ var _useState15 = React.useState(false),
10041
10567
  _useState16 = _slicedToArray(_useState15, 2),
10042
- credentialData = _useState16[0],
10043
- setCredentialData = _useState16[1];
10044
- var _useState17 = React.useState({}),
10568
+ isAuthorizing = _useState16[0],
10569
+ setIsAuthorizing = _useState16[1];
10570
+ var _useState17 = React.useState(null),
10045
10571
  _useState18 = _slicedToArray(_useState17, 2),
10046
- formErrors = _useState18[0],
10047
- setFormErrors = _useState18[1];
10048
-
10049
- // Advanced config row state
10050
- var _useState19 = React.useState([]),
10572
+ authResult = _useState18[0],
10573
+ setAuthResult = _useState18[1];
10574
+ var _useState19 = React.useState(null),
10051
10575
  _useState20 = _slicedToArray(_useState19, 2),
10052
- envMappingRows = _useState20[0],
10053
- setEnvMappingRows = _useState20[1];
10054
- var _useState21 = React.useState([]),
10576
+ selectedTools = _useState20[0],
10577
+ setSelectedTools = _useState20[1];
10578
+
10579
+ // Configuration form state
10580
+ var _useState21 = React.useState(""),
10055
10581
  _useState22 = _slicedToArray(_useState21, 2),
10056
- headerRows = _useState22[0],
10057
- setHeaderRows = _useState22[1];
10582
+ providerName = _useState22[0],
10583
+ setProviderName = _useState22[1];
10584
+ var _useState23 = React.useState({}),
10585
+ _useState24 = _slicedToArray(_useState23, 2),
10586
+ credentialData = _useState24[0],
10587
+ setCredentialData = _useState24[1];
10588
+ var _useState25 = React.useState({}),
10589
+ _useState26 = _slicedToArray(_useState25, 2),
10590
+ formErrors = _useState26[0],
10591
+ setFormErrors = _useState26[1];
10592
+
10593
+ // Advanced config row state
10594
+ var _useState27 = React.useState([]),
10595
+ _useState28 = _slicedToArray(_useState27, 2),
10596
+ envMappingRows = _useState28[0],
10597
+ setEnvMappingRows = _useState28[1];
10598
+ var _useState29 = React.useState([]),
10599
+ _useState30 = _slicedToArray(_useState29, 2),
10600
+ headerRows = _useState30[0],
10601
+ setHeaderRows = _useState30[1];
10058
10602
  var rowIdRef = React.useRef(0);
10059
10603
  var nextRowId = function nextRowId() {
10060
10604
  return "pick_".concat(++rowIdRef.current);
@@ -10072,13 +10616,28 @@ var McpServerPicker = function McpServerPicker(_ref) {
10072
10616
  return deriveFormFields(effectiveMcpConfig, selectedServer.credentialSchema || {});
10073
10617
  }, [selectedServer, effectiveMcpConfig]);
10074
10618
 
10619
+ // Dynamic wizard steps based on whether auth is needed
10620
+ var hasAuth = !!(selectedServer !== null && selectedServer !== void 0 && selectedServer.authCommand);
10621
+ var wizardSteps = hasAuth ? ["configure", "authorize", "testTools"] : ["configure", "testTools"];
10622
+ var totalSteps = wizardSteps.length;
10623
+ var currentStepType = wizardSteps[wizardStep];
10624
+
10075
10625
  // Load catalog on open
10076
10626
  React.useEffect(function () {
10077
10627
  if (isOpen && dashApi && catalog.length === 0) {
10078
10628
  setIsLoadingCatalog(true);
10079
10629
  dashApi.mcpGetCatalog(function (event, result) {
10080
- setCatalog(result.catalog || []);
10630
+ var loadedCatalog = result.catalog || [];
10631
+ setCatalog(loadedCatalog);
10081
10632
  setIsLoadingCatalog(false);
10633
+
10634
+ // Auto-select if autoSelectId is provided
10635
+ if (autoSelectId) {
10636
+ var match = loadedCatalog.find(function (s) {
10637
+ return s.id === autoSelectId;
10638
+ });
10639
+ if (match) handleSelectServer(match);
10640
+ }
10082
10641
  }, function (event, err) {
10083
10642
  setIsLoadingCatalog(false);
10084
10643
  });
@@ -10086,6 +10645,17 @@ var McpServerPicker = function McpServerPicker(_ref) {
10086
10645
  // eslint-disable-next-line react-hooks/exhaustive-deps
10087
10646
  }, [isOpen, dashApi]);
10088
10647
 
10648
+ // Auto-select from already-loaded catalog when autoSelectId changes
10649
+ React.useEffect(function () {
10650
+ if (isOpen && autoSelectId && catalog.length > 0 && !isConfiguring) {
10651
+ var match = catalog.find(function (s) {
10652
+ return s.id === autoSelectId;
10653
+ });
10654
+ if (match) handleSelectServer(match);
10655
+ }
10656
+ // eslint-disable-next-line react-hooks/exhaustive-deps
10657
+ }, [isOpen, autoSelectId]);
10658
+
10089
10659
  // Filter catalog by search
10090
10660
  var filteredCatalog = catalog.filter(function (server) {
10091
10661
  if (!searchQuery) return true;
@@ -10095,15 +10665,33 @@ var McpServerPicker = function McpServerPicker(_ref) {
10095
10665
  });
10096
10666
  });
10097
10667
 
10668
+ // Wizard step navigation with validation gates
10669
+ var handleWizardStepChange = function handleWizardStepChange(newStep) {
10670
+ if (newStep < wizardStep) {
10671
+ setWizardStep(newStep);
10672
+ return;
10673
+ }
10674
+ if (currentStepType === "configure" && newStep > wizardStep) {
10675
+ if (!validateForm()) return;
10676
+ }
10677
+ if (currentStepType === "authorize" && newStep > wizardStep) {
10678
+ if (!(authResult !== null && authResult !== void 0 && authResult.success)) return;
10679
+ }
10680
+ setWizardStep(newStep);
10681
+ };
10682
+
10098
10683
  // Handle server selection -> show configuration form
10099
10684
  var handleSelectServer = function handleSelectServer(server) {
10100
10685
  var _server$mcpConfig, _server$mcpConfig2;
10101
10686
  setSelectedServer(server);
10102
10687
  setIsConfiguring(true);
10103
10688
  setTestResult(null);
10689
+ setAuthResult(null);
10104
10690
  setProviderName(server.name);
10105
10691
  setCredentialData({});
10106
10692
  setFormErrors({});
10693
+ setWizardStep(0);
10694
+ setSelectedTools(null);
10107
10695
  setEnvMappingRows(envMappingToRows((_server$mcpConfig = server.mcpConfig) === null || _server$mcpConfig === void 0 ? void 0 : _server$mcpConfig.envMapping, nextRowId));
10108
10696
  setHeaderRows(headerTemplateToRows((_server$mcpConfig2 = server.mcpConfig) === null || _server$mcpConfig2 === void 0 ? void 0 : _server$mcpConfig2.headerTemplate, nextRowId));
10109
10697
  };
@@ -10160,6 +10748,11 @@ var McpServerPicker = function McpServerPicker(_ref) {
10160
10748
  message: "Connected! Found ".concat((result.tools || []).length, " tools.")
10161
10749
  });
10162
10750
 
10751
+ // Pre-select all tools
10752
+ setSelectedTools((result.tools || []).map(function (t) {
10753
+ return t.name;
10754
+ }));
10755
+
10163
10756
  // Stop the test server
10164
10757
  dashApi.mcpStopServer(testName, function () {}, function () {});
10165
10758
  setIsTesting(false);
@@ -10172,33 +10765,66 @@ var McpServerPicker = function McpServerPicker(_ref) {
10172
10765
  });
10173
10766
  };
10174
10767
 
10768
+ // Handle authorize (OAuth browser flow)
10769
+ var handleAuthorize = function handleAuthorize() {
10770
+ if (!dashApi || !(selectedServer !== null && selectedServer !== void 0 && selectedServer.authCommand)) return;
10771
+ setIsAuthorizing(true);
10772
+ setAuthResult(null);
10773
+ dashApi.mcpRunAuth(effectiveMcpConfig, credentialData, selectedServer.authCommand, function (event, result) {
10774
+ if (result.error) {
10775
+ setAuthResult({
10776
+ success: false,
10777
+ message: result.message
10778
+ });
10779
+ } else {
10780
+ setAuthResult({
10781
+ success: true,
10782
+ message: "Authorized!"
10783
+ });
10784
+ }
10785
+ setIsAuthorizing(false);
10786
+ }, function (event, err) {
10787
+ setAuthResult({
10788
+ success: false,
10789
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Authorization failed"
10790
+ });
10791
+ setIsAuthorizing(false);
10792
+ });
10793
+ };
10794
+
10175
10795
  // Handle save - create the MCP provider
10176
10796
  var handleSaveProvider = function handleSaveProvider() {
10177
10797
  if (!selectedServer || !validateForm()) return;
10178
- onSave(providerName.trim(), selectedServer.id, credentialData, effectiveMcpConfig);
10798
+ onSave(providerName.trim(), selectedServer.id, credentialData, effectiveMcpConfig, selectedTools);
10179
10799
  handleClose();
10180
10800
  };
10181
10801
  var handleClose = function handleClose() {
10182
10802
  setSelectedServer(null);
10183
10803
  setIsConfiguring(false);
10184
10804
  setTestResult(null);
10805
+ setAuthResult(null);
10806
+ setSelectedTools(null);
10185
10807
  setSearchQuery("");
10186
10808
  setProviderName("");
10187
10809
  setCredentialData({});
10188
10810
  setFormErrors({});
10189
10811
  setEnvMappingRows([]);
10190
10812
  setHeaderRows([]);
10813
+ setWizardStep(0);
10191
10814
  setIsOpen(false);
10192
10815
  };
10193
10816
  var handleBack = function handleBack() {
10194
10817
  setSelectedServer(null);
10195
10818
  setIsConfiguring(false);
10196
10819
  setTestResult(null);
10820
+ setAuthResult(null);
10821
+ setSelectedTools(null);
10197
10822
  setProviderName("");
10198
10823
  setCredentialData({});
10199
10824
  setFormErrors({});
10200
10825
  setEnvMappingRows([]);
10201
10826
  setHeaderRows([]);
10827
+ setWizardStep(0);
10202
10828
  };
10203
10829
 
10204
10830
  // Prune credential data when form fields change (advanced config removed a field)
@@ -10334,153 +10960,268 @@ var McpServerPicker = function McpServerPicker(_ref) {
10334
10960
  })]
10335
10961
  }) :
10336
10962
  /*#__PURE__*/
10337
- // MCP Server Configuration Form
10963
+ // MCP Server Configuration — Stepper
10338
10964
  jsxRuntime.jsxs("div", {
10339
- className: "flex flex-col gap-6 p-6",
10340
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10341
- className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-3",
10342
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
10343
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
10344
- children: "MCP Server Connection"
10345
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
10346
- className: "space-y-2 text-sm",
10347
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10348
- className: "flex gap-2",
10349
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10350
- className: "opacity-50 w-24 shrink-0",
10351
- children: "Transport:"
10352
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
10353
- text: effectiveMcpConfig.transport === "streamable_http" ? "Streamable HTTP" : "stdio"
10354
- })]
10355
- }), effectiveMcpConfig.transport === "streamable_http" ? /*#__PURE__*/jsxRuntime.jsxs("div", {
10356
- className: "flex gap-2",
10357
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10358
- className: "opacity-50 w-24 shrink-0",
10359
- children: "Endpoint:"
10360
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
10361
- className: "text-xs opacity-70",
10362
- children: "Remote hosted server (URL provided below)"
10363
- })]
10364
- }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
10365
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10366
- className: "flex gap-2",
10367
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10368
- className: "opacity-50 w-24 shrink-0",
10369
- children: "Command:"
10370
- }), /*#__PURE__*/jsxRuntime.jsxs("code", {
10371
- className: "text-xs bg-white/5 px-2 py-0.5 rounded",
10372
- children: [effectiveMcpConfig.command, " ", (effectiveMcpConfig.args || []).join(" ")]
10965
+ className: "flex flex-col h-full",
10966
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
10967
+ className: "flex-1 min-h-0 flex flex-col",
10968
+ children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
10969
+ activeStep: wizardStep,
10970
+ onStepChange: handleWizardStepChange,
10971
+ showNavigation: false,
10972
+ className: "flex-1 min-h-0 flex flex-col px-6 pt-4",
10973
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
10974
+ label: "Configure",
10975
+ description: "Name & credentials",
10976
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
10977
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
10978
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10979
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-3",
10980
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
10981
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
10982
+ children: "MCP Server Connection"
10983
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
10984
+ className: "space-y-2 text-sm",
10985
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10986
+ className: "flex gap-2",
10987
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10988
+ className: "opacity-50 w-24 shrink-0",
10989
+ children: "Transport:"
10990
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
10991
+ text: effectiveMcpConfig.transport === "streamable_http" ? "Streamable HTTP" : "stdio"
10992
+ })]
10993
+ }), effectiveMcpConfig.transport === "streamable_http" ? /*#__PURE__*/jsxRuntime.jsxs("div", {
10994
+ className: "flex gap-2",
10995
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10996
+ className: "opacity-50 w-24 shrink-0",
10997
+ children: "Endpoint:"
10998
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
10999
+ className: "text-xs opacity-70",
11000
+ children: "Remote hosted server (URL provided below)"
11001
+ })]
11002
+ }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
11003
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
11004
+ className: "flex gap-2",
11005
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
11006
+ className: "opacity-50 w-24 shrink-0",
11007
+ children: "Command:"
11008
+ }), /*#__PURE__*/jsxRuntime.jsxs("code", {
11009
+ className: "text-xs bg-white/5 px-2 py-0.5 rounded",
11010
+ children: [effectiveMcpConfig.command, " ", (effectiveMcpConfig.args || []).join(" ")]
11011
+ })]
11012
+ }), effectiveMcpConfig.envMapping && Object.keys(effectiveMcpConfig.envMapping).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
11013
+ className: "flex gap-2",
11014
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
11015
+ className: "opacity-50 w-24 shrink-0",
11016
+ children: "Env Vars:"
11017
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
11018
+ className: "text-xs opacity-70",
11019
+ children: Object.keys(effectiveMcpConfig.envMapping).join(", ")
11020
+ })]
11021
+ })]
11022
+ })]
11023
+ })]
11024
+ }), /*#__PURE__*/jsxRuntime.jsx(AdvancedMcpConfig, {
11025
+ transport: effectiveMcpConfig.transport || "stdio",
11026
+ envMappingRows: envMappingRows,
11027
+ onEnvMappingRowsChange: setEnvMappingRows,
11028
+ headerRows: headerRows,
11029
+ onHeaderRowsChange: setHeaderRows
11030
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
11031
+ className: "flex flex-col gap-2",
11032
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
11033
+ label: "Provider Name",
11034
+ required: true
11035
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
11036
+ className: "text-sm opacity-50",
11037
+ children: "A name to identify this MCP server instance (e.g., \"Algolia Production\")"
11038
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
11039
+ value: providerName,
11040
+ onChange: function onChange(value) {
11041
+ setProviderName(value);
11042
+ if (formErrors.providerName && value !== null && value !== void 0 && value.trim()) {
11043
+ setFormErrors(function (prev) {
11044
+ var next = _objectSpread$o({}, prev);
11045
+ delete next.providerName;
11046
+ return next;
11047
+ });
11048
+ }
11049
+ },
11050
+ placeholder: "Enter provider name"
11051
+ }), formErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
11052
+ className: "text-sm text-red-400",
11053
+ children: formErrors.providerName
11054
+ })]
11055
+ }), formFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
11056
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
11057
+ className: "border-t border-white/10 pt-4",
11058
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
11059
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
11060
+ children: effectiveMcpConfig.transport === "streamable_http" ? "Server Configuration" : "Authentication"
11061
+ })
11062
+ }), formFields.map(function (field) {
11063
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
11064
+ className: "flex flex-col gap-2",
11065
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
11066
+ label: field.displayName,
11067
+ required: field.required
11068
+ }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
11069
+ className: "text-sm opacity-50",
11070
+ children: field.instructions
11071
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
11072
+ className: "flex gap-2",
11073
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
11074
+ className: "flex-1",
11075
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
11076
+ type: field.secret ? "password" : "text",
11077
+ value: credentialData[field.key] || "",
11078
+ onChange: function onChange(value) {
11079
+ return handleCredentialChange(field.key, value);
11080
+ },
11081
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
11082
+ })
11083
+ }), field.type === "file" && /*#__PURE__*/jsxRuntime.jsx("button", {
11084
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
11085
+ var filepath;
11086
+ return _regeneratorRuntime.wrap(function (_context) {
11087
+ while (1) switch (_context.prev = _context.next) {
11088
+ case 0:
11089
+ _context.next = 1;
11090
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
11091
+ case 1:
11092
+ filepath = _context.sent;
11093
+ if (filepath) handleCredentialChange(field.key, filepath);
11094
+ case 2:
11095
+ case "end":
11096
+ return _context.stop();
11097
+ }
11098
+ }, _callee);
11099
+ })),
11100
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
11101
+ children: "Browse"
11102
+ })]
11103
+ }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
11104
+ className: "text-sm text-red-400",
11105
+ children: formErrors[field.key]
11106
+ })]
11107
+ }, field.key);
11108
+ })]
10373
11109
  })]
10374
- }), effectiveMcpConfig.envMapping && Object.keys(effectiveMcpConfig.envMapping).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
10375
- className: "flex gap-2",
10376
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10377
- className: "opacity-50 w-24 shrink-0",
10378
- children: "Env Vars:"
10379
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
10380
- className: "text-xs opacity-70",
10381
- children: Object.keys(effectiveMcpConfig.envMapping).join(", ")
11110
+ })
11111
+ }), hasAuth && /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
11112
+ label: "Authorize",
11113
+ description: "OAuth authentication",
11114
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
11115
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
11116
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
11117
+ className: "flex flex-col items-center justify-center py-8 space-y-4",
11118
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
11119
+ className: "text-sm opacity-60 text-center max-w-md",
11120
+ children: "This server requires OAuth authorization. Click the button below to open a browser window and complete the authentication flow."
11121
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11122
+ title: isAuthorizing ? "Authorizing..." : "Authorize",
11123
+ onClick: handleAuthorize,
11124
+ size: "md"
11125
+ })]
11126
+ }), authResult && /*#__PURE__*/jsxRuntime.jsx("div", {
11127
+ 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"),
11128
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
11129
+ className: "flex items-center gap-2",
11130
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
11131
+ icon: authResult.success ? "circle-check" : "circle-exclamation"
11132
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
11133
+ children: authResult.message
11134
+ })]
11135
+ })
11136
+ }), authResult && !authResult.success && /*#__PURE__*/jsxRuntime.jsxs("div", {
11137
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-2",
11138
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
11139
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
11140
+ children: "Troubleshooting"
11141
+ }), /*#__PURE__*/jsxRuntime.jsxs("ul", {
11142
+ className: "text-sm opacity-60 space-y-1 list-disc list-inside",
11143
+ children: [/*#__PURE__*/jsxRuntime.jsx("li", {
11144
+ children: "Ensure Node.js and npx are available in your PATH"
11145
+ }), /*#__PURE__*/jsxRuntime.jsx("li", {
11146
+ children: "Try running the auth command manually in your terminal"
11147
+ }), /*#__PURE__*/jsxRuntime.jsx("li", {
11148
+ children: "Check that your OAuth credentials file is valid"
11149
+ }), /*#__PURE__*/jsxRuntime.jsx("li", {
11150
+ children: "If using nvm, ensure the correct Node version is active"
11151
+ })]
11152
+ })]
10382
11153
  })]
10383
- })]
11154
+ })
11155
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
11156
+ label: "Test & Tools",
11157
+ description: "Verify & select tools",
11158
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
11159
+ className: "flex-1 min-h-0 flex flex-col pb-4 space-y-4",
11160
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
11161
+ className: "flex items-center gap-3",
11162
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11163
+ title: isTesting ? "Fetching..." : "Fetch Tools",
11164
+ onClick: handleTestConnection,
11165
+ size: "sm"
11166
+ }), testResult && /*#__PURE__*/jsxRuntime.jsxs("span", {
11167
+ className: "text-sm ".concat(testResult.success ? "text-green-400" : "text-red-400"),
11168
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
11169
+ icon: testResult.success ? "circle-check" : "circle-exclamation",
11170
+ className: "mr-1"
11171
+ }), testResult.message]
11172
+ })]
11173
+ }), (testResult === null || testResult === void 0 ? void 0 : testResult.success) && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && selectedTools && /*#__PURE__*/jsxRuntime.jsx(ToolSelector, {
11174
+ tools: testResult.tools,
11175
+ selectedTools: selectedTools,
11176
+ onSelectionChange: setSelectedTools
11177
+ }), !testResult && /*#__PURE__*/jsxRuntime.jsx("div", {
11178
+ className: "text-center py-8 opacity-50",
11179
+ children: "Click \"Fetch Tools\" to test the connection and discover available tools."
11180
+ })]
11181
+ })
10384
11182
  })]
10385
- })]
10386
- }), /*#__PURE__*/jsxRuntime.jsx(AdvancedMcpConfig, {
10387
- transport: effectiveMcpConfig.transport || "stdio",
10388
- envMappingRows: envMappingRows,
10389
- onEnvMappingRowsChange: setEnvMappingRows,
10390
- headerRows: headerRows,
10391
- onHeaderRowsChange: setHeaderRows
11183
+ })
10392
11184
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
10393
- className: "flex flex-col gap-2",
10394
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
10395
- label: "Provider Name",
10396
- required: true
10397
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
10398
- className: "text-sm opacity-50",
10399
- children: "A name to identify this MCP server instance (e.g., \"Algolia Production\")"
10400
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
10401
- value: providerName,
10402
- onChange: function onChange(value) {
10403
- setProviderName(value);
10404
- if (formErrors.providerName && value !== null && value !== void 0 && value.trim()) {
10405
- setFormErrors(function (prev) {
10406
- var next = _objectSpread$o({}, prev);
10407
- delete next.providerName;
10408
- return next;
10409
- });
10410
- }
10411
- },
10412
- placeholder: "Enter provider name"
10413
- }), formErrors.providerName && /*#__PURE__*/jsxRuntime.jsx("p", {
10414
- className: "text-sm text-red-400",
10415
- children: formErrors.providerName
10416
- })]
10417
- }), formFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
10418
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
10419
- className: "border-t border-white/10 pt-4",
10420
- children: /*#__PURE__*/jsxRuntime.jsx("p", {
10421
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
10422
- children: effectiveMcpConfig.transport === "streamable_http" ? "Server Configuration" : "Authentication"
10423
- })
10424
- }), formFields.map(function (field) {
10425
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
10426
- className: "flex flex-col gap-2",
10427
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FormLabel, {
10428
- label: field.displayName,
10429
- required: field.required
10430
- }), field.instructions && /*#__PURE__*/jsxRuntime.jsx("p", {
10431
- className: "text-sm opacity-50",
10432
- children: field.instructions
10433
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
10434
- type: field.secret ? "password" : "text",
10435
- value: credentialData[field.key] || "",
10436
- onChange: function onChange(value) {
10437
- return handleCredentialChange(field.key, value);
10438
- },
10439
- placeholder: "Enter ".concat(field.displayName.toLowerCase())
10440
- }), formErrors[field.key] && /*#__PURE__*/jsxRuntime.jsx("p", {
10441
- className: "text-sm text-red-400",
10442
- children: formErrors[field.key]
10443
- })]
10444
- }, field.key);
10445
- })]
10446
- }), testResult && /*#__PURE__*/jsxRuntime.jsxs("div", {
10447
- 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"),
11185
+ className: "flex-shrink-0 flex flex-row items-center px-6 py-4 border-t border-white/10",
10448
11186
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
10449
- className: "flex items-center gap-2",
10450
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
10451
- icon: testResult.success ? "circle-check" : "circle-exclamation"
10452
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
10453
- children: testResult.message
11187
+ className: "flex flex-row gap-2",
11188
+ children: [wizardStep === 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11189
+ title: "Cancel",
11190
+ onClick: handleBack,
11191
+ size: "sm"
11192
+ }), wizardStep > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11193
+ title: "Back",
11194
+ onClick: function onClick() {
11195
+ return setWizardStep(wizardStep - 1);
11196
+ },
11197
+ size: "sm"
10454
11198
  })]
10455
- }), testResult.success && ((_testResult$tools = testResult.tools) === null || _testResult$tools === void 0 ? void 0 : _testResult$tools.length) > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
10456
- className: "mt-2 ml-6 space-y-1",
10457
- children: testResult.tools.map(function (tool) {
10458
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
10459
- className: "text-xs",
10460
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
10461
- className: "font-mono",
10462
- children: tool.name
10463
- }), tool.description && /*#__PURE__*/jsxRuntime.jsxs("span", {
10464
- className: "opacity-60 ml-2",
10465
- children: ["- ", tool.description]
10466
- })]
10467
- }, tool.name);
11199
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
11200
+ className: "flex-1 text-center",
11201
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
11202
+ className: "text-xs opacity-40",
11203
+ children: ["Step ", wizardStep + 1, " of ", totalSteps]
10468
11204
  })
10469
- })]
10470
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
10471
- className: "flex gap-3 justify-end pt-4 border-t border-white/10",
10472
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
10473
- title: "Cancel",
10474
- onClick: handleBack,
10475
- size: "sm"
10476
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
10477
- title: isTesting ? "Testing..." : "Test Connection",
10478
- onClick: handleTestConnection,
10479
- size: "sm"
10480
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
10481
- title: "Save MCP Server",
10482
- onClick: handleSaveProvider,
10483
- size: "sm"
11205
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
11206
+ className: "flex flex-row gap-2",
11207
+ children: [currentStepType === "configure" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11208
+ title: "Next",
11209
+ onClick: function onClick() {
11210
+ return handleWizardStepChange(wizardStep + 1);
11211
+ },
11212
+ size: "sm"
11213
+ }), currentStepType === "authorize" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11214
+ title: "Next",
11215
+ onClick: function onClick() {
11216
+ return handleWizardStepChange(wizardStep + 1);
11217
+ },
11218
+ disabled: !(authResult !== null && authResult !== void 0 && authResult.success),
11219
+ size: "sm"
11220
+ }), currentStepType === "testTools" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
11221
+ title: "Save MCP Server",
11222
+ onClick: handleSaveProvider,
11223
+ size: "sm"
11224
+ })]
10484
11225
  })]
10485
11226
  })]
10486
11227
  })
@@ -11037,7 +11778,7 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
11037
11778
  });
11038
11779
  }
11039
11780
  }
11040
- function handleMcpProviderSave(providerName, providerType, mcpCredentials, mcpConfig) {
11781
+ function handleMcpProviderSave(providerName, providerType, mcpCredentials, mcpConfig, allowedTools) {
11041
11782
  var _dashboardContext$cre2;
11042
11783
  var appId = dashboardContext === null || dashboardContext === void 0 || (_dashboardContext$cre2 = dashboardContext.credentials) === null || _dashboardContext$cre2 === void 0 ? void 0 : _dashboardContext$cre2.appId;
11043
11784
  if (dashboardContext !== null && dashboardContext !== void 0 && dashboardContext.dashApi && appId) {
@@ -11045,7 +11786,8 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
11045
11786
  providerType: providerType,
11046
11787
  credentials: mcpCredentials,
11047
11788
  providerClass: "mcp",
11048
- mcpConfig: mcpConfig
11789
+ mcpConfig: mcpConfig,
11790
+ allowedTools: allowedTools
11049
11791
  }, function () {
11050
11792
  handleSelectProvider(mcpPickerWidgetId, mcpPickerProviderType, providerName);
11051
11793
  setIsMcpPickerOpen(false);
@@ -11380,7 +12122,8 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
11380
12122
  }), /*#__PURE__*/jsxRuntime.jsx(McpServerPicker, {
11381
12123
  isOpen: isMcpPickerOpen,
11382
12124
  setIsOpen: setIsMcpPickerOpen,
11383
- onSave: handleMcpProviderSave
12125
+ onSave: handleMcpProviderSave,
12126
+ autoSelectId: mcpPickerProviderType
11384
12127
  })]
11385
12128
  })]
11386
12129
  }, "layout-builder")
@@ -25973,82 +26716,6 @@ var FoldersSection = function FoldersSection(_ref) {
25973
26716
  });
25974
26717
  };
25975
26718
 
25976
- var ToolSelector = function ToolSelector(_ref) {
25977
- var _ref$tools = _ref.tools,
25978
- tools = _ref$tools === void 0 ? [] : _ref$tools,
25979
- _ref$selectedTools = _ref.selectedTools,
25980
- selectedTools = _ref$selectedTools === void 0 ? [] : _ref$selectedTools,
25981
- onSelectionChange = _ref.onSelectionChange;
25982
- if (!tools || tools.length === 0) return null;
25983
- var allSelected = selectedTools.length === tools.length;
25984
- var handleToggleAll = function handleToggleAll() {
25985
- if (allSelected) {
25986
- onSelectionChange([]);
25987
- } else {
25988
- onSelectionChange(tools.map(function (t) {
25989
- return t.name;
25990
- }));
25991
- }
25992
- };
25993
- var handleToggle = function handleToggle(toolName) {
25994
- if (selectedTools.includes(toolName)) {
25995
- onSelectionChange(selectedTools.filter(function (t) {
25996
- return t !== toolName;
25997
- }));
25998
- } else {
25999
- onSelectionChange([].concat(_toConsumableArray(selectedTools), [toolName]));
26000
- }
26001
- };
26002
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
26003
- className: "space-y-2 flex-1 flex flex-col min-h-0",
26004
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26005
- className: "flex items-center justify-between",
26006
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26007
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
26008
- children: "Allowed Tools"
26009
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
26010
- onClick: handleToggleAll,
26011
- className: "text-xs text-blue-400 hover:text-blue-300 transition-colors",
26012
- children: allSelected ? "Deselect All" : "Select All"
26013
- })]
26014
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
26015
- className: "text-sm opacity-50",
26016
- children: "Choose which tools this provider can expose to widgets"
26017
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
26018
- className: "space-y-1 flex-1 min-h-0 overflow-y-auto",
26019
- children: tools.map(function (tool) {
26020
- var checked = selectedTools.includes(tool.name);
26021
- return /*#__PURE__*/jsxRuntime.jsxs("label", {
26022
- className: "flex items-start gap-2 p-1.5 rounded hover:bg-white/5 cursor-pointer",
26023
- children: [/*#__PURE__*/jsxRuntime.jsx("input", {
26024
- type: "checkbox",
26025
- checked: checked,
26026
- onChange: function onChange() {
26027
- return handleToggle(tool.name);
26028
- },
26029
- className: "mt-0.5 rounded border-white/20 bg-white/5 text-blue-500 focus:ring-blue-500/30"
26030
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26031
- className: "flex-1 min-w-0",
26032
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26033
- className: "text-xs font-mono",
26034
- children: tool.name
26035
- }), tool.description && /*#__PURE__*/jsxRuntime.jsxs("span", {
26036
- className: "text-xs opacity-50 ml-2",
26037
- children: ["\u2014 ", tool.description]
26038
- })]
26039
- })]
26040
- }, tool.name);
26041
- })
26042
- }), /*#__PURE__*/jsxRuntime.jsxs("p", {
26043
- className: "text-xs opacity-40",
26044
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26045
- icon: "shield-halved",
26046
- className: "mr-1"
26047
- }), selectedTools.length, " of ", tools.length, " tools selected"]
26048
- })]
26049
- });
26050
- };
26051
-
26052
26719
  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; }
26053
26720
  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; }
26054
26721
  var ProviderDetail = function ProviderDetail(_ref) {
@@ -26077,7 +26744,9 @@ var ProviderDetail = function ProviderDetail(_ref) {
26077
26744
  onDelete = _ref.onDelete,
26078
26745
  onSaveAllowedTools = _ref.onSaveAllowedTools,
26079
26746
  _ref$catalogAuthComma = _ref.catalogAuthCommand,
26080
- catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma;
26747
+ catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma,
26748
+ _ref$catalogCredentia = _ref.catalogCredentialSchema,
26749
+ catalogCredentialSchema = _ref$catalogCredentia === void 0 ? {} : _ref$catalogCredentia;
26081
26750
  var appContext = React.useContext(AppContext);
26082
26751
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
26083
26752
  var isMcp = (provider === null || provider === void 0 ? void 0 : provider.providerClass) === "mcp";
@@ -26112,8 +26781,8 @@ var ProviderDetail = function ProviderDetail(_ref) {
26112
26781
  // Derive credential fields for MCP providers in edit mode
26113
26782
  var mcpFormFields = React.useMemo(function () {
26114
26783
  if (!isMcp || !(provider !== null && provider !== void 0 && provider.mcpConfig)) return [];
26115
- return deriveFormFields(provider.mcpConfig, {});
26116
- }, [isMcp, provider]);
26784
+ return deriveFormFields(provider.mcpConfig, catalogCredentialSchema);
26785
+ }, [isMcp, provider, catalogCredentialSchema]);
26117
26786
 
26118
26787
  // Credential field keys for non-MCP providers
26119
26788
  var credentialKeys = React.useMemo(function () {
@@ -28739,7 +29408,8 @@ var ProvidersSection = function ProvidersSection(_ref) {
28739
29408
  return setDeleteTarget(name);
28740
29409
  },
28741
29410
  onSaveAllowedTools: handleSaveAllowedTools,
28742
- catalogAuthCommand: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.authCommand) || null
29411
+ catalogAuthCommand: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.authCommand) || null,
29412
+ catalogCredentialSchema: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.credentialSchema) || {}
28743
29413
  });
28744
29414
  }
28745
29415
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {