@trops/dash-core 0.1.68 → 0.1.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -7319,195 +7319,710 @@ var ProviderForm = function ProviderForm(_ref) {
7319
7319
  });
7320
7320
  };
7321
7321
 
7322
- 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; } } }; }
7323
- 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; } }
7324
- 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; }
7322
+ var ToolSelector = function ToolSelector(_ref) {
7323
+ var _ref$tools = _ref.tools,
7324
+ tools = _ref$tools === void 0 ? [] : _ref$tools,
7325
+ _ref$selectedTools = _ref.selectedTools,
7326
+ selectedTools = _ref$selectedTools === void 0 ? [] : _ref$selectedTools,
7327
+ onSelectionChange = _ref.onSelectionChange;
7328
+ if (!tools || tools.length === 0) return null;
7329
+ var allSelected = selectedTools.length === tools.length;
7330
+ var handleToggleAll = function handleToggleAll() {
7331
+ if (allSelected) {
7332
+ onSelectionChange([]);
7333
+ } else {
7334
+ onSelectionChange(tools.map(function (t) {
7335
+ return t.name;
7336
+ }));
7337
+ }
7338
+ };
7339
+ var handleToggle = function handleToggle(toolName) {
7340
+ if (selectedTools.includes(toolName)) {
7341
+ onSelectionChange(selectedTools.filter(function (t) {
7342
+ return t !== toolName;
7343
+ }));
7344
+ } else {
7345
+ onSelectionChange([].concat(_toConsumableArray(selectedTools), [toolName]));
7346
+ }
7347
+ };
7348
+ return /*#__PURE__*/jsxs("div", {
7349
+ className: "space-y-2 flex-1 flex flex-col min-h-0",
7350
+ children: [/*#__PURE__*/jsxs("div", {
7351
+ className: "flex items-center justify-between",
7352
+ children: [/*#__PURE__*/jsx("p", {
7353
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
7354
+ children: "Allowed Tools"
7355
+ }), /*#__PURE__*/jsx("button", {
7356
+ onClick: handleToggleAll,
7357
+ className: "text-xs text-blue-400 hover:text-blue-300 transition-colors",
7358
+ children: allSelected ? "Deselect All" : "Select All"
7359
+ })]
7360
+ }), /*#__PURE__*/jsx("p", {
7361
+ className: "text-sm opacity-50",
7362
+ children: "Choose which tools this provider can expose to widgets"
7363
+ }), /*#__PURE__*/jsx("div", {
7364
+ className: "space-y-1 flex-1 min-h-0 overflow-y-auto",
7365
+ children: tools.map(function (tool) {
7366
+ var checked = selectedTools.includes(tool.name);
7367
+ return /*#__PURE__*/jsxs("label", {
7368
+ className: "flex items-start gap-2 p-1.5 rounded hover:bg-white/5 cursor-pointer",
7369
+ children: [/*#__PURE__*/jsx("input", {
7370
+ type: "checkbox",
7371
+ checked: checked,
7372
+ onChange: function onChange() {
7373
+ return handleToggle(tool.name);
7374
+ },
7375
+ className: "mt-0.5 rounded border-white/20 bg-white/5 text-blue-500 focus:ring-blue-500/30"
7376
+ }), /*#__PURE__*/jsxs("div", {
7377
+ className: "flex-1 min-w-0",
7378
+ children: [/*#__PURE__*/jsx("span", {
7379
+ className: "text-xs font-mono",
7380
+ children: tool.name
7381
+ }), tool.description && /*#__PURE__*/jsxs("span", {
7382
+ className: "text-xs opacity-50 ml-2",
7383
+ children: ["\u2014 ", tool.description]
7384
+ })]
7385
+ })]
7386
+ }, tool.name);
7387
+ })
7388
+ }), /*#__PURE__*/jsxs("p", {
7389
+ className: "text-xs opacity-40",
7390
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
7391
+ icon: "shield-halved",
7392
+ className: "mr-1"
7393
+ }), selectedTools.length, " of ", tools.length, " tools selected"]
7394
+ })]
7395
+ });
7396
+ };
7397
+
7325
7398
  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; }
7326
7399
  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; }
7327
- var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7328
- var isOpen = _ref.isOpen,
7329
- onClose = _ref.onClose,
7330
- onSelectWidget = _ref.onSelectWidget;
7331
- _ref.workspaceType;
7332
- var _useContext = useContext(ThemeContext),
7333
- currentTheme = _useContext.currentTheme;
7334
- var _useContext2 = useContext(AppContext),
7335
- _useContext2$provider = _useContext2.providers,
7336
- availableProviders = _useContext2$provider === void 0 ? {} : _useContext2$provider,
7337
- dashApi = _useContext2.dashApi,
7338
- credentials = _useContext2.credentials,
7339
- refreshProviders = _useContext2.refreshProviders;
7400
+ /**
7401
+ * Shared MCP utility functions.
7402
+ *
7403
+ * Extracted from McpServerPicker so ProviderDetail (and any future consumer)
7404
+ * can reuse the same field-derivation logic.
7405
+ */
7340
7406
 
7341
- // State management
7342
- var _useState = useState("Installed"),
7343
- _useState2 = _slicedToArray(_useState, 2),
7344
- selectedSource = _useState2[0],
7345
- setSelectedSource = _useState2[1]; // "Installed" | "Discover"
7346
- var _useState3 = useState(null),
7347
- _useState4 = _slicedToArray(_useState3, 2),
7348
- selectedWidget = _useState4[0],
7349
- setSelectedWidget = _useState4[1];
7350
- var _useState5 = useState([]),
7351
- _useState6 = _slicedToArray(_useState5, 2),
7352
- widgets = _useState6[0],
7353
- setWidgets = _useState6[1];
7407
+ /**
7408
+ * Derive required form fields from an mcpConfig, using credentialSchema
7409
+ * as optional enrichment for display names, instructions, and secret flags.
7410
+ *
7411
+ * For streamable_http: extracts {{placeholder}} fields from url and headerTemplate.
7412
+ * For stdio: extracts credential field names from envMapping values.
7413
+ *
7414
+ * @param {object} mcpConfig - The MCP server configuration
7415
+ * @param {object} credentialSchema - Optional metadata for field labels/instructions
7416
+ * @returns {Array<{ key, displayName, required, secret, instructions, type }>}
7417
+ */
7418
+ function deriveFormFields(mcpConfig) {
7419
+ var credentialSchema = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7420
+ var fieldKeys = new Set();
7421
+ if (mcpConfig.transport === "streamable_http") {
7422
+ // Extract {{field}} placeholders from url
7423
+ if (mcpConfig.url) {
7424
+ var urlMatches = mcpConfig.url.match(/\{\{(\w+)\}\}/g) || [];
7425
+ urlMatches.forEach(function (m) {
7426
+ return fieldKeys.add(m.slice(2, -2));
7427
+ });
7428
+ }
7429
+ // Extract {{field}} placeholders from headerTemplate values
7430
+ if (mcpConfig.headerTemplate) {
7431
+ Object.values(mcpConfig.headerTemplate).forEach(function (template) {
7432
+ var matches = template.match(/\{\{(\w+)\}\}/g) || [];
7433
+ matches.forEach(function (m) {
7434
+ return fieldKeys.add(m.slice(2, -2));
7435
+ });
7436
+ });
7437
+ }
7438
+ } else {
7439
+ // stdio: extract credential field names from envMapping values
7440
+ if (mcpConfig.envMapping) {
7441
+ Object.values(mcpConfig.envMapping).forEach(function (credField) {
7442
+ fieldKeys.add(credField);
7443
+ });
7444
+ }
7445
+ }
7354
7446
 
7355
- // Filter state
7356
- var _useState7 = useState(""),
7357
- _useState8 = _slicedToArray(_useState7, 2),
7358
- searchQuery = _useState8[0],
7359
- setSearchQuery = _useState8[1];
7360
- var _useState9 = useState("all"),
7361
- _useState0 = _slicedToArray(_useState9, 2),
7362
- selectedAuthor = _useState0[0],
7363
- setSelectedAuthor = _useState0[1];
7364
- var _useState1 = useState("all"),
7365
- _useState10 = _slicedToArray(_useState1, 2),
7366
- selectedProvider = _useState10[0],
7367
- setSelectedProvider = _useState10[1];
7447
+ // Also include any fields defined in credentialSchema that aren't already derived
7448
+ if (credentialSchema) {
7449
+ Object.keys(credentialSchema).forEach(function (key) {
7450
+ return fieldKeys.add(key);
7451
+ });
7452
+ }
7368
7453
 
7369
- // Phase 2: Provider and userConfig state
7370
- var _useState11 = useState({}),
7371
- _useState12 = _slicedToArray(_useState11, 2),
7372
- selectedProviders = _useState12[0],
7373
- setSelectedProviders = _useState12[1];
7374
- var _useState13 = useState({}),
7375
- _useState14 = _slicedToArray(_useState13, 2),
7376
- userConfigValues = _useState14[0],
7377
- setUserConfigValues = _useState14[1];
7454
+ // Build the field list with metadata from credentialSchema or auto-generated defaults
7455
+ return Array.from(fieldKeys).map(function (key) {
7456
+ var schemaMeta = credentialSchema[key];
7457
+ if (schemaMeta) {
7458
+ return {
7459
+ key: key,
7460
+ displayName: schemaMeta.displayName || formatFieldName(key),
7461
+ required: schemaMeta.required === true,
7462
+ secret: schemaMeta.secret || false,
7463
+ instructions: schemaMeta.instructions || null,
7464
+ type: schemaMeta.type || "text"
7465
+ };
7466
+ }
7378
7467
 
7379
- // Phase 3: Recent widgets state
7380
- var _useState15 = useState([]),
7381
- _useState16 = _slicedToArray(_useState15, 2),
7382
- recentWidgets = _useState16[0],
7383
- setRecentWidgets = _useState16[1];
7468
+ // Auto-generate defaults from the field name
7469
+ return {
7470
+ key: key,
7471
+ displayName: formatFieldName(key),
7472
+ required: false,
7473
+ secret: isLikelySecret(key),
7474
+ instructions: null,
7475
+ type: "text"
7476
+ };
7477
+ });
7478
+ }
7384
7479
 
7385
- // Inline provider creation state
7386
- var _useState17 = useState(null),
7387
- _useState18 = _slicedToArray(_useState17, 2),
7388
- inlineCreateType = _useState18[0],
7389
- setInlineCreateType = _useState18[1];
7390
- var _useState19 = useState({}),
7391
- _useState20 = _slicedToArray(_useState19, 2),
7392
- inlineCreateSchema = _useState20[0],
7393
- setInlineCreateSchema = _useState20[1];
7394
- var _useState21 = useState(null),
7395
- _useState22 = _slicedToArray(_useState21, 2),
7396
- inlineCreateError = _useState22[0],
7397
- setInlineCreateError = _useState22[1];
7398
- var _useState23 = useState(false),
7399
- _useState24 = _slicedToArray(_useState23, 2),
7400
- isCreatingProvider = _useState24[0],
7401
- setIsCreatingProvider = _useState24[1];
7480
+ /**
7481
+ * Convert a camelCase field name to a human-readable title.
7482
+ * e.g., "apiKey" → "API Key", "url" → "URL", "botToken" → "Bot Token"
7483
+ */
7484
+ function formatFieldName(name) {
7485
+ var acronyms = {
7486
+ url: "URL",
7487
+ api: "API",
7488
+ id: "ID",
7489
+ mcp: "MCP"
7490
+ };
7491
+ return name.replace(/([A-Z])/g, " $1").replace(/^./, function (s) {
7492
+ return s.toUpperCase();
7493
+ }).trim().split(" ").map(function (word) {
7494
+ return acronyms[word.toLowerCase()] || word;
7495
+ }).join(" ");
7496
+ }
7402
7497
 
7403
- // Installed widget grouping
7404
- var _useState25 = useState(new Set()),
7405
- _useState26 = _slicedToArray(_useState25, 2),
7406
- expandedGroups = _useState26[0],
7407
- setExpandedGroups = _useState26[1];
7498
+ /**
7499
+ * Heuristic: does this field name likely contain a secret value?
7500
+ */
7501
+ function isLikelySecret(name) {
7502
+ var lower = name.toLowerCase();
7503
+ return /key|token|secret|password|credential|auth/.test(lower);
7504
+ }
7408
7505
 
7409
- // Registry state
7410
- var _useState27 = useState(false),
7411
- _useState28 = _slicedToArray(_useState27, 2),
7412
- isLoadingRegistry = _useState28[0],
7413
- setIsLoadingRegistry = _useState28[1];
7414
- var _useState29 = useState(null),
7415
- _useState30 = _slicedToArray(_useState29, 2),
7416
- registryError = _useState30[0],
7417
- setRegistryError = _useState30[1];
7418
- var _useState31 = useState([]),
7419
- _useState32 = _slicedToArray(_useState31, 2),
7420
- registryPackages = _useState32[0],
7421
- setRegistryPackages = _useState32[1];
7422
- var _useState33 = useState("packages"),
7423
- _useState34 = _slicedToArray(_useState33, 2),
7424
- registryViewMode = _useState34[0],
7425
- setRegistryViewMode = _useState34[1]; // "packages" | "widgets"
7426
- var _useState35 = useState(new Set()),
7427
- _useState36 = _slicedToArray(_useState35, 2),
7428
- expandedPackages = _useState36[0],
7429
- setExpandedPackages = _useState36[1];
7430
- var _useState37 = useState(null),
7431
- _useState38 = _slicedToArray(_useState37, 2),
7432
- selectedPackage = _useState38[0],
7433
- setSelectedPackage = _useState38[1];
7434
- var _useState39 = useState(false),
7435
- _useState40 = _slicedToArray(_useState39, 2),
7436
- isInstalling = _useState40[0],
7437
- setIsInstalling = _useState40[1];
7438
- var _useState41 = useState(null),
7439
- _useState42 = _slicedToArray(_useState41, 2),
7440
- installError = _useState42[0],
7441
- setInstallError = _useState42[1];
7442
-
7443
- // Phase 3: Recent Widgets - localStorage functions
7444
- var loadRecentWidgets = function loadRecentWidgets() {
7445
- try {
7446
- var stored = localStorage.getItem("recentWidgets");
7447
- var recentData = stored ? JSON.parse(stored) : [];
7448
-
7449
- // Get widget details from ComponentManager
7450
- var allWidgets = ComponentManager.map();
7451
- var enrichedRecent = recentData.slice(0, 5) // Show top 5
7452
- .map(function (entry) {
7453
- var widget = allWidgets[entry.widgetKey];
7454
- if (!widget) return null; // Widget no longer exists
7455
- return _objectSpread$r(_objectSpread$r({
7456
- key: entry.widgetKey
7457
- }, widget), {}, {
7458
- savedProviders: entry.providers || {},
7459
- savedUserConfig: entry.userConfig || {},
7460
- timestamp: entry.timestamp
7461
- });
7462
- }).filter(Boolean); // Remove null entries
7506
+ /**
7507
+ * Build an mcpConfig by overlaying advanced-section rows onto a catalog base config.
7508
+ *
7509
+ * For stdio: replaces `envMapping` with the rows from the advanced section.
7510
+ * For streamable_http: replaces `headerTemplate` with the rows from the advanced section.
7511
+ *
7512
+ * @param {object} baseMcpConfig - The catalog's original mcpConfig
7513
+ * @param {Array<{ envVar: string, credField: string }>} envMappingRows - Current env var rows
7514
+ * @param {Array<{ headerName: string, headerValue: string }>} headerRows - Current header rows
7515
+ * @returns {object} A new mcpConfig with overridden envMapping or headerTemplate
7516
+ */
7517
+ function buildMcpConfigFromOverrides(baseMcpConfig, envMappingRows, headerRows) {
7518
+ if (baseMcpConfig.transport === "streamable_http") {
7519
+ var headerTemplate = {};
7520
+ headerRows.forEach(function (row) {
7521
+ var name = row.headerName.trim();
7522
+ var value = row.headerValue.trim();
7523
+ if (name && value) {
7524
+ headerTemplate[name] = value;
7525
+ }
7526
+ });
7527
+ var config = _objectSpread$r({}, baseMcpConfig);
7528
+ if (Object.keys(headerTemplate).length > 0) {
7529
+ config.headerTemplate = headerTemplate;
7530
+ } else {
7531
+ delete config.headerTemplate;
7532
+ }
7533
+ return config;
7534
+ }
7463
7535
 
7464
- setRecentWidgets(enrichedRecent);
7465
- } catch (error) {
7466
- setRecentWidgets([]);
7536
+ // stdio
7537
+ var envMapping = {};
7538
+ envMappingRows.forEach(function (row) {
7539
+ var env = row.envVar.trim();
7540
+ var cred = row.credField.trim();
7541
+ if (env && cred) {
7542
+ envMapping[env] = cred;
7467
7543
  }
7468
- };
7469
- var saveToRecent = function saveToRecent(widget, providers, userConfig) {
7470
- try {
7471
- var stored = localStorage.getItem("recentWidgets");
7472
- var recent = stored ? JSON.parse(stored) : [];
7544
+ });
7545
+ return _objectSpread$r(_objectSpread$r({}, baseMcpConfig), {}, {
7546
+ envMapping: envMapping
7547
+ });
7548
+ }
7473
7549
 
7474
- // Create new entry
7475
- var newEntry = {
7476
- widgetKey: widget.key,
7477
- timestamp: Date.now(),
7478
- providers: providers || {},
7479
- userConfig: userConfig || {}
7480
- };
7550
+ /**
7551
+ * Convert an envMapping object into row state for the advanced config UI.
7552
+ *
7553
+ * @param {object} envMapping - e.g. { SLACK_BOT_TOKEN: "botToken" }
7554
+ * @param {Function} nextRowId - Function that returns a unique row ID
7555
+ * @returns {Array<{ id: string, envVar: string, credField: string }>}
7556
+ */
7557
+ function envMappingToRows(envMapping, nextRowId) {
7558
+ if (!envMapping) return [];
7559
+ return Object.entries(envMapping).map(function (_ref) {
7560
+ var _ref2 = _slicedToArray(_ref, 2),
7561
+ envVar = _ref2[0],
7562
+ credField = _ref2[1];
7563
+ return {
7564
+ id: nextRowId(),
7565
+ envVar: envVar,
7566
+ credField: credField
7567
+ };
7568
+ });
7569
+ }
7481
7570
 
7482
- // Remove existing entry for this widget (if any) and add new one at front
7483
- var updated = [newEntry].concat(_toConsumableArray(recent.filter(function (r) {
7484
- return r.widgetKey !== widget.key;
7485
- }))).slice(0, 10); // Keep max 10
7571
+ /**
7572
+ * Convert a headerTemplate object into row state for the advanced config UI.
7573
+ *
7574
+ * @param {object} headerTemplate - e.g. { "Authorization": "Bearer {{apiKey}}" }
7575
+ * @param {Function} nextRowId - Function that returns a unique row ID
7576
+ * @returns {Array<{ id: string, headerName: string, headerValue: string }>}
7577
+ */
7578
+ function headerTemplateToRows(headerTemplate, nextRowId) {
7579
+ if (!headerTemplate) return [];
7580
+ return Object.entries(headerTemplate).map(function (_ref3) {
7581
+ var _ref4 = _slicedToArray(_ref3, 2),
7582
+ headerName = _ref4[0],
7583
+ headerValue = _ref4[1];
7584
+ return {
7585
+ id: nextRowId(),
7586
+ headerName: headerName,
7587
+ headerValue: headerValue
7588
+ };
7589
+ });
7590
+ }
7486
7591
 
7487
- localStorage.setItem("recentWidgets", JSON.stringify(updated));
7592
+ /**
7593
+ * Serialize the current form state into a bare MCP JSON config string.
7594
+ *
7595
+ * Output format (stdio):
7596
+ * {
7597
+ * "type": "stdio",
7598
+ * "command": "npx",
7599
+ * "args": ["-y", "package-name"],
7600
+ * "env": { "API_KEY": "${API_KEY}" }
7601
+ * }
7602
+ *
7603
+ * Output format (HTTP):
7604
+ * {
7605
+ * "type": "streamable_http",
7606
+ * "url": "https://example.com/mcp",
7607
+ * "headerTemplate": { "Authorization": "Bearer {{apiKey}}" }
7608
+ * }
7609
+ *
7610
+ * Credential values are NOT embedded — env values use ${FIELD_NAME} syntax
7611
+ * to reference credential fields entered separately in the form.
7612
+ *
7613
+ * @param {string} name - The provider name (unused in output, kept for API compat)
7614
+ * @param {string} transport - "stdio" or "streamable_http"
7615
+ * @param {object} fields - { command, args, envMappingRows, url, headerRows }
7616
+ * @returns {string} Formatted JSON string
7617
+ */
7618
+ function formStateToMcpJson(name, transport, fields) {
7619
+ var _fields$command = fields.command,
7620
+ command = _fields$command === void 0 ? "" : _fields$command,
7621
+ _fields$args = fields.args,
7622
+ args = _fields$args === void 0 ? "" : _fields$args,
7623
+ _fields$envMappingRow = fields.envMappingRows,
7624
+ envMappingRows = _fields$envMappingRow === void 0 ? [] : _fields$envMappingRow,
7625
+ _fields$url = fields.url,
7626
+ url = _fields$url === void 0 ? "" : _fields$url,
7627
+ _fields$headerRows = fields.headerRows,
7628
+ headerRows = _fields$headerRows === void 0 ? [] : _fields$headerRows;
7629
+ var serverConfig;
7630
+ if (transport === "stdio") {
7631
+ var argsArray = args.trim().split(/\s+/).filter(Boolean);
7632
+ var env = {};
7633
+ envMappingRows.forEach(function (row) {
7634
+ var envVar = row.envVar.trim();
7635
+ var credField = row.credField.trim();
7636
+ if (envVar && credField) {
7637
+ env[envVar] = "${".concat(credField, "}");
7638
+ }
7639
+ });
7640
+ serverConfig = {
7641
+ type: "stdio",
7642
+ command: command.trim()
7643
+ };
7644
+ if (argsArray.length > 0) serverConfig.args = argsArray;
7645
+ if (Object.keys(env).length > 0) serverConfig.env = env;
7646
+ } else {
7647
+ // streamable_http
7648
+ serverConfig = {
7649
+ type: "streamable_http",
7650
+ url: url.trim()
7651
+ };
7652
+ var headerTemplate = {};
7653
+ headerRows.forEach(function (row) {
7654
+ var hName = row.headerName.trim();
7655
+ var hValue = row.headerValue.trim();
7656
+ if (hName && hValue) {
7657
+ headerTemplate[hName] = hValue;
7658
+ }
7659
+ });
7660
+ if (Object.keys(headerTemplate).length > 0) serverConfig.headerTemplate = headerTemplate;
7661
+ }
7662
+ return JSON.stringify(serverConfig, null, 2);
7663
+ }
7488
7664
 
7489
- // Reload recent widgets to update UI
7490
- loadRecentWidgets();
7491
- } catch (error) {
7665
+ /**
7666
+ * Parse an MCP JSON config string back into form state.
7667
+ *
7668
+ * Accepts multiple input formats:
7669
+ * - Bare config: { "command": ..., "args": [...], "env": { "KEY": "${FIELD}" } }
7670
+ * - Wrapped: { "mcpServers": { "name": { ... } } } — unwraps and uses key as providerName
7671
+ *
7672
+ * Transport detection:
7673
+ * - Explicit `type` or `transport` field
7674
+ * - Inferred: `url` present → streamable_http, `command` present → stdio
7675
+ *
7676
+ * stdio env value parsing:
7677
+ * - "${FIELD_NAME}" → envVar = key, credField = FIELD_NAME (reference syntax)
7678
+ * - "literal-value" → envVar = key, credField = key, credentialData[key] = value
7679
+ *
7680
+ * @param {string} jsonString - The JSON to parse
7681
+ * @param {Function} nextRowId - Function that returns a unique row ID
7682
+ * @returns {{ providerName, transport, command, args, envMappingRows, url, headerRows, credentialData, error }}
7683
+ */
7684
+ function mcpJsonToFormState(jsonString, nextRowId) {
7685
+ var parsed;
7686
+ try {
7687
+ parsed = JSON.parse(jsonString);
7688
+ } catch (e) {
7689
+ return {
7690
+ error: "Invalid JSON: ".concat(e.message)
7691
+ };
7692
+ }
7693
+ var providerName = "";
7694
+ var serverConfig;
7695
+ if (parsed.mcpServers && _typeof(parsed.mcpServers) === "object") {
7696
+ var entries = Object.entries(parsed.mcpServers);
7697
+ if (entries.length === 0) {
7698
+ return {
7699
+ error: "No server found in mcpServers"
7700
+ };
7492
7701
  }
7493
- };
7494
- var handleRecentClick = function handleRecentClick(recentWidget) {
7495
- setSelectedWidget(recentWidget);
7496
- setSelectedProviders(recentWidget.savedProviders || {});
7497
- setUserConfigValues(recentWidget.savedUserConfig || {});
7498
- // Reset inline provider creation form
7499
- setInlineCreateType(null);
7500
- setInlineCreateSchema({});
7501
- setInlineCreateError(null);
7502
- };
7503
-
7504
- // Fetch widgets when modal opens
7505
- useEffect(function () {
7506
- if (isOpen) {
7507
- loadWidgets();
7508
- loadRecentWidgets(); // Phase 3: Load recent widgets
7509
- // Reset filters when modal opens
7510
- setSearchQuery("");
7702
+ var _entries$ = _slicedToArray(entries[0], 2);
7703
+ providerName = _entries$[0];
7704
+ serverConfig = _entries$[1];
7705
+ } else if (parsed.command || parsed.url || parsed.type || parsed.transport) {
7706
+ serverConfig = parsed;
7707
+ } else {
7708
+ return {
7709
+ error: "Unrecognized format: expected a server config with command, url, or type"
7710
+ };
7711
+ }
7712
+
7713
+ // Determine transport from type/transport field or infer from contents
7714
+ var explicitType = serverConfig.type || serverConfig.transport;
7715
+ var transport;
7716
+ if (explicitType) {
7717
+ transport = explicitType === "stdio" ? "stdio" : "streamable_http";
7718
+ } else {
7719
+ transport = serverConfig.url ? "streamable_http" : "stdio";
7720
+ }
7721
+ var result = {
7722
+ providerName: providerName,
7723
+ transport: transport,
7724
+ command: "",
7725
+ args: "",
7726
+ envMappingRows: [],
7727
+ url: "",
7728
+ headerRows: [],
7729
+ credentialData: {},
7730
+ error: null
7731
+ };
7732
+ if (transport === "stdio") {
7733
+ result.command = serverConfig.command || "";
7734
+ result.args = (serverConfig.args || []).join(" ");
7735
+ if (serverConfig.env && _typeof(serverConfig.env) === "object") {
7736
+ Object.entries(serverConfig.env).forEach(function (_ref5) {
7737
+ var _ref6 = _slicedToArray(_ref5, 2),
7738
+ envVar = _ref6[0],
7739
+ value = _ref6[1];
7740
+ // Check for ${FIELD_NAME} reference syntax
7741
+ var refMatch = typeof value === "string" && value.match(/^\$\{(.+)\}$/);
7742
+ if (refMatch) {
7743
+ // Reference syntax — credField is the extracted name, no credential value
7744
+ result.envMappingRows.push({
7745
+ id: nextRowId(),
7746
+ envVar: envVar,
7747
+ credField: refMatch[1]
7748
+ });
7749
+ } else {
7750
+ // Literal value — use envVar as credField and store the value
7751
+ result.envMappingRows.push({
7752
+ id: nextRowId(),
7753
+ envVar: envVar,
7754
+ credField: envVar
7755
+ });
7756
+ result.credentialData[envVar] = value || "";
7757
+ }
7758
+ });
7759
+ }
7760
+ } else {
7761
+ result.url = serverConfig.url || "";
7762
+ var headers = serverConfig.headers || serverConfig.headerTemplate || {};
7763
+ if (_typeof(headers) === "object") {
7764
+ Object.entries(headers).forEach(function (_ref7) {
7765
+ var _ref8 = _slicedToArray(_ref7, 2),
7766
+ headerName = _ref8[0],
7767
+ headerValue = _ref8[1];
7768
+ result.headerRows.push({
7769
+ id: nextRowId(),
7770
+ headerName: headerName,
7771
+ headerValue: headerValue
7772
+ });
7773
+ });
7774
+ }
7775
+ }
7776
+ return result;
7777
+ }
7778
+
7779
+ 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; } } }; }
7780
+ 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; } }
7781
+ 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; }
7782
+ 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; }
7783
+ 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; }
7784
+ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7785
+ var isOpen = _ref.isOpen,
7786
+ onClose = _ref.onClose,
7787
+ onSelectWidget = _ref.onSelectWidget;
7788
+ _ref.workspaceType;
7789
+ var _useContext = useContext(ThemeContext),
7790
+ currentTheme = _useContext.currentTheme;
7791
+ var _useContext2 = useContext(AppContext),
7792
+ _useContext2$provider = _useContext2.providers,
7793
+ availableProviders = _useContext2$provider === void 0 ? {} : _useContext2$provider,
7794
+ dashApi = _useContext2.dashApi,
7795
+ credentials = _useContext2.credentials,
7796
+ refreshProviders = _useContext2.refreshProviders;
7797
+
7798
+ // State management
7799
+ var _useState = useState("Installed"),
7800
+ _useState2 = _slicedToArray(_useState, 2),
7801
+ selectedSource = _useState2[0],
7802
+ setSelectedSource = _useState2[1]; // "Installed" | "Discover"
7803
+ var _useState3 = useState(null),
7804
+ _useState4 = _slicedToArray(_useState3, 2),
7805
+ selectedWidget = _useState4[0],
7806
+ setSelectedWidget = _useState4[1];
7807
+ var _useState5 = useState([]),
7808
+ _useState6 = _slicedToArray(_useState5, 2),
7809
+ widgets = _useState6[0],
7810
+ setWidgets = _useState6[1];
7811
+
7812
+ // Filter state
7813
+ var _useState7 = useState(""),
7814
+ _useState8 = _slicedToArray(_useState7, 2),
7815
+ searchQuery = _useState8[0],
7816
+ setSearchQuery = _useState8[1];
7817
+ var _useState9 = useState("all"),
7818
+ _useState0 = _slicedToArray(_useState9, 2),
7819
+ selectedAuthor = _useState0[0],
7820
+ setSelectedAuthor = _useState0[1];
7821
+ var _useState1 = useState("all"),
7822
+ _useState10 = _slicedToArray(_useState1, 2),
7823
+ selectedProvider = _useState10[0],
7824
+ setSelectedProvider = _useState10[1];
7825
+
7826
+ // Phase 2: Provider and userConfig state
7827
+ var _useState11 = useState({}),
7828
+ _useState12 = _slicedToArray(_useState11, 2),
7829
+ selectedProviders = _useState12[0],
7830
+ setSelectedProviders = _useState12[1];
7831
+ var _useState13 = useState({}),
7832
+ _useState14 = _slicedToArray(_useState13, 2),
7833
+ userConfigValues = _useState14[0],
7834
+ setUserConfigValues = _useState14[1];
7835
+
7836
+ // Phase 3: Recent widgets state
7837
+ var _useState15 = useState([]),
7838
+ _useState16 = _slicedToArray(_useState15, 2),
7839
+ recentWidgets = _useState16[0],
7840
+ setRecentWidgets = _useState16[1];
7841
+
7842
+ // Inline provider creation state
7843
+ var _useState17 = useState(null),
7844
+ _useState18 = _slicedToArray(_useState17, 2),
7845
+ inlineCreateType = _useState18[0],
7846
+ setInlineCreateType = _useState18[1];
7847
+ var _useState19 = useState({}),
7848
+ _useState20 = _slicedToArray(_useState19, 2),
7849
+ inlineCreateSchema = _useState20[0],
7850
+ setInlineCreateSchema = _useState20[1];
7851
+ var _useState21 = useState(null),
7852
+ _useState22 = _slicedToArray(_useState21, 2),
7853
+ inlineCreateError = _useState22[0],
7854
+ setInlineCreateError = _useState22[1];
7855
+ var _useState23 = useState(false),
7856
+ _useState24 = _slicedToArray(_useState23, 2),
7857
+ isCreatingProvider = _useState24[0],
7858
+ setIsCreatingProvider = _useState24[1];
7859
+
7860
+ // MCP catalog for inline stepper creation
7861
+ var _useState25 = useState([]),
7862
+ _useState26 = _slicedToArray(_useState25, 2),
7863
+ mcpCatalog = _useState26[0],
7864
+ setMcpCatalog = _useState26[1];
7865
+ var _useState27 = useState(null),
7866
+ _useState28 = _slicedToArray(_useState27, 2),
7867
+ inlineCatalogEntry = _useState28[0],
7868
+ setInlineCatalogEntry = _useState28[1];
7869
+
7870
+ // Inline MCP stepper state
7871
+ var _useState29 = useState(0),
7872
+ _useState30 = _slicedToArray(_useState29, 2),
7873
+ inlineWizardStep = _useState30[0],
7874
+ setInlineWizardStep = _useState30[1];
7875
+ var _useState31 = useState({}),
7876
+ _useState32 = _slicedToArray(_useState31, 2),
7877
+ inlineCredentialData = _useState32[0],
7878
+ setInlineCredentialData = _useState32[1];
7879
+ var _useState33 = useState(""),
7880
+ _useState34 = _slicedToArray(_useState33, 2),
7881
+ inlineProviderName = _useState34[0],
7882
+ setInlineProviderName = _useState34[1];
7883
+ var _useState35 = useState({}),
7884
+ _useState36 = _slicedToArray(_useState35, 2),
7885
+ inlineFormErrors = _useState36[0],
7886
+ setInlineFormErrors = _useState36[1];
7887
+ var _useState37 = useState(null),
7888
+ _useState38 = _slicedToArray(_useState37, 2),
7889
+ inlineTestResult = _useState38[0],
7890
+ setInlineTestResult = _useState38[1];
7891
+ var _useState39 = useState(false),
7892
+ _useState40 = _slicedToArray(_useState39, 2),
7893
+ inlineIsTesting = _useState40[0],
7894
+ setInlineIsTesting = _useState40[1];
7895
+ var _useState41 = useState(null),
7896
+ _useState42 = _slicedToArray(_useState41, 2),
7897
+ inlineAuthResult = _useState42[0],
7898
+ setInlineAuthResult = _useState42[1];
7899
+ var _useState43 = useState(false),
7900
+ _useState44 = _slicedToArray(_useState43, 2),
7901
+ inlineIsAuthorizing = _useState44[0],
7902
+ setInlineIsAuthorizing = _useState44[1];
7903
+ var _useState45 = useState(null),
7904
+ _useState46 = _slicedToArray(_useState45, 2),
7905
+ inlineSelectedTools = _useState46[0],
7906
+ setInlineSelectedTools = _useState46[1];
7907
+
7908
+ // Installed widget grouping
7909
+ var _useState47 = useState(new Set()),
7910
+ _useState48 = _slicedToArray(_useState47, 2),
7911
+ expandedGroups = _useState48[0],
7912
+ setExpandedGroups = _useState48[1];
7913
+
7914
+ // Registry state
7915
+ var _useState49 = useState(false),
7916
+ _useState50 = _slicedToArray(_useState49, 2),
7917
+ isLoadingRegistry = _useState50[0],
7918
+ setIsLoadingRegistry = _useState50[1];
7919
+ var _useState51 = useState(null),
7920
+ _useState52 = _slicedToArray(_useState51, 2),
7921
+ registryError = _useState52[0],
7922
+ setRegistryError = _useState52[1];
7923
+ var _useState53 = useState([]),
7924
+ _useState54 = _slicedToArray(_useState53, 2),
7925
+ registryPackages = _useState54[0],
7926
+ setRegistryPackages = _useState54[1];
7927
+ var _useState55 = useState("packages"),
7928
+ _useState56 = _slicedToArray(_useState55, 2),
7929
+ registryViewMode = _useState56[0],
7930
+ setRegistryViewMode = _useState56[1]; // "packages" | "widgets"
7931
+ var _useState57 = useState(new Set()),
7932
+ _useState58 = _slicedToArray(_useState57, 2),
7933
+ expandedPackages = _useState58[0],
7934
+ setExpandedPackages = _useState58[1];
7935
+ var _useState59 = useState(null),
7936
+ _useState60 = _slicedToArray(_useState59, 2),
7937
+ selectedPackage = _useState60[0],
7938
+ setSelectedPackage = _useState60[1];
7939
+ var _useState61 = useState(false),
7940
+ _useState62 = _slicedToArray(_useState61, 2),
7941
+ isInstalling = _useState62[0],
7942
+ setIsInstalling = _useState62[1];
7943
+ var _useState63 = useState(null),
7944
+ _useState64 = _slicedToArray(_useState63, 2),
7945
+ installError = _useState64[0],
7946
+ setInstallError = _useState64[1];
7947
+
7948
+ // Phase 3: Recent Widgets - localStorage functions
7949
+ var loadRecentWidgets = function loadRecentWidgets() {
7950
+ try {
7951
+ var stored = localStorage.getItem("recentWidgets");
7952
+ var recentData = stored ? JSON.parse(stored) : [];
7953
+
7954
+ // Get widget details from ComponentManager
7955
+ var allWidgets = ComponentManager.map();
7956
+ var enrichedRecent = recentData.slice(0, 5) // Show top 5
7957
+ .map(function (entry) {
7958
+ var widget = allWidgets[entry.widgetKey];
7959
+ if (!widget) return null; // Widget no longer exists
7960
+ return _objectSpread$q(_objectSpread$q({
7961
+ key: entry.widgetKey
7962
+ }, widget), {}, {
7963
+ savedProviders: entry.providers || {},
7964
+ savedUserConfig: entry.userConfig || {},
7965
+ timestamp: entry.timestamp
7966
+ });
7967
+ }).filter(Boolean); // Remove null entries
7968
+
7969
+ setRecentWidgets(enrichedRecent);
7970
+ } catch (error) {
7971
+ setRecentWidgets([]);
7972
+ }
7973
+ };
7974
+ var saveToRecent = function saveToRecent(widget, providers, userConfig) {
7975
+ try {
7976
+ var stored = localStorage.getItem("recentWidgets");
7977
+ var recent = stored ? JSON.parse(stored) : [];
7978
+
7979
+ // Create new entry
7980
+ var newEntry = {
7981
+ widgetKey: widget.key,
7982
+ timestamp: Date.now(),
7983
+ providers: providers || {},
7984
+ userConfig: userConfig || {}
7985
+ };
7986
+
7987
+ // Remove existing entry for this widget (if any) and add new one at front
7988
+ var updated = [newEntry].concat(_toConsumableArray(recent.filter(function (r) {
7989
+ return r.widgetKey !== widget.key;
7990
+ }))).slice(0, 10); // Keep max 10
7991
+
7992
+ localStorage.setItem("recentWidgets", JSON.stringify(updated));
7993
+
7994
+ // Reload recent widgets to update UI
7995
+ loadRecentWidgets();
7996
+ } catch (error) {
7997
+ }
7998
+ };
7999
+ var handleRecentClick = function handleRecentClick(recentWidget) {
8000
+ setSelectedWidget(recentWidget);
8001
+ setSelectedProviders(recentWidget.savedProviders || {});
8002
+ setUserConfigValues(recentWidget.savedUserConfig || {});
8003
+ // Reset inline provider creation form
8004
+ setInlineCreateType(null);
8005
+ setInlineCreateSchema({});
8006
+ setInlineCreateError(null);
8007
+ };
8008
+
8009
+ // Fetch MCP catalog for inline stepper creation
8010
+ useEffect(function () {
8011
+ if (isOpen && dashApi && mcpCatalog.length === 0) {
8012
+ dashApi.mcpGetCatalog(function (event, result) {
8013
+ return setMcpCatalog((result === null || result === void 0 ? void 0 : result.catalog) || []);
8014
+ }, function () {});
8015
+ }
8016
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8017
+ }, [isOpen, dashApi]);
8018
+
8019
+ // Fetch widgets when modal opens
8020
+ useEffect(function () {
8021
+ if (isOpen) {
8022
+ loadWidgets();
8023
+ loadRecentWidgets(); // Phase 3: Load recent widgets
8024
+ // Reset filters when modal opens
8025
+ setSearchQuery("");
7511
8026
  setSelectedAuthor("all");
7512
8027
  setSelectedProvider("all");
7513
8028
  setExpandedGroups(new Set()); // Start with all groups collapsed
@@ -7593,7 +8108,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7593
8108
  // Get widgets from ComponentManager
7594
8109
  var allWidgets = ComponentManager.map();
7595
8110
  var widgetList = Object.keys(allWidgets).map(function (key) {
7596
- return _objectSpread$r({
8111
+ return _objectSpread$q({
7597
8112
  key: key
7598
8113
  }, allWidgets[key]);
7599
8114
  }).filter(function (widget) {
@@ -7793,21 +8308,37 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7793
8308
  };
7794
8309
  var handleProviderSelect = function handleProviderSelect(providerType, providerName) {
7795
8310
  if (providerName === "__create_new__") {
7796
- // Find credential schema for this provider type
7797
8311
  var providerReq = selectedWidget.providers.find(function (p) {
7798
8312
  return p.type === providerType;
7799
8313
  });
7800
8314
 
7801
- // Show inline creation form
8315
+ // Look up full catalog entry for MCP providers
8316
+ var catalogEntry = mcpCatalog.find(function (s) {
8317
+ return s.id === providerType;
8318
+ });
7802
8319
  setInlineCreateType(providerType);
7803
- setInlineCreateSchema((providerReq === null || providerReq === void 0 ? void 0 : providerReq.credentialSchema) || {});
8320
+ setInlineCreateSchema((catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.credentialSchema) || (providerReq === null || providerReq === void 0 ? void 0 : providerReq.credentialSchema) || {});
7804
8321
  setInlineCreateError(null);
8322
+
8323
+ // Initialize stepper state for MCP providers
8324
+ if (catalogEntry) {
8325
+ setInlineCatalogEntry(catalogEntry);
8326
+ setInlineProviderName(catalogEntry.name);
8327
+ setInlineCredentialData({});
8328
+ setInlineFormErrors({});
8329
+ setInlineWizardStep(0);
8330
+ setInlineTestResult(null);
8331
+ setInlineAuthResult(null);
8332
+ setInlineSelectedTools(null);
8333
+ } else {
8334
+ setInlineCatalogEntry(null);
8335
+ }
7805
8336
  } else {
7806
8337
  // Normal provider selection - also close any open inline form
7807
8338
  setInlineCreateType(null);
7808
8339
  setInlineCreateSchema({});
7809
8340
  setInlineCreateError(null);
7810
- setSelectedProviders(_objectSpread$r(_objectSpread$r({}, selectedProviders), {}, _defineProperty({}, providerType, providerName)));
8341
+ setSelectedProviders(_objectSpread$q(_objectSpread$q({}, selectedProviders), {}, _defineProperty({}, providerType, providerName)));
7811
8342
  }
7812
8343
  };
7813
8344
  var handleInlineProviderSubmit = function handleInlineProviderSubmit(formData) {
@@ -7828,7 +8359,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7828
8359
 
7829
8360
  // Auto-select the newly created provider
7830
8361
  setSelectedProviders(function (prev) {
7831
- return _objectSpread$r(_objectSpread$r({}, prev), {}, _defineProperty({}, providerType, providerName));
8362
+ return _objectSpread$q(_objectSpread$q({}, prev), {}, _defineProperty({}, providerType, providerName));
7832
8363
  });
7833
8364
 
7834
8365
  // Collapse the inline form
@@ -7844,9 +8375,163 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7844
8375
  setInlineCreateType(null);
7845
8376
  setInlineCreateSchema({});
7846
8377
  setInlineCreateError(null);
8378
+ setInlineCatalogEntry(null);
8379
+ setInlineWizardStep(0);
8380
+ setInlineCredentialData({});
8381
+ setInlineProviderName("");
8382
+ setInlineFormErrors({});
8383
+ setInlineTestResult(null);
8384
+ setInlineAuthResult(null);
8385
+ setInlineSelectedTools(null);
8386
+ setInlineIsTesting(false);
8387
+ setInlineIsAuthorizing(false);
7847
8388
  };
7848
- var handleConfigChange = function handleConfigChange(key, value) {
7849
- setUserConfigValues(_objectSpread$r(_objectSpread$r({}, userConfigValues), {}, _defineProperty({}, key, value)));
8389
+
8390
+ // ── Inline MCP Stepper Handlers ──
8391
+
8392
+ var inlineFormFields = useMemo(function () {
8393
+ if (!(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.mcpConfig)) return [];
8394
+ return deriveFormFields(inlineCatalogEntry.mcpConfig, inlineCatalogEntry.credentialSchema || {});
8395
+ }, [inlineCatalogEntry]);
8396
+ var inlineHasAuth = !!(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.authCommand);
8397
+ var inlineWizardSteps = inlineHasAuth ? ["configure", "authorize", "testTools"] : ["configure", "testTools"];
8398
+ var inlineTotalSteps = inlineWizardSteps.length;
8399
+ var inlineCurrentStepType = inlineWizardSteps[inlineWizardStep];
8400
+ var inlineValidateForm = function inlineValidateForm() {
8401
+ var errors = {};
8402
+ if (!(inlineProviderName !== null && inlineProviderName !== void 0 && inlineProviderName.trim())) {
8403
+ errors.providerName = "Provider name is required";
8404
+ }
8405
+ inlineFormFields.forEach(function (field) {
8406
+ var _inlineCredentialData;
8407
+ if (field.required && !((_inlineCredentialData = inlineCredentialData[field.key]) !== null && _inlineCredentialData !== void 0 && _inlineCredentialData.trim())) {
8408
+ errors[field.key] = "".concat(field.displayName, " is required");
8409
+ }
8410
+ });
8411
+ setInlineFormErrors(errors);
8412
+ return Object.keys(errors).length === 0;
8413
+ };
8414
+ var inlineHandleCredentialChange = function inlineHandleCredentialChange(fieldName, value) {
8415
+ setInlineCredentialData(function (prev) {
8416
+ return _objectSpread$q(_objectSpread$q({}, prev), {}, _defineProperty({}, fieldName, value));
8417
+ });
8418
+ if (inlineFormErrors[fieldName] && value !== null && value !== void 0 && value.trim()) {
8419
+ setInlineFormErrors(function (prev) {
8420
+ var next = _objectSpread$q({}, prev);
8421
+ delete next[fieldName];
8422
+ return next;
8423
+ });
8424
+ }
8425
+ };
8426
+ var inlineHandleWizardStepChange = function inlineHandleWizardStepChange(newStep) {
8427
+ if (newStep < inlineWizardStep) {
8428
+ setInlineWizardStep(newStep);
8429
+ return;
8430
+ }
8431
+ if (inlineCurrentStepType === "configure" && newStep > inlineWizardStep) {
8432
+ if (!inlineValidateForm()) return;
8433
+ }
8434
+ if (inlineCurrentStepType === "authorize" && newStep > inlineWizardStep) {
8435
+ if (!(inlineAuthResult !== null && inlineAuthResult !== void 0 && inlineAuthResult.success)) return;
8436
+ }
8437
+ setInlineWizardStep(newStep);
8438
+ };
8439
+ var inlineHandleTestConnection = function inlineHandleTestConnection() {
8440
+ if (!dashApi || !(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.mcpConfig)) return;
8441
+ setInlineIsTesting(true);
8442
+ setInlineTestResult(null);
8443
+ var testName = "__test__".concat(inlineCatalogEntry.id);
8444
+ dashApi.mcpStartServer(testName, inlineCatalogEntry.mcpConfig, inlineCredentialData, function (event, result) {
8445
+ if (result.error) {
8446
+ setInlineTestResult({
8447
+ success: false,
8448
+ message: result.message
8449
+ });
8450
+ setInlineIsTesting(false);
8451
+ return;
8452
+ }
8453
+ setInlineTestResult({
8454
+ success: true,
8455
+ tools: result.tools || [],
8456
+ message: "Connected! Found ".concat((result.tools || []).length, " tools.")
8457
+ });
8458
+ setInlineSelectedTools((result.tools || []).map(function (t) {
8459
+ return t.name;
8460
+ }));
8461
+ dashApi.mcpStopServer(testName, function () {}, function () {});
8462
+ setInlineIsTesting(false);
8463
+ }, function (event, err) {
8464
+ setInlineTestResult({
8465
+ success: false,
8466
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Connection failed"
8467
+ });
8468
+ setInlineIsTesting(false);
8469
+ });
8470
+ };
8471
+ var inlineHandleAuthorize = function inlineHandleAuthorize() {
8472
+ if (!dashApi || !(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.mcpConfig) || !(inlineCatalogEntry !== null && inlineCatalogEntry !== void 0 && inlineCatalogEntry.authCommand)) return;
8473
+ setInlineIsAuthorizing(true);
8474
+ setInlineAuthResult(null);
8475
+ dashApi.mcpRunAuth(inlineCatalogEntry.mcpConfig, inlineCredentialData, inlineCatalogEntry.authCommand, function (event, result) {
8476
+ if (result.error) {
8477
+ setInlineAuthResult({
8478
+ success: false,
8479
+ message: result.message
8480
+ });
8481
+ } else {
8482
+ setInlineAuthResult({
8483
+ success: true,
8484
+ message: "Authorized!"
8485
+ });
8486
+ }
8487
+ setInlineIsAuthorizing(false);
8488
+ }, function (event, err) {
8489
+ setInlineAuthResult({
8490
+ success: false,
8491
+ message: (err === null || err === void 0 ? void 0 : err.message) || "Authorization failed"
8492
+ });
8493
+ setInlineIsAuthorizing(false);
8494
+ });
8495
+ };
8496
+ var inlineHandleSave = function inlineHandleSave() {
8497
+ if (!inlineCatalogEntry || !inlineValidateForm()) return;
8498
+ var providerType = inlineCreateType;
8499
+ var providerName = inlineProviderName.trim();
8500
+ setIsCreatingProvider(true);
8501
+ setInlineCreateError(null);
8502
+ dashApi.saveProvider(credentials.appId, providerName, {
8503
+ providerType: providerType,
8504
+ credentials: inlineCredentialData,
8505
+ providerClass: "mcp",
8506
+ mcpConfig: inlineCatalogEntry.mcpConfig,
8507
+ allowedTools: inlineSelectedTools
8508
+ }, function (event, result) {
8509
+ if (refreshProviders) {
8510
+ refreshProviders();
8511
+ }
8512
+ setSelectedProviders(function (prev) {
8513
+ return _objectSpread$q(_objectSpread$q({}, prev), {}, _defineProperty({}, providerType, providerName));
8514
+ });
8515
+
8516
+ // Reset stepper state
8517
+ setInlineCreateType(null);
8518
+ setInlineCreateSchema({});
8519
+ setInlineCatalogEntry(null);
8520
+ setIsCreatingProvider(false);
8521
+ setInlineWizardStep(0);
8522
+ setInlineCredentialData({});
8523
+ setInlineProviderName("");
8524
+ setInlineFormErrors({});
8525
+ setInlineTestResult(null);
8526
+ setInlineAuthResult(null);
8527
+ setInlineSelectedTools(null);
8528
+ }, function (event, error) {
8529
+ setInlineCreateError("Failed to create provider: ".concat((error === null || error === void 0 ? void 0 : error.message) || "Unknown error"));
8530
+ setIsCreatingProvider(false);
8531
+ });
8532
+ };
8533
+ var handleConfigChange = function handleConfigChange(key, value) {
8534
+ setUserConfigValues(_objectSpread$q(_objectSpread$q({}, userConfigValues), {}, _defineProperty({}, key, value)));
7850
8535
  };
7851
8536
 
7852
8537
  // Install a package from the registry
@@ -7936,7 +8621,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
7936
8621
 
7937
8622
  // Phase 3: Save to recent widgets
7938
8623
  saveToRecent(selectedWidget, selectedProviders, userConfigValues);
7939
- onSelectWidget(_objectSpread$r(_objectSpread$r({}, selectedWidget), {}, {
8624
+ onSelectWidget(_objectSpread$q(_objectSpread$q({}, selectedWidget), {}, {
7940
8625
  selectedProviders: selectedProviders,
7941
8626
  // Pass to parent
7942
8627
  userConfigValues: userConfigValues // Pass to parent
@@ -8477,6 +9162,7 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
8477
9162
  }), /*#__PURE__*/jsx("div", {
8478
9163
  className: "space-y-2",
8479
9164
  children: selectedWidget.providers.map(function (providerReq, idx) {
9165
+ var _inlineCatalogEntry$m, _inlineCatalogEntry$m2, _inlineCatalogEntry$m3, _inlineCatalogEntry$m4, _inlineCatalogEntry$m5, _inlineTestResult$too;
8480
9166
  // Get available providers of this type
8481
9167
  var providersOfType = Object.values(availableProviders).filter(function (p) {
8482
9168
  return p.type === providerReq.type;
@@ -8521,7 +9207,227 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
8521
9207
  className: "text-xs text-red-400",
8522
9208
  children: inlineCreateError
8523
9209
  })
8524
- }), /*#__PURE__*/jsx(ProviderForm, {
9210
+ }), inlineCatalogEntry ?
9211
+ /*#__PURE__*/
9212
+ /* MCP Provider: Stepper-based creation */
9213
+ jsxs("div", {
9214
+ className: "space-y-3",
9215
+ children: [/*#__PURE__*/jsxs(Stepper, {
9216
+ activeStep: inlineWizardStep,
9217
+ onStepChange: inlineHandleWizardStepChange,
9218
+ showNavigation: false,
9219
+ className: "flex-1 min-h-0 flex flex-col",
9220
+ children: [/*#__PURE__*/jsx(Stepper.Step, {
9221
+ label: "Configure",
9222
+ description: "Name & credentials",
9223
+ children: /*#__PURE__*/jsxs("div", {
9224
+ className: "space-y-4 pb-2",
9225
+ children: [/*#__PURE__*/jsxs("div", {
9226
+ className: "bg-white/5 border border-white/10 rounded-lg p-3 space-y-2",
9227
+ children: [/*#__PURE__*/jsx("p", {
9228
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
9229
+ children: "MCP Server Connection"
9230
+ }), /*#__PURE__*/jsxs("div", {
9231
+ className: "space-y-1 text-sm",
9232
+ children: [/*#__PURE__*/jsxs("div", {
9233
+ className: "flex gap-2",
9234
+ children: [/*#__PURE__*/jsx("span", {
9235
+ className: "opacity-50 w-20 shrink-0",
9236
+ children: "Transport:"
9237
+ }), /*#__PURE__*/jsx(Tag, {
9238
+ text: ((_inlineCatalogEntry$m = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m === void 0 ? void 0 : _inlineCatalogEntry$m.transport) === "streamable_http" ? "Streamable HTTP" : "stdio"
9239
+ })]
9240
+ }), ((_inlineCatalogEntry$m2 = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m2 === void 0 ? void 0 : _inlineCatalogEntry$m2.transport) !== "streamable_http" && /*#__PURE__*/jsxs("div", {
9241
+ className: "flex gap-2",
9242
+ children: [/*#__PURE__*/jsx("span", {
9243
+ className: "opacity-50 w-20 shrink-0",
9244
+ children: "Command:"
9245
+ }), /*#__PURE__*/jsxs("code", {
9246
+ className: "text-xs bg-white/5 px-2 py-0.5 rounded",
9247
+ 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(" ")]
9248
+ })]
9249
+ })]
9250
+ })]
9251
+ }), /*#__PURE__*/jsxs("div", {
9252
+ className: "flex flex-col gap-1",
9253
+ children: [/*#__PURE__*/jsx(FormLabel, {
9254
+ label: "Provider Name",
9255
+ required: true
9256
+ }), /*#__PURE__*/jsx(InputText, {
9257
+ value: inlineProviderName,
9258
+ onChange: function onChange(value) {
9259
+ setInlineProviderName(value);
9260
+ if (inlineFormErrors.providerName && value !== null && value !== void 0 && value.trim()) {
9261
+ setInlineFormErrors(function (prev) {
9262
+ var next = _objectSpread$q({}, prev);
9263
+ delete next.providerName;
9264
+ return next;
9265
+ });
9266
+ }
9267
+ },
9268
+ placeholder: "Enter provider name"
9269
+ }), inlineFormErrors.providerName && /*#__PURE__*/jsx("p", {
9270
+ className: "text-xs text-red-400",
9271
+ children: inlineFormErrors.providerName
9272
+ })]
9273
+ }), inlineFormFields.length > 0 && /*#__PURE__*/jsxs(Fragment, {
9274
+ children: [/*#__PURE__*/jsx("div", {
9275
+ className: "border-t border-white/10 pt-3",
9276
+ children: /*#__PURE__*/jsx("p", {
9277
+ className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
9278
+ children: ((_inlineCatalogEntry$m5 = inlineCatalogEntry.mcpConfig) === null || _inlineCatalogEntry$m5 === void 0 ? void 0 : _inlineCatalogEntry$m5.transport) === "streamable_http" ? "Server Configuration" : "Authentication"
9279
+ })
9280
+ }), inlineFormFields.map(function (field) {
9281
+ return /*#__PURE__*/jsxs("div", {
9282
+ className: "flex flex-col gap-1",
9283
+ children: [/*#__PURE__*/jsx(FormLabel, {
9284
+ label: field.displayName,
9285
+ required: field.required
9286
+ }), field.instructions && /*#__PURE__*/jsx("p", {
9287
+ className: "text-xs opacity-50",
9288
+ children: field.instructions
9289
+ }), /*#__PURE__*/jsxs("div", {
9290
+ className: "flex gap-2",
9291
+ children: [/*#__PURE__*/jsx("div", {
9292
+ className: "flex-1",
9293
+ children: /*#__PURE__*/jsx(InputText, {
9294
+ type: field.secret ? "password" : "text",
9295
+ value: inlineCredentialData[field.key] || "",
9296
+ onChange: function onChange(value) {
9297
+ return inlineHandleCredentialChange(field.key, value);
9298
+ },
9299
+ placeholder: field.type === "file" ? "Select a file..." : "Enter ".concat(field.displayName.toLowerCase())
9300
+ })
9301
+ }), field.type === "file" && /*#__PURE__*/jsx("button", {
9302
+ onClick: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
9303
+ var filepath;
9304
+ return _regeneratorRuntime.wrap(function (_context3) {
9305
+ while (1) switch (_context3.prev = _context3.next) {
9306
+ case 0:
9307
+ _context3.next = 1;
9308
+ return window.mainApi.dialog.chooseFile(true, ["json"]);
9309
+ case 1:
9310
+ filepath = _context3.sent;
9311
+ if (filepath) inlineHandleCredentialChange(field.key, filepath);
9312
+ case 2:
9313
+ case "end":
9314
+ return _context3.stop();
9315
+ }
9316
+ }, _callee3);
9317
+ })),
9318
+ className: "px-3 py-1.5 text-sm rounded bg-white/10 hover:bg-white/20 transition-colors",
9319
+ children: "Browse"
9320
+ })]
9321
+ }), inlineFormErrors[field.key] && /*#__PURE__*/jsx("p", {
9322
+ className: "text-xs text-red-400",
9323
+ children: inlineFormErrors[field.key]
9324
+ })]
9325
+ }, field.key);
9326
+ })]
9327
+ })]
9328
+ })
9329
+ }), inlineHasAuth && /*#__PURE__*/jsx(Stepper.Step, {
9330
+ label: "Authorize",
9331
+ description: "OAuth authentication",
9332
+ children: /*#__PURE__*/jsxs("div", {
9333
+ className: "space-y-4 pb-2",
9334
+ children: [/*#__PURE__*/jsxs("div", {
9335
+ className: "flex flex-col items-center justify-center py-6 space-y-3",
9336
+ children: [/*#__PURE__*/jsx("p", {
9337
+ className: "text-sm opacity-60 text-center max-w-md",
9338
+ children: "This server requires OAuth authorization. Click the button below to open a browser window and complete the authentication flow."
9339
+ }), /*#__PURE__*/jsx(Button, {
9340
+ title: inlineIsAuthorizing ? "Authorizing..." : "Authorize",
9341
+ onClick: inlineHandleAuthorize,
9342
+ size: "sm"
9343
+ })]
9344
+ }), inlineAuthResult && /*#__PURE__*/jsx("div", {
9345
+ 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"),
9346
+ children: /*#__PURE__*/jsxs("div", {
9347
+ className: "flex items-center gap-2",
9348
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
9349
+ icon: inlineAuthResult.success ? "circle-check" : "circle-exclamation"
9350
+ }), /*#__PURE__*/jsx("span", {
9351
+ children: inlineAuthResult.message
9352
+ })]
9353
+ })
9354
+ })]
9355
+ })
9356
+ }), /*#__PURE__*/jsx(Stepper.Step, {
9357
+ label: "Test & Tools",
9358
+ description: "Verify & select tools",
9359
+ children: /*#__PURE__*/jsxs("div", {
9360
+ className: "space-y-3 pb-2",
9361
+ children: [/*#__PURE__*/jsxs("div", {
9362
+ className: "flex items-center gap-3",
9363
+ children: [/*#__PURE__*/jsx(Button, {
9364
+ title: inlineIsTesting ? "Fetching..." : "Fetch Tools",
9365
+ onClick: inlineHandleTestConnection,
9366
+ size: "sm"
9367
+ }), inlineTestResult && /*#__PURE__*/jsxs("span", {
9368
+ className: "text-sm ".concat(inlineTestResult.success ? "text-green-400" : "text-red-400"),
9369
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
9370
+ icon: inlineTestResult.success ? "circle-check" : "circle-exclamation",
9371
+ className: "mr-1"
9372
+ }), inlineTestResult.message]
9373
+ })]
9374
+ }), (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__*/jsx(ToolSelector, {
9375
+ tools: inlineTestResult.tools,
9376
+ selectedTools: inlineSelectedTools,
9377
+ onSelectionChange: setInlineSelectedTools
9378
+ }), !inlineTestResult && /*#__PURE__*/jsx("div", {
9379
+ className: "text-center py-6 opacity-50 text-sm",
9380
+ children: "Click \"Fetch Tools\" to test the connection and discover available tools."
9381
+ })]
9382
+ })
9383
+ })]
9384
+ }), /*#__PURE__*/jsxs("div", {
9385
+ className: "flex flex-row items-center pt-3 border-t border-white/10",
9386
+ children: [/*#__PURE__*/jsxs("div", {
9387
+ className: "flex flex-row gap-2",
9388
+ children: [inlineWizardStep === 0 && /*#__PURE__*/jsx(Button, {
9389
+ title: "Cancel",
9390
+ onClick: handleInlineProviderCancel,
9391
+ size: "sm"
9392
+ }), inlineWizardStep > 0 && /*#__PURE__*/jsx(Button, {
9393
+ title: "Back",
9394
+ onClick: function onClick() {
9395
+ return setInlineWizardStep(inlineWizardStep - 1);
9396
+ },
9397
+ size: "sm"
9398
+ })]
9399
+ }), /*#__PURE__*/jsx("div", {
9400
+ className: "flex-1 text-center",
9401
+ children: /*#__PURE__*/jsxs("span", {
9402
+ className: "text-xs opacity-40",
9403
+ children: ["Step ", inlineWizardStep + 1, " of ", inlineTotalSteps]
9404
+ })
9405
+ }), /*#__PURE__*/jsxs("div", {
9406
+ className: "flex flex-row gap-2",
9407
+ children: [inlineCurrentStepType === "configure" && /*#__PURE__*/jsx(Button, {
9408
+ title: "Next",
9409
+ onClick: function onClick() {
9410
+ return inlineHandleWizardStepChange(inlineWizardStep + 1);
9411
+ },
9412
+ size: "sm"
9413
+ }), inlineCurrentStepType === "authorize" && /*#__PURE__*/jsx(Button, {
9414
+ title: "Next",
9415
+ onClick: function onClick() {
9416
+ return inlineHandleWizardStepChange(inlineWizardStep + 1);
9417
+ },
9418
+ disabled: !(inlineAuthResult !== null && inlineAuthResult !== void 0 && inlineAuthResult.success),
9419
+ size: "sm"
9420
+ }), inlineCurrentStepType === "testTools" && /*#__PURE__*/jsx(Button, {
9421
+ title: isCreatingProvider ? "Saving..." : "Save MCP Server",
9422
+ onClick: inlineHandleSave,
9423
+ size: "sm"
9424
+ })]
9425
+ })]
9426
+ })]
9427
+ }) :
9428
+ /*#__PURE__*/
9429
+ /* Credential Provider: flat form fallback */
9430
+ jsx(ProviderForm, {
8525
9431
  credentialSchema: inlineCreateSchema,
8526
9432
  onSubmit: handleInlineProviderSubmit,
8527
9433
  onCancel: handleInlineProviderCancel,
@@ -8540,10 +9446,10 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
8540
9446
  children: "CONFIGURATION"
8541
9447
  }), /*#__PURE__*/jsx("div", {
8542
9448
  className: "space-y-2",
8543
- children: Object.entries(selectedWidget.userConfig).map(function (_ref8) {
8544
- var _ref9 = _slicedToArray(_ref8, 2),
8545
- key = _ref9[0],
8546
- config = _ref9[1];
9449
+ children: Object.entries(selectedWidget.userConfig).map(function (_ref9) {
9450
+ var _ref0 = _slicedToArray(_ref9, 2),
9451
+ key = _ref0[0],
9452
+ config = _ref0[1];
8547
9453
  return /*#__PURE__*/jsxs("div", {
8548
9454
  className: "space-y-1",
8549
9455
  children: [/*#__PURE__*/jsxs("label", {
@@ -9028,748 +9934,367 @@ var WidgetCardHeader = function WidgetCardHeader(_ref) {
9028
9934
  position: "absolute top-full right-0 mt-1",
9029
9935
  portal: true,
9030
9936
  align: "right",
9031
- children: [/*#__PURE__*/jsx(DropdownPanel.Header, {
9032
- children: "Actions"
9033
- }), overflowActions.map(function (action) {
9034
- return /*#__PURE__*/jsxs(MenuItem2, {
9035
- onClick: action.onClick,
9036
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
9037
- icon: action.icon,
9038
- className: "w-4 text-center opacity-60"
9039
- }), /*#__PURE__*/jsx("span", {
9040
- children: action.label
9041
- })]
9042
- }, action.label);
9043
- })]
9044
- })]
9045
- }) : null
9046
- })]
9047
- });
9048
- };
9049
-
9050
- /**
9051
- * WidgetCard
9052
- *
9053
- * Wrapper component for widgets that provides:
9054
- * - Header with drag handle, provider controls, actions (edit mode only)
9055
- * - Body with padding around widget content (edit mode only)
9056
- * - Footer for future features (edit mode only)
9057
- *
9058
- * In preview mode (preview === true):
9059
- * - Only renders the widget content without any wrapper
9060
- *
9061
- * In edit mode (preview === false):
9062
- * - Renders header + padded content + optional footer
9063
- */
9064
-
9065
- var WidgetCardContext = /*#__PURE__*/React__default.createContext({
9066
- preview: false
9067
- });
9068
-
9069
- /**
9070
- * WidgetCard.Header - Header section with controls
9071
- * Only renders in edit mode (preview === false)
9072
- */
9073
- var WidgetCardHeader_Component = function WidgetCardHeader_Component(_ref) {
9074
- var item = _ref.item,
9075
- _ref$cellNumber = _ref.cellNumber,
9076
- cellNumber = _ref$cellNumber === void 0 ? null : _ref$cellNumber,
9077
- _ref$providers = _ref.providers,
9078
- providers = _ref$providers === void 0 ? [] : _ref$providers,
9079
- _ref$selectedProvider = _ref.selectedProviders,
9080
- selectedProviders = _ref$selectedProvider === void 0 ? {} : _ref$selectedProvider,
9081
- onProviderChange = _ref.onProviderChange,
9082
- onConfigure = _ref.onConfigure,
9083
- onDelete = _ref.onDelete,
9084
- _ref$onSplitHorizonta = _ref.onSplitHorizontal,
9085
- onSplitHorizontal = _ref$onSplitHorizonta === void 0 ? null : _ref$onSplitHorizonta,
9086
- _ref$onSplitVertical = _ref.onSplitVertical,
9087
- onSplitVertical = _ref$onSplitVertical === void 0 ? null : _ref$onSplitVertical,
9088
- _ref$isSelected = _ref.isSelected,
9089
- isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
9090
- _ref$isSelectable = _ref.isSelectable,
9091
- isSelectable = _ref$isSelectable === void 0 ? true : _ref$isSelectable,
9092
- _ref$onToggleSelect = _ref.onToggleSelect,
9093
- onToggleSelect = _ref$onToggleSelect === void 0 ? null : _ref$onToggleSelect;
9094
- var _React$useContext = React__default.useContext(WidgetCardContext),
9095
- preview = _React$useContext.preview;
9096
-
9097
- // Don't render header in preview mode
9098
- if (preview === true) {
9099
- return null;
9100
- }
9101
- return /*#__PURE__*/jsx(WidgetCardHeader, {
9102
- item: item,
9103
- cellNumber: cellNumber,
9104
- providers: providers,
9105
- selectedProviders: selectedProviders,
9106
- onProviderChange: onProviderChange,
9107
- onConfigure: onConfigure,
9108
- onDelete: onDelete,
9109
- onSplitHorizontal: onSplitHorizontal,
9110
- onSplitVertical: onSplitVertical,
9111
- isSelected: isSelected,
9112
- isSelectable: isSelectable,
9113
- onToggleSelect: onToggleSelect
9114
- });
9115
- };
9116
-
9117
- /**
9118
- * WidgetCard.Body - Body section with widget content
9119
- * In edit mode: adds padding around content
9120
- * In preview mode: renders content without padding
9121
- */
9122
- var WidgetCardBody = function WidgetCardBody(_ref2) {
9123
- var children = _ref2.children,
9124
- _ref2$padding = _ref2.padding,
9125
- padding = _ref2$padding === void 0 ? "p-2" : _ref2$padding,
9126
- _ref2$className = _ref2.className,
9127
- className = _ref2$className === void 0 ? "" : _ref2$className;
9128
- var _React$useContext2 = React__default.useContext(WidgetCardContext),
9129
- preview = _React$useContext2.preview;
9130
-
9131
- // In preview mode, render children without padding wrapper
9132
- if (preview === true) {
9133
- return /*#__PURE__*/jsx(Fragment, {
9134
- children: children
9135
- });
9136
- }
9137
-
9138
- // In edit mode, render with padding
9139
- return /*#__PURE__*/jsx("div", {
9140
- className: "flex-1 min-h-0 overflow-auto ".concat(padding, " ").concat(className),
9141
- children: children
9142
- });
9143
- };
9144
-
9145
- /**
9146
- * WidgetCard.Footer - Footer section with handler warnings
9147
- * Only renders in edit mode (preview === false)
9148
- * Shows amber warning when widget has eventHandlers that lack listener connections
9149
- */
9150
- var WidgetCardFooter = function WidgetCardFooter(_ref3) {
9151
- var children = _ref3.children,
9152
- _ref3$item = _ref3.item,
9153
- item = _ref3$item === void 0 ? null : _ref3$item,
9154
- _ref3$onConfigure = _ref3.onConfigure,
9155
- onConfigure = _ref3$onConfigure === void 0 ? null : _ref3$onConfigure,
9156
- _ref3$className = _ref3.className,
9157
- className = _ref3$className === void 0 ? "" : _ref3$className;
9158
- var _React$useContext3 = React__default.useContext(WidgetCardContext),
9159
- preview = _React$useContext3.preview;
9160
- if (preview === true) return null;
9161
-
9162
- // Compute unconfigured handlers
9163
- var widgetConfig = item !== null && item !== void 0 && item.component ? ComponentManager.config(item.component, item) : null;
9164
- var eventHandlers = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.eventHandlers) || [];
9165
- var listeners = (item === null || item === void 0 ? void 0 : item.listeners) || {};
9166
- var unconfiguredCount = eventHandlers.filter(function (h) {
9167
- return !listeners[h] || listeners[h].length === 0;
9168
- }).length;
9169
-
9170
- // Don't render if no children AND no warnings
9171
- if (!children && unconfiguredCount === 0) return null;
9172
- return /*#__PURE__*/jsxs("div", {
9173
- className: "border-t border-gray-700 px-3 py-1.5 bg-transparent ".concat(className),
9174
- children: [children, unconfiguredCount > 0 && /*#__PURE__*/jsxs("button", {
9175
- type: "button",
9176
- onClick: function onClick() {
9177
- return onConfigure && onConfigure(item, "handlers");
9178
- },
9179
- 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",
9180
- title: "Click to configure listeners",
9181
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
9182
- icon: "phone",
9183
- className: "text-[10px]"
9184
- }), /*#__PURE__*/jsxs("span", {
9185
- children: [unconfiguredCount, " listener", unconfiguredCount > 1 ? "s" : "", " not connected"]
9186
- })]
9187
- })]
9188
- });
9189
- };
9190
-
9191
- /**
9192
- * WidgetCard - Main wrapper component
9193
- *
9194
- * In preview mode: renders children without any wrapper
9195
- * In edit mode: wraps children in a container
9196
- */
9197
- var WidgetCard = function WidgetCard(_ref4) {
9198
- var _ref4$preview = _ref4.preview,
9199
- preview = _ref4$preview === void 0 ? false : _ref4$preview,
9200
- children = _ref4.children,
9201
- _ref4$className = _ref4.className,
9202
- className = _ref4$className === void 0 ? "" : _ref4$className;
9203
- // In preview mode, render children without wrapper
9204
- if (preview === true) {
9205
- return /*#__PURE__*/jsx(WidgetCardContext.Provider, {
9206
- value: {
9207
- preview: preview
9208
- },
9209
- children: children
9210
- });
9211
- }
9212
-
9213
- // In edit mode, render with wrapper (no padding - Body handles padding)
9214
- return /*#__PURE__*/jsx(WidgetCardContext.Provider, {
9215
- value: {
9216
- preview: preview
9217
- },
9218
- children: /*#__PURE__*/jsx("div", {
9219
- className: "flex flex-col w-full h-full min-h-0 overflow-hidden rounded border border-dashed border-gray-700 ".concat(className),
9220
- children: children
9221
- })
9222
- });
9223
- };
9224
-
9225
- // Attach subcomponents
9226
- WidgetCard.Header = WidgetCardHeader_Component;
9227
- WidgetCard.Body = WidgetCardBody;
9228
- WidgetCard.Footer = WidgetCardFooter;
9229
-
9230
- var ProviderSelector = function ProviderSelector(_ref) {
9231
- var isOpen = _ref.isOpen,
9232
- setIsOpen = _ref.setIsOpen,
9233
- providerType = _ref.providerType,
9234
- _ref$existingProvider = _ref.existingProviders,
9235
- existingProviders = _ref$existingProvider === void 0 ? [] : _ref$existingProvider,
9236
- _ref$credentialSchema = _ref.credentialSchema,
9237
- credentialSchema = _ref$credentialSchema === void 0 ? {} : _ref$credentialSchema,
9238
- onSelect = _ref.onSelect,
9239
- onCreate = _ref.onCreate;
9240
- var _useState = useState("select"),
9241
- _useState2 = _slicedToArray(_useState, 2),
9242
- activeTab = _useState2[0],
9243
- setActiveTab = _useState2[1]; // "select" or "create"
9244
-
9245
- /**
9246
- * Filter providers by type
9247
- */
9248
- var filteredProviders = existingProviders.filter(function (p) {
9249
- return p.type === providerType;
9250
- });
9251
-
9252
- /**
9253
- * Handle provider selection
9254
- */
9255
- var handleSelectProvider = function handleSelectProvider(providerName) {
9256
- onSelect(providerName);
9257
- setIsOpen(false);
9258
- };
9259
-
9260
- /**
9261
- * Handle new provider creation
9262
- */
9263
- var handleCreateProvider = function handleCreateProvider(formData) {
9264
- // formData now contains { name, credentials }
9265
- var providerName = formData.name,
9266
- credentials = formData.credentials;
9267
- onCreate(providerName, credentials);
9268
- setIsOpen(false);
9269
- };
9270
- return /*#__PURE__*/jsx(Modal, {
9271
- isOpen: isOpen,
9272
- setIsOpen: setIsOpen,
9273
- width: "w-11/12 xl:w-5/6",
9274
- height: "h-5/6",
9275
- children: /*#__PURE__*/jsxs(Panel, {
9276
- border: true,
9277
- padding: false,
9278
- backgroundColor: "bg-gray-800",
9279
- borderColor: "border-gray-700",
9280
- children: [/*#__PURE__*/jsx(Panel.Header, {
9281
- border: true,
9282
- borderColor: "border-gray-700",
9283
- children: /*#__PURE__*/jsxs("div", {
9284
- className: "flex flex-col w-full space-y-4",
9285
- children: [/*#__PURE__*/jsxs("div", {
9286
- className: "flex flex-row justify-between items-start",
9287
- children: [/*#__PURE__*/jsxs("div", {
9288
- className: "flex-1",
9289
- children: [/*#__PURE__*/jsx("h2", {
9290
- className: "text-2xl font-bold text-gray-100",
9291
- children: providerType ? /*#__PURE__*/jsxs(Fragment, {
9292
- children: ["Manage ", /*#__PURE__*/jsx("span", {
9293
- className: "capitalize",
9294
- children: providerType
9295
- }), " ", "Providers"]
9296
- }) : "Select Provider"
9297
- }), /*#__PURE__*/jsx("p", {
9298
- className: "text-sm text-gray-400 mt-1",
9299
- children: activeTab === "select" ? "Select an existing ".concat(providerType, " provider or create a new one") : "Create a new ".concat(providerType, " provider")
9300
- })]
9301
- }), /*#__PURE__*/jsx("button", {
9302
- onClick: function onClick() {
9303
- return setIsOpen(false);
9304
- },
9305
- className: "ml-4 text-gray-400 hover:text-gray-200 transition-colors",
9306
- children: /*#__PURE__*/jsx(FontAwesomeIcon, {
9307
- icon: "times",
9308
- className: "text-xl"
9309
- })
9310
- })]
9311
- }), /*#__PURE__*/jsxs("div", {
9312
- className: "flex gap-2",
9313
- children: [/*#__PURE__*/jsx(Button, {
9314
- title: "Select Existing (".concat(filteredProviders.length, ")"),
9315
- onClick: function onClick() {
9316
- return setActiveTab("select");
9317
- },
9318
- backgroundColor: activeTab === "select" ? "bg-blue-600" : "bg-gray-700",
9319
- hoverBackgroundColor: activeTab === "select" ? "hover:bg-blue-700" : "hover:bg-gray-600",
9320
- padding: "px-4 py-2",
9321
- textSize: "text-sm"
9322
- }), /*#__PURE__*/jsx(Button, {
9323
- title: "Create New",
9324
- onClick: function onClick() {
9325
- return setActiveTab("create");
9326
- },
9327
- backgroundColor: activeTab === "create" ? "bg-blue-600" : "bg-gray-700",
9328
- hoverBackgroundColor: activeTab === "create" ? "hover:bg-blue-700" : "hover:bg-gray-600",
9329
- padding: "px-4 py-2",
9330
- textSize: "text-sm"
9331
- })]
9332
- })]
9333
- })
9334
- }), /*#__PURE__*/jsx(Panel.Body, {
9335
- children: /*#__PURE__*/jsx("div", {
9336
- className: "h-full overflow-y-auto",
9337
- children: activeTab === "select" ?
9338
- /*#__PURE__*/
9339
- // Select Tab
9340
- jsx("div", {
9341
- className: "p-6",
9342
- children: filteredProviders.length > 0 ? /*#__PURE__*/jsx("div", {
9343
- className: "space-y-3",
9344
- children: filteredProviders.map(function (provider) {
9345
- return /*#__PURE__*/jsxs("button", {
9346
- onClick: function onClick() {
9347
- return handleSelectProvider(provider.name);
9348
- },
9349
- 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",
9350
- children: [/*#__PURE__*/jsx("div", {
9351
- className: "font-semibold",
9352
- children: provider.name
9353
- }), /*#__PURE__*/jsxs("div", {
9354
- className: "text-sm opacity-70 mt-1",
9355
- children: ["Type:", " ", /*#__PURE__*/jsx("span", {
9356
- className: "capitalize",
9357
- children: provider.type
9358
- })]
9359
- }), provider.credentials && Object.keys(provider.credentials).length > 0 && /*#__PURE__*/jsxs("div", {
9360
- className: "text-xs opacity-50 mt-2",
9361
- children: ["Fields:", " ", Object.keys(provider.credentials).join(", ")]
9362
- })]
9363
- }, provider.name);
9364
- })
9365
- }) : /*#__PURE__*/jsxs("div", {
9366
- className: "text-center py-12",
9367
- children: [/*#__PURE__*/jsxs(SubHeading3, {
9368
- className: "opacity-50",
9369
- children: ["No ", providerType, " providers found"]
9370
- }), /*#__PURE__*/jsx(Paragraph, {
9371
- className: "mt-2 opacity-70",
9372
- children: "Create one using the \"Create New\" tab"
9937
+ children: [/*#__PURE__*/jsx(DropdownPanel.Header, {
9938
+ children: "Actions"
9939
+ }), overflowActions.map(function (action) {
9940
+ return /*#__PURE__*/jsxs(MenuItem2, {
9941
+ onClick: action.onClick,
9942
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
9943
+ icon: action.icon,
9944
+ className: "w-4 text-center opacity-60"
9945
+ }), /*#__PURE__*/jsx("span", {
9946
+ children: action.label
9373
9947
  })]
9374
- })
9375
- }) :
9376
- /*#__PURE__*/
9377
- // Create Tab
9378
- jsx(ProviderForm, {
9379
- credentialSchema: credentialSchema,
9380
- onSubmit: handleCreateProvider,
9381
- onCancel: function onCancel() {
9382
- return setIsOpen(false);
9383
- },
9384
- submitLabel: "Create Provider",
9385
- providerType: providerType
9386
- })
9387
- })
9388
- })]
9389
- })
9948
+ }, action.label);
9949
+ })]
9950
+ })]
9951
+ }) : null
9952
+ })]
9390
9953
  });
9391
9954
  };
9392
9955
 
9393
- 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; }
9394
- 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; }
9395
9956
  /**
9396
- * Shared MCP utility functions.
9957
+ * WidgetCard
9397
9958
  *
9398
- * Extracted from McpServerPicker so ProviderDetail (and any future consumer)
9399
- * can reuse the same field-derivation logic.
9400
- */
9401
-
9402
- /**
9403
- * Derive required form fields from an mcpConfig, using credentialSchema
9404
- * as optional enrichment for display names, instructions, and secret flags.
9959
+ * Wrapper component for widgets that provides:
9960
+ * - Header with drag handle, provider controls, actions (edit mode only)
9961
+ * - Body with padding around widget content (edit mode only)
9962
+ * - Footer for future features (edit mode only)
9405
9963
  *
9406
- * For streamable_http: extracts {{placeholder}} fields from url and headerTemplate.
9407
- * For stdio: extracts credential field names from envMapping values.
9964
+ * In preview mode (preview === true):
9965
+ * - Only renders the widget content without any wrapper
9408
9966
  *
9409
- * @param {object} mcpConfig - The MCP server configuration
9410
- * @param {object} credentialSchema - Optional metadata for field labels/instructions
9411
- * @returns {Array<{ key, displayName, required, secret, instructions, type }>}
9967
+ * In edit mode (preview === false):
9968
+ * - Renders header + padded content + optional footer
9412
9969
  */
9413
- function deriveFormFields(mcpConfig) {
9414
- var credentialSchema = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9415
- var fieldKeys = new Set();
9416
- if (mcpConfig.transport === "streamable_http") {
9417
- // Extract {{field}} placeholders from url
9418
- if (mcpConfig.url) {
9419
- var urlMatches = mcpConfig.url.match(/\{\{(\w+)\}\}/g) || [];
9420
- urlMatches.forEach(function (m) {
9421
- return fieldKeys.add(m.slice(2, -2));
9422
- });
9423
- }
9424
- // Extract {{field}} placeholders from headerTemplate values
9425
- if (mcpConfig.headerTemplate) {
9426
- Object.values(mcpConfig.headerTemplate).forEach(function (template) {
9427
- var matches = template.match(/\{\{(\w+)\}\}/g) || [];
9428
- matches.forEach(function (m) {
9429
- return fieldKeys.add(m.slice(2, -2));
9430
- });
9431
- });
9432
- }
9433
- } else {
9434
- // stdio: extract credential field names from envMapping values
9435
- if (mcpConfig.envMapping) {
9436
- Object.values(mcpConfig.envMapping).forEach(function (credField) {
9437
- fieldKeys.add(credField);
9438
- });
9439
- }
9440
- }
9441
-
9442
- // Also include any fields defined in credentialSchema that aren't already derived
9443
- if (credentialSchema) {
9444
- Object.keys(credentialSchema).forEach(function (key) {
9445
- return fieldKeys.add(key);
9446
- });
9447
- }
9448
-
9449
- // Build the field list with metadata from credentialSchema or auto-generated defaults
9450
- return Array.from(fieldKeys).map(function (key) {
9451
- var schemaMeta = credentialSchema[key];
9452
- if (schemaMeta) {
9453
- return {
9454
- key: key,
9455
- displayName: schemaMeta.displayName || formatFieldName(key),
9456
- required: schemaMeta.required === true,
9457
- secret: schemaMeta.secret || false,
9458
- instructions: schemaMeta.instructions || null,
9459
- type: schemaMeta.type || "text"
9460
- };
9461
- }
9462
9970
 
9463
- // Auto-generate defaults from the field name
9464
- return {
9465
- key: key,
9466
- displayName: formatFieldName(key),
9467
- required: false,
9468
- secret: isLikelySecret(key),
9469
- instructions: null,
9470
- type: "text"
9471
- };
9472
- });
9473
- }
9971
+ var WidgetCardContext = /*#__PURE__*/React__default.createContext({
9972
+ preview: false
9973
+ });
9474
9974
 
9475
9975
  /**
9476
- * Convert a camelCase field name to a human-readable title.
9477
- * e.g., "apiKey" "API Key", "url" "URL", "botToken" → "Bot Token"
9976
+ * WidgetCard.Header - Header section with controls
9977
+ * Only renders in edit mode (preview === false)
9478
9978
  */
9479
- function formatFieldName(name) {
9480
- var acronyms = {
9481
- url: "URL",
9482
- api: "API",
9483
- id: "ID",
9484
- mcp: "MCP"
9485
- };
9486
- return name.replace(/([A-Z])/g, " $1").replace(/^./, function (s) {
9487
- return s.toUpperCase();
9488
- }).trim().split(" ").map(function (word) {
9489
- return acronyms[word.toLowerCase()] || word;
9490
- }).join(" ");
9491
- }
9979
+ var WidgetCardHeader_Component = function WidgetCardHeader_Component(_ref) {
9980
+ var item = _ref.item,
9981
+ _ref$cellNumber = _ref.cellNumber,
9982
+ cellNumber = _ref$cellNumber === void 0 ? null : _ref$cellNumber,
9983
+ _ref$providers = _ref.providers,
9984
+ providers = _ref$providers === void 0 ? [] : _ref$providers,
9985
+ _ref$selectedProvider = _ref.selectedProviders,
9986
+ selectedProviders = _ref$selectedProvider === void 0 ? {} : _ref$selectedProvider,
9987
+ onProviderChange = _ref.onProviderChange,
9988
+ onConfigure = _ref.onConfigure,
9989
+ onDelete = _ref.onDelete,
9990
+ _ref$onSplitHorizonta = _ref.onSplitHorizontal,
9991
+ onSplitHorizontal = _ref$onSplitHorizonta === void 0 ? null : _ref$onSplitHorizonta,
9992
+ _ref$onSplitVertical = _ref.onSplitVertical,
9993
+ onSplitVertical = _ref$onSplitVertical === void 0 ? null : _ref$onSplitVertical,
9994
+ _ref$isSelected = _ref.isSelected,
9995
+ isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
9996
+ _ref$isSelectable = _ref.isSelectable,
9997
+ isSelectable = _ref$isSelectable === void 0 ? true : _ref$isSelectable,
9998
+ _ref$onToggleSelect = _ref.onToggleSelect,
9999
+ onToggleSelect = _ref$onToggleSelect === void 0 ? null : _ref$onToggleSelect;
10000
+ var _React$useContext = React__default.useContext(WidgetCardContext),
10001
+ preview = _React$useContext.preview;
9492
10002
 
9493
- /**
9494
- * Heuristic: does this field name likely contain a secret value?
9495
- */
9496
- function isLikelySecret(name) {
9497
- var lower = name.toLowerCase();
9498
- return /key|token|secret|password|credential|auth/.test(lower);
9499
- }
10003
+ // Don't render header in preview mode
10004
+ if (preview === true) {
10005
+ return null;
10006
+ }
10007
+ return /*#__PURE__*/jsx(WidgetCardHeader, {
10008
+ item: item,
10009
+ cellNumber: cellNumber,
10010
+ providers: providers,
10011
+ selectedProviders: selectedProviders,
10012
+ onProviderChange: onProviderChange,
10013
+ onConfigure: onConfigure,
10014
+ onDelete: onDelete,
10015
+ onSplitHorizontal: onSplitHorizontal,
10016
+ onSplitVertical: onSplitVertical,
10017
+ isSelected: isSelected,
10018
+ isSelectable: isSelectable,
10019
+ onToggleSelect: onToggleSelect
10020
+ });
10021
+ };
9500
10022
 
9501
10023
  /**
9502
- * Build an mcpConfig by overlaying advanced-section rows onto a catalog base config.
9503
- *
9504
- * For stdio: replaces `envMapping` with the rows from the advanced section.
9505
- * For streamable_http: replaces `headerTemplate` with the rows from the advanced section.
9506
- *
9507
- * @param {object} baseMcpConfig - The catalog's original mcpConfig
9508
- * @param {Array<{ envVar: string, credField: string }>} envMappingRows - Current env var rows
9509
- * @param {Array<{ headerName: string, headerValue: string }>} headerRows - Current header rows
9510
- * @returns {object} A new mcpConfig with overridden envMapping or headerTemplate
10024
+ * WidgetCard.Body - Body section with widget content
10025
+ * In edit mode: adds padding around content
10026
+ * In preview mode: renders content without padding
9511
10027
  */
9512
- function buildMcpConfigFromOverrides(baseMcpConfig, envMappingRows, headerRows) {
9513
- if (baseMcpConfig.transport === "streamable_http") {
9514
- var headerTemplate = {};
9515
- headerRows.forEach(function (row) {
9516
- var name = row.headerName.trim();
9517
- var value = row.headerValue.trim();
9518
- if (name && value) {
9519
- headerTemplate[name] = value;
9520
- }
10028
+ var WidgetCardBody = function WidgetCardBody(_ref2) {
10029
+ var children = _ref2.children,
10030
+ _ref2$padding = _ref2.padding,
10031
+ padding = _ref2$padding === void 0 ? "p-2" : _ref2$padding,
10032
+ _ref2$className = _ref2.className,
10033
+ className = _ref2$className === void 0 ? "" : _ref2$className;
10034
+ var _React$useContext2 = React__default.useContext(WidgetCardContext),
10035
+ preview = _React$useContext2.preview;
10036
+
10037
+ // In preview mode, render children without padding wrapper
10038
+ if (preview === true) {
10039
+ return /*#__PURE__*/jsx(Fragment, {
10040
+ children: children
9521
10041
  });
9522
- var config = _objectSpread$q({}, baseMcpConfig);
9523
- if (Object.keys(headerTemplate).length > 0) {
9524
- config.headerTemplate = headerTemplate;
9525
- } else {
9526
- delete config.headerTemplate;
9527
- }
9528
- return config;
9529
10042
  }
9530
10043
 
9531
- // stdio
9532
- var envMapping = {};
9533
- envMappingRows.forEach(function (row) {
9534
- var env = row.envVar.trim();
9535
- var cred = row.credField.trim();
9536
- if (env && cred) {
9537
- envMapping[env] = cred;
9538
- }
9539
- });
9540
- return _objectSpread$q(_objectSpread$q({}, baseMcpConfig), {}, {
9541
- envMapping: envMapping
9542
- });
9543
- }
9544
-
9545
- /**
9546
- * Convert an envMapping object into row state for the advanced config UI.
9547
- *
9548
- * @param {object} envMapping - e.g. { SLACK_BOT_TOKEN: "botToken" }
9549
- * @param {Function} nextRowId - Function that returns a unique row ID
9550
- * @returns {Array<{ id: string, envVar: string, credField: string }>}
9551
- */
9552
- function envMappingToRows(envMapping, nextRowId) {
9553
- if (!envMapping) return [];
9554
- return Object.entries(envMapping).map(function (_ref) {
9555
- var _ref2 = _slicedToArray(_ref, 2),
9556
- envVar = _ref2[0],
9557
- credField = _ref2[1];
9558
- return {
9559
- id: nextRowId(),
9560
- envVar: envVar,
9561
- credField: credField
9562
- };
10044
+ // In edit mode, render with padding
10045
+ return /*#__PURE__*/jsx("div", {
10046
+ className: "flex-1 min-h-0 overflow-auto ".concat(padding, " ").concat(className),
10047
+ children: children
9563
10048
  });
9564
- }
10049
+ };
9565
10050
 
9566
10051
  /**
9567
- * Convert a headerTemplate object into row state for the advanced config UI.
9568
- *
9569
- * @param {object} headerTemplate - e.g. { "Authorization": "Bearer {{apiKey}}" }
9570
- * @param {Function} nextRowId - Function that returns a unique row ID
9571
- * @returns {Array<{ id: string, headerName: string, headerValue: string }>}
10052
+ * WidgetCard.Footer - Footer section with handler warnings
10053
+ * Only renders in edit mode (preview === false)
10054
+ * Shows amber warning when widget has eventHandlers that lack listener connections
9572
10055
  */
9573
- function headerTemplateToRows(headerTemplate, nextRowId) {
9574
- if (!headerTemplate) return [];
9575
- return Object.entries(headerTemplate).map(function (_ref3) {
9576
- var _ref4 = _slicedToArray(_ref3, 2),
9577
- headerName = _ref4[0],
9578
- headerValue = _ref4[1];
9579
- return {
9580
- id: nextRowId(),
9581
- headerName: headerName,
9582
- headerValue: headerValue
9583
- };
10056
+ var WidgetCardFooter = function WidgetCardFooter(_ref3) {
10057
+ var children = _ref3.children,
10058
+ _ref3$item = _ref3.item,
10059
+ item = _ref3$item === void 0 ? null : _ref3$item,
10060
+ _ref3$onConfigure = _ref3.onConfigure,
10061
+ onConfigure = _ref3$onConfigure === void 0 ? null : _ref3$onConfigure,
10062
+ _ref3$className = _ref3.className,
10063
+ className = _ref3$className === void 0 ? "" : _ref3$className;
10064
+ var _React$useContext3 = React__default.useContext(WidgetCardContext),
10065
+ preview = _React$useContext3.preview;
10066
+ if (preview === true) return null;
10067
+
10068
+ // Compute unconfigured handlers
10069
+ var widgetConfig = item !== null && item !== void 0 && item.component ? ComponentManager.config(item.component, item) : null;
10070
+ var eventHandlers = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.eventHandlers) || [];
10071
+ var listeners = (item === null || item === void 0 ? void 0 : item.listeners) || {};
10072
+ var unconfiguredCount = eventHandlers.filter(function (h) {
10073
+ return !listeners[h] || listeners[h].length === 0;
10074
+ }).length;
10075
+
10076
+ // Don't render if no children AND no warnings
10077
+ if (!children && unconfiguredCount === 0) return null;
10078
+ return /*#__PURE__*/jsxs("div", {
10079
+ className: "border-t border-gray-700 px-3 py-1.5 bg-transparent ".concat(className),
10080
+ children: [children, unconfiguredCount > 0 && /*#__PURE__*/jsxs("button", {
10081
+ type: "button",
10082
+ onClick: function onClick() {
10083
+ return onConfigure && onConfigure(item, "handlers");
10084
+ },
10085
+ 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",
10086
+ title: "Click to configure listeners",
10087
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
10088
+ icon: "phone",
10089
+ className: "text-[10px]"
10090
+ }), /*#__PURE__*/jsxs("span", {
10091
+ children: [unconfiguredCount, " listener", unconfiguredCount > 1 ? "s" : "", " not connected"]
10092
+ })]
10093
+ })]
9584
10094
  });
9585
- }
10095
+ };
9586
10096
 
9587
10097
  /**
9588
- * Serialize the current form state into a bare MCP JSON config string.
9589
- *
9590
- * Output format (stdio):
9591
- * {
9592
- * "type": "stdio",
9593
- * "command": "npx",
9594
- * "args": ["-y", "package-name"],
9595
- * "env": { "API_KEY": "${API_KEY}" }
9596
- * }
9597
- *
9598
- * Output format (HTTP):
9599
- * {
9600
- * "type": "streamable_http",
9601
- * "url": "https://example.com/mcp",
9602
- * "headerTemplate": { "Authorization": "Bearer {{apiKey}}" }
9603
- * }
9604
- *
9605
- * Credential values are NOT embedded — env values use ${FIELD_NAME} syntax
9606
- * to reference credential fields entered separately in the form.
10098
+ * WidgetCard - Main wrapper component
9607
10099
  *
9608
- * @param {string} name - The provider name (unused in output, kept for API compat)
9609
- * @param {string} transport - "stdio" or "streamable_http"
9610
- * @param {object} fields - { command, args, envMappingRows, url, headerRows }
9611
- * @returns {string} Formatted JSON string
10100
+ * In preview mode: renders children without any wrapper
10101
+ * In edit mode: wraps children in a container
9612
10102
  */
9613
- function formStateToMcpJson(name, transport, fields) {
9614
- var _fields$command = fields.command,
9615
- command = _fields$command === void 0 ? "" : _fields$command,
9616
- _fields$args = fields.args,
9617
- args = _fields$args === void 0 ? "" : _fields$args,
9618
- _fields$envMappingRow = fields.envMappingRows,
9619
- envMappingRows = _fields$envMappingRow === void 0 ? [] : _fields$envMappingRow,
9620
- _fields$url = fields.url,
9621
- url = _fields$url === void 0 ? "" : _fields$url,
9622
- _fields$headerRows = fields.headerRows,
9623
- headerRows = _fields$headerRows === void 0 ? [] : _fields$headerRows;
9624
- var serverConfig;
9625
- if (transport === "stdio") {
9626
- var argsArray = args.trim().split(/\s+/).filter(Boolean);
9627
- var env = {};
9628
- envMappingRows.forEach(function (row) {
9629
- var envVar = row.envVar.trim();
9630
- var credField = row.credField.trim();
9631
- if (envVar && credField) {
9632
- env[envVar] = "${".concat(credField, "}");
9633
- }
9634
- });
9635
- serverConfig = {
9636
- type: "stdio",
9637
- command: command.trim()
9638
- };
9639
- if (argsArray.length > 0) serverConfig.args = argsArray;
9640
- if (Object.keys(env).length > 0) serverConfig.env = env;
9641
- } else {
9642
- // streamable_http
9643
- serverConfig = {
9644
- type: "streamable_http",
9645
- url: url.trim()
9646
- };
9647
- var headerTemplate = {};
9648
- headerRows.forEach(function (row) {
9649
- var hName = row.headerName.trim();
9650
- var hValue = row.headerValue.trim();
9651
- if (hName && hValue) {
9652
- headerTemplate[hName] = hValue;
9653
- }
10103
+ var WidgetCard = function WidgetCard(_ref4) {
10104
+ var _ref4$preview = _ref4.preview,
10105
+ preview = _ref4$preview === void 0 ? false : _ref4$preview,
10106
+ children = _ref4.children,
10107
+ _ref4$className = _ref4.className,
10108
+ className = _ref4$className === void 0 ? "" : _ref4$className;
10109
+ // In preview mode, render children without wrapper
10110
+ if (preview === true) {
10111
+ return /*#__PURE__*/jsx(WidgetCardContext.Provider, {
10112
+ value: {
10113
+ preview: preview
10114
+ },
10115
+ children: children
9654
10116
  });
9655
- if (Object.keys(headerTemplate).length > 0) serverConfig.headerTemplate = headerTemplate;
9656
10117
  }
9657
- return JSON.stringify(serverConfig, null, 2);
9658
- }
9659
10118
 
9660
- /**
9661
- * Parse an MCP JSON config string back into form state.
9662
- *
9663
- * Accepts multiple input formats:
9664
- * - Bare config: { "command": ..., "args": [...], "env": { "KEY": "${FIELD}" } }
9665
- * - Wrapped: { "mcpServers": { "name": { ... } } } — unwraps and uses key as providerName
9666
- *
9667
- * Transport detection:
9668
- * - Explicit `type` or `transport` field
9669
- * - Inferred: `url` present → streamable_http, `command` present → stdio
9670
- *
9671
- * stdio env value parsing:
9672
- * - "${FIELD_NAME}" → envVar = key, credField = FIELD_NAME (reference syntax)
9673
- * - "literal-value" → envVar = key, credField = key, credentialData[key] = value
9674
- *
9675
- * @param {string} jsonString - The JSON to parse
9676
- * @param {Function} nextRowId - Function that returns a unique row ID
9677
- * @returns {{ providerName, transport, command, args, envMappingRows, url, headerRows, credentialData, error }}
9678
- */
9679
- function mcpJsonToFormState(jsonString, nextRowId) {
9680
- var parsed;
9681
- try {
9682
- parsed = JSON.parse(jsonString);
9683
- } catch (e) {
9684
- return {
9685
- error: "Invalid JSON: ".concat(e.message)
9686
- };
9687
- }
9688
- var providerName = "";
9689
- var serverConfig;
9690
- if (parsed.mcpServers && _typeof(parsed.mcpServers) === "object") {
9691
- var entries = Object.entries(parsed.mcpServers);
9692
- if (entries.length === 0) {
9693
- return {
9694
- error: "No server found in mcpServers"
9695
- };
9696
- }
9697
- var _entries$ = _slicedToArray(entries[0], 2);
9698
- providerName = _entries$[0];
9699
- serverConfig = _entries$[1];
9700
- } else if (parsed.command || parsed.url || parsed.type || parsed.transport) {
9701
- serverConfig = parsed;
9702
- } else {
9703
- return {
9704
- error: "Unrecognized format: expected a server config with command, url, or type"
9705
- };
9706
- }
10119
+ // In edit mode, render with wrapper (no padding - Body handles padding)
10120
+ return /*#__PURE__*/jsx(WidgetCardContext.Provider, {
10121
+ value: {
10122
+ preview: preview
10123
+ },
10124
+ children: /*#__PURE__*/jsx("div", {
10125
+ className: "flex flex-col w-full h-full min-h-0 overflow-hidden rounded border border-dashed border-gray-700 ".concat(className),
10126
+ children: children
10127
+ })
10128
+ });
10129
+ };
9707
10130
 
9708
- // Determine transport from type/transport field or infer from contents
9709
- var explicitType = serverConfig.type || serverConfig.transport;
9710
- var transport;
9711
- if (explicitType) {
9712
- transport = explicitType === "stdio" ? "stdio" : "streamable_http";
9713
- } else {
9714
- transport = serverConfig.url ? "streamable_http" : "stdio";
9715
- }
9716
- var result = {
9717
- providerName: providerName,
9718
- transport: transport,
9719
- command: "",
9720
- args: "",
9721
- envMappingRows: [],
9722
- url: "",
9723
- headerRows: [],
9724
- credentialData: {},
9725
- error: null
10131
+ // Attach subcomponents
10132
+ WidgetCard.Header = WidgetCardHeader_Component;
10133
+ WidgetCard.Body = WidgetCardBody;
10134
+ WidgetCard.Footer = WidgetCardFooter;
10135
+
10136
+ var ProviderSelector = function ProviderSelector(_ref) {
10137
+ var isOpen = _ref.isOpen,
10138
+ setIsOpen = _ref.setIsOpen,
10139
+ providerType = _ref.providerType,
10140
+ _ref$existingProvider = _ref.existingProviders,
10141
+ existingProviders = _ref$existingProvider === void 0 ? [] : _ref$existingProvider,
10142
+ _ref$credentialSchema = _ref.credentialSchema,
10143
+ credentialSchema = _ref$credentialSchema === void 0 ? {} : _ref$credentialSchema,
10144
+ onSelect = _ref.onSelect,
10145
+ onCreate = _ref.onCreate;
10146
+ var _useState = useState("select"),
10147
+ _useState2 = _slicedToArray(_useState, 2),
10148
+ activeTab = _useState2[0],
10149
+ setActiveTab = _useState2[1]; // "select" or "create"
10150
+
10151
+ /**
10152
+ * Filter providers by type
10153
+ */
10154
+ var filteredProviders = existingProviders.filter(function (p) {
10155
+ return p.type === providerType;
10156
+ });
10157
+
10158
+ /**
10159
+ * Handle provider selection
10160
+ */
10161
+ var handleSelectProvider = function handleSelectProvider(providerName) {
10162
+ onSelect(providerName);
10163
+ setIsOpen(false);
9726
10164
  };
9727
- if (transport === "stdio") {
9728
- result.command = serverConfig.command || "";
9729
- result.args = (serverConfig.args || []).join(" ");
9730
- if (serverConfig.env && _typeof(serverConfig.env) === "object") {
9731
- Object.entries(serverConfig.env).forEach(function (_ref5) {
9732
- var _ref6 = _slicedToArray(_ref5, 2),
9733
- envVar = _ref6[0],
9734
- value = _ref6[1];
9735
- // Check for ${FIELD_NAME} reference syntax
9736
- var refMatch = typeof value === "string" && value.match(/^\$\{(.+)\}$/);
9737
- if (refMatch) {
9738
- // Reference syntax — credField is the extracted name, no credential value
9739
- result.envMappingRows.push({
9740
- id: nextRowId(),
9741
- envVar: envVar,
9742
- credField: refMatch[1]
9743
- });
9744
- } else {
9745
- // Literal value — use envVar as credField and store the value
9746
- result.envMappingRows.push({
9747
- id: nextRowId(),
9748
- envVar: envVar,
9749
- credField: envVar
9750
- });
9751
- result.credentialData[envVar] = value || "";
9752
- }
9753
- });
9754
- }
9755
- } else {
9756
- result.url = serverConfig.url || "";
9757
- var headers = serverConfig.headers || serverConfig.headerTemplate || {};
9758
- if (_typeof(headers) === "object") {
9759
- Object.entries(headers).forEach(function (_ref7) {
9760
- var _ref8 = _slicedToArray(_ref7, 2),
9761
- headerName = _ref8[0],
9762
- headerValue = _ref8[1];
9763
- result.headerRows.push({
9764
- id: nextRowId(),
9765
- headerName: headerName,
9766
- headerValue: headerValue
9767
- });
9768
- });
9769
- }
9770
- }
9771
- return result;
9772
- }
10165
+
10166
+ /**
10167
+ * Handle new provider creation
10168
+ */
10169
+ var handleCreateProvider = function handleCreateProvider(formData) {
10170
+ // formData now contains { name, credentials }
10171
+ var providerName = formData.name,
10172
+ credentials = formData.credentials;
10173
+ onCreate(providerName, credentials);
10174
+ setIsOpen(false);
10175
+ };
10176
+ return /*#__PURE__*/jsx(Modal, {
10177
+ isOpen: isOpen,
10178
+ setIsOpen: setIsOpen,
10179
+ width: "w-11/12 xl:w-5/6",
10180
+ height: "h-5/6",
10181
+ children: /*#__PURE__*/jsxs(Panel, {
10182
+ border: true,
10183
+ padding: false,
10184
+ backgroundColor: "bg-gray-800",
10185
+ borderColor: "border-gray-700",
10186
+ children: [/*#__PURE__*/jsx(Panel.Header, {
10187
+ border: true,
10188
+ borderColor: "border-gray-700",
10189
+ children: /*#__PURE__*/jsxs("div", {
10190
+ className: "flex flex-col w-full space-y-4",
10191
+ children: [/*#__PURE__*/jsxs("div", {
10192
+ className: "flex flex-row justify-between items-start",
10193
+ children: [/*#__PURE__*/jsxs("div", {
10194
+ className: "flex-1",
10195
+ children: [/*#__PURE__*/jsx("h2", {
10196
+ className: "text-2xl font-bold text-gray-100",
10197
+ children: providerType ? /*#__PURE__*/jsxs(Fragment, {
10198
+ children: ["Manage ", /*#__PURE__*/jsx("span", {
10199
+ className: "capitalize",
10200
+ children: providerType
10201
+ }), " ", "Providers"]
10202
+ }) : "Select Provider"
10203
+ }), /*#__PURE__*/jsx("p", {
10204
+ className: "text-sm text-gray-400 mt-1",
10205
+ children: activeTab === "select" ? "Select an existing ".concat(providerType, " provider or create a new one") : "Create a new ".concat(providerType, " provider")
10206
+ })]
10207
+ }), /*#__PURE__*/jsx("button", {
10208
+ onClick: function onClick() {
10209
+ return setIsOpen(false);
10210
+ },
10211
+ className: "ml-4 text-gray-400 hover:text-gray-200 transition-colors",
10212
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
10213
+ icon: "times",
10214
+ className: "text-xl"
10215
+ })
10216
+ })]
10217
+ }), /*#__PURE__*/jsxs("div", {
10218
+ className: "flex gap-2",
10219
+ children: [/*#__PURE__*/jsx(Button, {
10220
+ title: "Select Existing (".concat(filteredProviders.length, ")"),
10221
+ onClick: function onClick() {
10222
+ return setActiveTab("select");
10223
+ },
10224
+ backgroundColor: activeTab === "select" ? "bg-blue-600" : "bg-gray-700",
10225
+ hoverBackgroundColor: activeTab === "select" ? "hover:bg-blue-700" : "hover:bg-gray-600",
10226
+ padding: "px-4 py-2",
10227
+ textSize: "text-sm"
10228
+ }), /*#__PURE__*/jsx(Button, {
10229
+ title: "Create New",
10230
+ onClick: function onClick() {
10231
+ return setActiveTab("create");
10232
+ },
10233
+ backgroundColor: activeTab === "create" ? "bg-blue-600" : "bg-gray-700",
10234
+ hoverBackgroundColor: activeTab === "create" ? "hover:bg-blue-700" : "hover:bg-gray-600",
10235
+ padding: "px-4 py-2",
10236
+ textSize: "text-sm"
10237
+ })]
10238
+ })]
10239
+ })
10240
+ }), /*#__PURE__*/jsx(Panel.Body, {
10241
+ children: /*#__PURE__*/jsx("div", {
10242
+ className: "h-full overflow-y-auto",
10243
+ children: activeTab === "select" ?
10244
+ /*#__PURE__*/
10245
+ // Select Tab
10246
+ jsx("div", {
10247
+ className: "p-6",
10248
+ children: filteredProviders.length > 0 ? /*#__PURE__*/jsx("div", {
10249
+ className: "space-y-3",
10250
+ children: filteredProviders.map(function (provider) {
10251
+ return /*#__PURE__*/jsxs("button", {
10252
+ onClick: function onClick() {
10253
+ return handleSelectProvider(provider.name);
10254
+ },
10255
+ 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",
10256
+ children: [/*#__PURE__*/jsx("div", {
10257
+ className: "font-semibold",
10258
+ children: provider.name
10259
+ }), /*#__PURE__*/jsxs("div", {
10260
+ className: "text-sm opacity-70 mt-1",
10261
+ children: ["Type:", " ", /*#__PURE__*/jsx("span", {
10262
+ className: "capitalize",
10263
+ children: provider.type
10264
+ })]
10265
+ }), provider.credentials && Object.keys(provider.credentials).length > 0 && /*#__PURE__*/jsxs("div", {
10266
+ className: "text-xs opacity-50 mt-2",
10267
+ children: ["Fields:", " ", Object.keys(provider.credentials).join(", ")]
10268
+ })]
10269
+ }, provider.name);
10270
+ })
10271
+ }) : /*#__PURE__*/jsxs("div", {
10272
+ className: "text-center py-12",
10273
+ children: [/*#__PURE__*/jsxs(SubHeading3, {
10274
+ className: "opacity-50",
10275
+ children: ["No ", providerType, " providers found"]
10276
+ }), /*#__PURE__*/jsx(Paragraph, {
10277
+ className: "mt-2 opacity-70",
10278
+ children: "Create one using the \"Create New\" tab"
10279
+ })]
10280
+ })
10281
+ }) :
10282
+ /*#__PURE__*/
10283
+ // Create Tab
10284
+ jsx(ProviderForm, {
10285
+ credentialSchema: credentialSchema,
10286
+ onSubmit: handleCreateProvider,
10287
+ onCancel: function onCancel() {
10288
+ return setIsOpen(false);
10289
+ },
10290
+ submitLabel: "Create Provider",
10291
+ providerType: providerType
10292
+ })
10293
+ })
10294
+ })]
10295
+ })
10296
+ });
10297
+ };
9773
10298
 
9774
10299
  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; }
9775
10300
  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; }
@@ -25954,82 +26479,6 @@ var FoldersSection = function FoldersSection(_ref) {
25954
26479
  });
25955
26480
  };
25956
26481
 
25957
- var ToolSelector = function ToolSelector(_ref) {
25958
- var _ref$tools = _ref.tools,
25959
- tools = _ref$tools === void 0 ? [] : _ref$tools,
25960
- _ref$selectedTools = _ref.selectedTools,
25961
- selectedTools = _ref$selectedTools === void 0 ? [] : _ref$selectedTools,
25962
- onSelectionChange = _ref.onSelectionChange;
25963
- if (!tools || tools.length === 0) return null;
25964
- var allSelected = selectedTools.length === tools.length;
25965
- var handleToggleAll = function handleToggleAll() {
25966
- if (allSelected) {
25967
- onSelectionChange([]);
25968
- } else {
25969
- onSelectionChange(tools.map(function (t) {
25970
- return t.name;
25971
- }));
25972
- }
25973
- };
25974
- var handleToggle = function handleToggle(toolName) {
25975
- if (selectedTools.includes(toolName)) {
25976
- onSelectionChange(selectedTools.filter(function (t) {
25977
- return t !== toolName;
25978
- }));
25979
- } else {
25980
- onSelectionChange([].concat(_toConsumableArray(selectedTools), [toolName]));
25981
- }
25982
- };
25983
- return /*#__PURE__*/jsxs("div", {
25984
- className: "space-y-2 flex-1 flex flex-col min-h-0",
25985
- children: [/*#__PURE__*/jsxs("div", {
25986
- className: "flex items-center justify-between",
25987
- children: [/*#__PURE__*/jsx("p", {
25988
- className: "text-xs font-semibold opacity-40 uppercase tracking-wider",
25989
- children: "Allowed Tools"
25990
- }), /*#__PURE__*/jsx("button", {
25991
- onClick: handleToggleAll,
25992
- className: "text-xs text-blue-400 hover:text-blue-300 transition-colors",
25993
- children: allSelected ? "Deselect All" : "Select All"
25994
- })]
25995
- }), /*#__PURE__*/jsx("p", {
25996
- className: "text-sm opacity-50",
25997
- children: "Choose which tools this provider can expose to widgets"
25998
- }), /*#__PURE__*/jsx("div", {
25999
- className: "space-y-1 flex-1 min-h-0 overflow-y-auto",
26000
- children: tools.map(function (tool) {
26001
- var checked = selectedTools.includes(tool.name);
26002
- return /*#__PURE__*/jsxs("label", {
26003
- className: "flex items-start gap-2 p-1.5 rounded hover:bg-white/5 cursor-pointer",
26004
- children: [/*#__PURE__*/jsx("input", {
26005
- type: "checkbox",
26006
- checked: checked,
26007
- onChange: function onChange() {
26008
- return handleToggle(tool.name);
26009
- },
26010
- className: "mt-0.5 rounded border-white/20 bg-white/5 text-blue-500 focus:ring-blue-500/30"
26011
- }), /*#__PURE__*/jsxs("div", {
26012
- className: "flex-1 min-w-0",
26013
- children: [/*#__PURE__*/jsx("span", {
26014
- className: "text-xs font-mono",
26015
- children: tool.name
26016
- }), tool.description && /*#__PURE__*/jsxs("span", {
26017
- className: "text-xs opacity-50 ml-2",
26018
- children: ["\u2014 ", tool.description]
26019
- })]
26020
- })]
26021
- }, tool.name);
26022
- })
26023
- }), /*#__PURE__*/jsxs("p", {
26024
- className: "text-xs opacity-40",
26025
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26026
- icon: "shield-halved",
26027
- className: "mr-1"
26028
- }), selectedTools.length, " of ", tools.length, " tools selected"]
26029
- })]
26030
- });
26031
- };
26032
-
26033
26482
  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; }
26034
26483
  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; }
26035
26484
  var ProviderDetail = function ProviderDetail(_ref) {
@@ -26058,7 +26507,9 @@ var ProviderDetail = function ProviderDetail(_ref) {
26058
26507
  onDelete = _ref.onDelete,
26059
26508
  onSaveAllowedTools = _ref.onSaveAllowedTools,
26060
26509
  _ref$catalogAuthComma = _ref.catalogAuthCommand,
26061
- catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma;
26510
+ catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma,
26511
+ _ref$catalogCredentia = _ref.catalogCredentialSchema,
26512
+ catalogCredentialSchema = _ref$catalogCredentia === void 0 ? {} : _ref$catalogCredentia;
26062
26513
  var appContext = useContext(AppContext);
26063
26514
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
26064
26515
  var isMcp = (provider === null || provider === void 0 ? void 0 : provider.providerClass) === "mcp";
@@ -26093,8 +26544,8 @@ var ProviderDetail = function ProviderDetail(_ref) {
26093
26544
  // Derive credential fields for MCP providers in edit mode
26094
26545
  var mcpFormFields = useMemo(function () {
26095
26546
  if (!isMcp || !(provider !== null && provider !== void 0 && provider.mcpConfig)) return [];
26096
- return deriveFormFields(provider.mcpConfig, {});
26097
- }, [isMcp, provider]);
26547
+ return deriveFormFields(provider.mcpConfig, catalogCredentialSchema);
26548
+ }, [isMcp, provider, catalogCredentialSchema]);
26098
26549
 
26099
26550
  // Credential field keys for non-MCP providers
26100
26551
  var credentialKeys = useMemo(function () {
@@ -28720,7 +29171,8 @@ var ProvidersSection = function ProvidersSection(_ref) {
28720
29171
  return setDeleteTarget(name);
28721
29172
  },
28722
29173
  onSaveAllowedTools: handleSaveAllowedTools,
28723
- catalogAuthCommand: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.authCommand) || null
29174
+ catalogAuthCommand: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.authCommand) || null,
29175
+ catalogCredentialSchema: (catalogEntry === null || catalogEntry === void 0 ? void 0 : catalogEntry.credentialSchema) || {}
28724
29176
  });
28725
29177
  }
28726
29178
  return /*#__PURE__*/jsxs(Fragment, {