@trops/dash-core 0.1.489 → 0.1.491
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/electron/index.js +835 -357
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +325 -42
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +325 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1644,9 +1644,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1644
1644
|
key: "mcpStartServer",
|
|
1645
1645
|
value: function mcpStartServer(serverName, mcpConfig, credentials, onSuccess, onError) {
|
|
1646
1646
|
var _this20 = this;
|
|
1647
|
+
var workspaceId = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
|
|
1647
1648
|
if (this.api !== null) {
|
|
1648
1649
|
try {
|
|
1649
|
-
this.api.mcp.startServer(serverName, mcpConfig, credentials).then(function (result) {
|
|
1650
|
+
this.api.mcp.startServer(serverName, mcpConfig, credentials, workspaceId).then(function (result) {
|
|
1650
1651
|
onSuccess(_this20.events.MCP_START_SERVER_COMPLETE, result);
|
|
1651
1652
|
})["catch"](function (error) {
|
|
1652
1653
|
onError(_this20.events.MCP_START_SERVER_ERROR, error);
|
|
@@ -1665,9 +1666,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1665
1666
|
key: "mcpStopServer",
|
|
1666
1667
|
value: function mcpStopServer(serverName, onSuccess, onError) {
|
|
1667
1668
|
var _this21 = this;
|
|
1669
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1668
1670
|
if (this.api !== null) {
|
|
1669
1671
|
try {
|
|
1670
|
-
this.api.mcp.stopServer(serverName).then(function (result) {
|
|
1672
|
+
this.api.mcp.stopServer(serverName, workspaceId).then(function (result) {
|
|
1671
1673
|
onSuccess(_this21.events.MCP_STOP_SERVER_COMPLETE, result);
|
|
1672
1674
|
})["catch"](function (error) {
|
|
1673
1675
|
onError(_this21.events.MCP_STOP_SERVER_ERROR, error);
|
|
@@ -1686,9 +1688,13 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1686
1688
|
key: "mcpCallTool",
|
|
1687
1689
|
value: function mcpCallTool(serverName, toolName, args, allowedTools, onSuccess, onError) {
|
|
1688
1690
|
var _this22 = this;
|
|
1691
|
+
var workspaceId = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
|
|
1689
1692
|
if (this.api !== null) {
|
|
1690
1693
|
try {
|
|
1691
|
-
|
|
1694
|
+
// widgetId is not threaded here; mcpApi.callTool defaults it to
|
|
1695
|
+
// null. Slice 3a: workspaceId scopes the MCP server process per
|
|
1696
|
+
// workspace.
|
|
1697
|
+
this.api.mcp.callTool(serverName, toolName, args, allowedTools, null, workspaceId).then(function (result) {
|
|
1692
1698
|
onSuccess(_this22.events.MCP_CALL_TOOL_COMPLETE, result);
|
|
1693
1699
|
})["catch"](function (error) {
|
|
1694
1700
|
onError(_this22.events.MCP_CALL_TOOL_ERROR, error);
|
|
@@ -1707,9 +1713,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1707
1713
|
key: "mcpListTools",
|
|
1708
1714
|
value: function mcpListTools(serverName, onSuccess, onError) {
|
|
1709
1715
|
var _this23 = this;
|
|
1716
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1710
1717
|
if (this.api !== null) {
|
|
1711
1718
|
try {
|
|
1712
|
-
this.api.mcp.listTools(serverName).then(function (result) {
|
|
1719
|
+
this.api.mcp.listTools(serverName, workspaceId).then(function (result) {
|
|
1713
1720
|
onSuccess(_this23.events.MCP_LIST_TOOLS_COMPLETE, result);
|
|
1714
1721
|
})["catch"](function (error) {
|
|
1715
1722
|
onError(_this23.events.MCP_LIST_TOOLS_ERROR, error);
|
|
@@ -1728,9 +1735,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1728
1735
|
key: "mcpListResources",
|
|
1729
1736
|
value: function mcpListResources(serverName, onSuccess, onError) {
|
|
1730
1737
|
var _this24 = this;
|
|
1738
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1731
1739
|
if (this.api !== null) {
|
|
1732
1740
|
try {
|
|
1733
|
-
this.api.mcp.listResources(serverName).then(function (result) {
|
|
1741
|
+
this.api.mcp.listResources(serverName, workspaceId).then(function (result) {
|
|
1734
1742
|
onSuccess(_this24.events.MCP_LIST_RESOURCES_COMPLETE, result);
|
|
1735
1743
|
})["catch"](function (error) {
|
|
1736
1744
|
onError(_this24.events.MCP_LIST_RESOURCES_ERROR, error);
|
|
@@ -1749,9 +1757,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1749
1757
|
key: "mcpReadResource",
|
|
1750
1758
|
value: function mcpReadResource(serverName, uri, onSuccess, onError) {
|
|
1751
1759
|
var _this25 = this;
|
|
1760
|
+
var workspaceId = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
1752
1761
|
if (this.api !== null) {
|
|
1753
1762
|
try {
|
|
1754
|
-
this.api.mcp.readResource(serverName, uri).then(function (result) {
|
|
1763
|
+
this.api.mcp.readResource(serverName, uri, workspaceId).then(function (result) {
|
|
1755
1764
|
onSuccess(_this25.events.MCP_READ_RESOURCE_COMPLETE, result);
|
|
1756
1765
|
})["catch"](function (error) {
|
|
1757
1766
|
onError(_this25.events.MCP_READ_RESOURCE_ERROR, error);
|
|
@@ -1770,9 +1779,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1770
1779
|
key: "mcpGetServerStatus",
|
|
1771
1780
|
value: function mcpGetServerStatus(serverName, onSuccess, onError) {
|
|
1772
1781
|
var _this26 = this;
|
|
1782
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1773
1783
|
if (this.api !== null) {
|
|
1774
1784
|
try {
|
|
1775
|
-
this.api.mcp.getServerStatus(serverName).then(function (result) {
|
|
1785
|
+
this.api.mcp.getServerStatus(serverName, workspaceId).then(function (result) {
|
|
1776
1786
|
onSuccess(_this26.events.MCP_SERVER_STATUS_COMPLETE, result);
|
|
1777
1787
|
})["catch"](function (error) {
|
|
1778
1788
|
onError(_this26.events.MCP_SERVER_STATUS_ERROR, error);
|
|
@@ -29120,17 +29130,27 @@ var useWidgetProviders = function useWidgetProviders() {
|
|
|
29120
29130
|
|
|
29121
29131
|
/**
|
|
29122
29132
|
* Module-level shared state for MCP server connections.
|
|
29123
|
-
* Prevents multiple hook instances (e.g., 4 widgets
|
|
29124
|
-
* each firing their own IPC startServer call.
|
|
29133
|
+
* Prevents multiple hook instances (e.g., 4 widgets on the same dashboard
|
|
29134
|
+
* using "slack") from each firing their own IPC startServer call.
|
|
29125
29135
|
*
|
|
29126
|
-
*
|
|
29127
|
-
*
|
|
29136
|
+
* Slice 3a: keys are scoped per `(workspaceId, serverName)` so two
|
|
29137
|
+
* dashboards using the same provider name don't share renderer state
|
|
29138
|
+
* (the main process spawns separate server instances for each).
|
|
29139
|
+
*
|
|
29140
|
+
* serverStates: tracks connection result + consumer reference count
|
|
29141
|
+
* pendingConnects: deduplicates in-flight IPC calls
|
|
29128
29142
|
*/
|
|
29129
29143
|
var serverStates = new Map();
|
|
29130
|
-
// Map
|
|
29144
|
+
// Map<`${workspaceId}::${serverName}`, { status, tools, resources, consumerCount }>
|
|
29131
29145
|
|
|
29132
29146
|
var pendingConnects$1 = new Map();
|
|
29133
|
-
// Map
|
|
29147
|
+
// Map<`${workspaceId}::${serverName}`, Promise<result>>
|
|
29148
|
+
|
|
29149
|
+
var NO_WORKSPACE = "__no_workspace__";
|
|
29150
|
+
function rendererStateKey(workspaceId, serverName) {
|
|
29151
|
+
var wid = workspaceId && typeof workspaceId === "string" ? workspaceId : NO_WORKSPACE;
|
|
29152
|
+
return wid + "::" + serverName;
|
|
29153
|
+
}
|
|
29134
29154
|
|
|
29135
29155
|
/**
|
|
29136
29156
|
* useMcpProvider Hook
|
|
@@ -29299,7 +29319,8 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29299
29319
|
* even when multiple hook instances call connect() simultaneously.
|
|
29300
29320
|
*/
|
|
29301
29321
|
var connect = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
29302
|
-
var
|
|
29322
|
+
var _workspace$workspaceD2;
|
|
29323
|
+
var workspaceId, stateKey, cached, statusResult, result, state, connectPromise, _result, _t2, _t3;
|
|
29303
29324
|
return _regeneratorRuntime.wrap(function (_context) {
|
|
29304
29325
|
while (1) switch (_context.prev = _context.next) {
|
|
29305
29326
|
case 0:
|
|
@@ -29330,9 +29351,15 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29330
29351
|
setError("Provider \"".concat(selectedProviderName, "\" has no MCP configuration"));
|
|
29331
29352
|
return _context.abrupt("return");
|
|
29332
29353
|
case 4:
|
|
29333
|
-
//
|
|
29354
|
+
// Slice 3a: scope state per (workspace, provider). Two dashboards
|
|
29355
|
+
// using the same provider name get separate server instances in the
|
|
29356
|
+
// main process, so the renderer state must mirror that or one
|
|
29357
|
+
// dashboard's "connected" cache will short-circuit a second
|
|
29358
|
+
// dashboard's connect that needs its own backing process.
|
|
29359
|
+
workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD2 = workspace.workspaceData) === null || _workspace$workspaceD2 === void 0 ? void 0 : _workspace$workspaceD2.id) || null;
|
|
29360
|
+
stateKey = rendererStateKey(workspaceId, selectedProviderName); // 1. Already connected at module level? Verify with main process before trusting cache.
|
|
29334
29361
|
// The server may have been stopped externally (e.g., Test Connection in settings).
|
|
29335
|
-
cached = serverStates.get(
|
|
29362
|
+
cached = serverStates.get(stateKey);
|
|
29336
29363
|
if (!(cached && cached.status === "connected")) {
|
|
29337
29364
|
_context.next = 9;
|
|
29338
29365
|
break;
|
|
@@ -29344,7 +29371,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29344
29371
|
return resolve(result);
|
|
29345
29372
|
}, function (event, err) {
|
|
29346
29373
|
return reject(err);
|
|
29347
|
-
});
|
|
29374
|
+
}, workspaceId);
|
|
29348
29375
|
});
|
|
29349
29376
|
case 6:
|
|
29350
29377
|
statusResult = _context.sent;
|
|
@@ -29357,25 +29384,25 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29357
29384
|
return _context.abrupt("return");
|
|
29358
29385
|
case 7:
|
|
29359
29386
|
// Server was stopped externally — clear stale cache and reconnect
|
|
29360
|
-
serverStates["delete"](
|
|
29387
|
+
serverStates["delete"](stateKey);
|
|
29361
29388
|
_context.next = 9;
|
|
29362
29389
|
break;
|
|
29363
29390
|
case 8:
|
|
29364
29391
|
_context.prev = 8;
|
|
29365
29392
|
_context["catch"](5);
|
|
29366
|
-
serverStates["delete"](
|
|
29393
|
+
serverStates["delete"](stateKey);
|
|
29367
29394
|
case 9:
|
|
29368
29395
|
setIsConnecting(true);
|
|
29369
29396
|
setError(null);
|
|
29370
29397
|
|
|
29371
29398
|
// 2. Another hook instance already connecting? Piggyback on its promise
|
|
29372
|
-
if (!pendingConnects$1.has(
|
|
29399
|
+
if (!pendingConnects$1.has(stateKey)) {
|
|
29373
29400
|
_context.next = 17;
|
|
29374
29401
|
break;
|
|
29375
29402
|
}
|
|
29376
29403
|
_context.prev = 10;
|
|
29377
29404
|
_context.next = 11;
|
|
29378
|
-
return pendingConnects$1.get(
|
|
29405
|
+
return pendingConnects$1.get(stateKey);
|
|
29379
29406
|
case 11:
|
|
29380
29407
|
result = _context.sent;
|
|
29381
29408
|
if (mountedRef.current) {
|
|
@@ -29394,7 +29421,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29394
29421
|
return _context.abrupt("return");
|
|
29395
29422
|
case 13:
|
|
29396
29423
|
// Increment consumer count and apply
|
|
29397
|
-
state = serverStates.get(
|
|
29424
|
+
state = serverStates.get(stateKey);
|
|
29398
29425
|
if (state) state.consumerCount++;
|
|
29399
29426
|
applyResult(result);
|
|
29400
29427
|
_context.next = 16;
|
|
@@ -29417,9 +29444,9 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29417
29444
|
// 3. First caller — fire the IPC call and share the promise
|
|
29418
29445
|
connectPromise = new Promise(function (resolve, reject) {
|
|
29419
29446
|
dashApi.mcpStartServer(selectedProviderName, provider.mcpConfig, provider.credentials, function (event, result) {
|
|
29420
|
-
pendingConnects$1["delete"](
|
|
29447
|
+
pendingConnects$1["delete"](stateKey);
|
|
29421
29448
|
if (result.error) {
|
|
29422
|
-
serverStates.set(
|
|
29449
|
+
serverStates.set(stateKey, {
|
|
29423
29450
|
status: "error",
|
|
29424
29451
|
tools: [],
|
|
29425
29452
|
resources: [],
|
|
@@ -29430,7 +29457,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29430
29457
|
}
|
|
29431
29458
|
|
|
29432
29459
|
// Store in module-level shared state
|
|
29433
|
-
serverStates.set(
|
|
29460
|
+
serverStates.set(stateKey, {
|
|
29434
29461
|
status: "connected",
|
|
29435
29462
|
tools: result.tools || [],
|
|
29436
29463
|
resources: result.resources || [],
|
|
@@ -29438,17 +29465,17 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29438
29465
|
});
|
|
29439
29466
|
resolve(result);
|
|
29440
29467
|
}, function (event, err) {
|
|
29441
|
-
pendingConnects$1["delete"](
|
|
29442
|
-
serverStates.set(
|
|
29468
|
+
pendingConnects$1["delete"](stateKey);
|
|
29469
|
+
serverStates.set(stateKey, {
|
|
29443
29470
|
status: "error",
|
|
29444
29471
|
tools: [],
|
|
29445
29472
|
resources: [],
|
|
29446
29473
|
consumerCount: 0
|
|
29447
29474
|
});
|
|
29448
29475
|
reject(err);
|
|
29449
|
-
});
|
|
29476
|
+
}, workspaceId);
|
|
29450
29477
|
});
|
|
29451
|
-
pendingConnects$1.set(
|
|
29478
|
+
pendingConnects$1.set(stateKey, connectPromise);
|
|
29452
29479
|
_context.prev = 18;
|
|
29453
29480
|
_context.next = 19;
|
|
29454
29481
|
return connectPromise;
|
|
@@ -29489,14 +29516,15 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29489
29516
|
return _context.stop();
|
|
29490
29517
|
}
|
|
29491
29518
|
}, _callee, null, [[5, 8], [10, 14], [18, 22]]);
|
|
29492
|
-
})), [dashApi, provider, providerType, selectedProviderName, applyResult]);
|
|
29519
|
+
})), [dashApi, provider, providerType, selectedProviderName, applyResult, workspace]);
|
|
29493
29520
|
|
|
29494
29521
|
/**
|
|
29495
29522
|
* Disconnect from the MCP server.
|
|
29496
29523
|
* Only sends the IPC stop call when this is the last consumer.
|
|
29497
29524
|
*/
|
|
29498
29525
|
var disconnect = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
29499
|
-
var
|
|
29526
|
+
var _workspace$workspaceD3;
|
|
29527
|
+
var workspaceId, stateKey, state;
|
|
29500
29528
|
return _regeneratorRuntime.wrap(function (_context2) {
|
|
29501
29529
|
while (1) switch (_context2.prev = _context2.next) {
|
|
29502
29530
|
case 0:
|
|
@@ -29506,7 +29534,9 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29506
29534
|
}
|
|
29507
29535
|
return _context2.abrupt("return");
|
|
29508
29536
|
case 1:
|
|
29509
|
-
|
|
29537
|
+
workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD3 = workspace.workspaceData) === null || _workspace$workspaceD3 === void 0 ? void 0 : _workspace$workspaceD3.id) || null;
|
|
29538
|
+
stateKey = rendererStateKey(workspaceId, selectedProviderName);
|
|
29539
|
+
state = serverStates.get(stateKey);
|
|
29510
29540
|
if (!state) {
|
|
29511
29541
|
_context2.next = 3;
|
|
29512
29542
|
break;
|
|
@@ -29525,7 +29555,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29525
29555
|
return _context2.abrupt("return");
|
|
29526
29556
|
case 2:
|
|
29527
29557
|
// Last consumer — actually stop the server
|
|
29528
|
-
serverStates["delete"](
|
|
29558
|
+
serverStates["delete"](stateKey);
|
|
29529
29559
|
case 3:
|
|
29530
29560
|
// Clear state synchronously BEFORE the IPC call so that
|
|
29531
29561
|
// a subsequent connect() won't short-circuit on stale connectedRef
|
|
@@ -29534,29 +29564,31 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29534
29564
|
setResources([]);
|
|
29535
29565
|
setStatus("disconnected");
|
|
29536
29566
|
connectedRef.current = false;
|
|
29537
|
-
pendingConnects$1["delete"](
|
|
29567
|
+
pendingConnects$1["delete"](stateKey);
|
|
29538
29568
|
return _context2.abrupt("return", new Promise(function (resolve) {
|
|
29539
29569
|
dashApi.mcpStopServer(selectedProviderName, function () {
|
|
29540
29570
|
return resolve();
|
|
29541
29571
|
}, function (event, err) {
|
|
29542
29572
|
resolve();
|
|
29543
|
-
});
|
|
29573
|
+
}, workspaceId);
|
|
29544
29574
|
}));
|
|
29545
29575
|
case 4:
|
|
29546
29576
|
case "end":
|
|
29547
29577
|
return _context2.stop();
|
|
29548
29578
|
}
|
|
29549
29579
|
}, _callee2);
|
|
29550
|
-
})), [dashApi, selectedProviderName]);
|
|
29580
|
+
})), [dashApi, selectedProviderName, workspace]);
|
|
29551
29581
|
|
|
29552
29582
|
/**
|
|
29553
29583
|
* Call a tool on the MCP server
|
|
29554
29584
|
*/
|
|
29555
29585
|
var callTool = React.useCallback(/*#__PURE__*/function () {
|
|
29556
29586
|
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(toolName) {
|
|
29587
|
+
var _workspace$workspaceD4;
|
|
29557
29588
|
var args,
|
|
29558
29589
|
widgetRequiredTools,
|
|
29559
29590
|
isRequired,
|
|
29591
|
+
workspaceId,
|
|
29560
29592
|
_args3 = arguments;
|
|
29561
29593
|
return _regeneratorRuntime.wrap(function (_context3) {
|
|
29562
29594
|
while (1) switch (_context3.prev = _context3.next) {
|
|
@@ -29583,6 +29615,10 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29583
29615
|
isRequired = widgetRequiredTools === null || widgetRequiredTools === void 0 ? void 0 : widgetRequiredTools.includes(toolName);
|
|
29584
29616
|
throw new Error("Tool \"".concat(toolName, "\" is not allowed for this widget. Allowed tools: ").concat(effectiveAllowedTools.join(", ")).concat(isRequired ? ". Note: \"".concat(toolName, "\" is declared as a required tool by this widget \u2014 update the provider's allowed tools in Settings \u2192 Providers.") : ""));
|
|
29585
29617
|
case 2:
|
|
29618
|
+
// Slice 3a: scope the MCP server process per workspace. The
|
|
29619
|
+
// workspace UUID is the canonical "current dashboard" identity
|
|
29620
|
+
// (see useNotifications, useScheduler for the same pattern).
|
|
29621
|
+
workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD4 = workspace.workspaceData) === null || _workspace$workspaceD4 === void 0 ? void 0 : _workspace$workspaceD4.id) || null;
|
|
29586
29622
|
return _context3.abrupt("return", new Promise(function (resolve, reject) {
|
|
29587
29623
|
var timeout = setTimeout(function () {
|
|
29588
29624
|
reject(new Error("Tool call \"".concat(toolName, "\" timed out after 30s")));
|
|
@@ -29597,7 +29633,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29597
29633
|
}, function (event, err) {
|
|
29598
29634
|
clearTimeout(timeout);
|
|
29599
29635
|
reject(new Error((err === null || err === void 0 ? void 0 : err.message) || "Failed to call MCP tool"));
|
|
29600
|
-
});
|
|
29636
|
+
}, workspaceId);
|
|
29601
29637
|
}));
|
|
29602
29638
|
case 3:
|
|
29603
29639
|
case "end":
|
|
@@ -29608,7 +29644,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29608
29644
|
return function (_x) {
|
|
29609
29645
|
return _ref3.apply(this, arguments);
|
|
29610
29646
|
};
|
|
29611
|
-
}(), [dashApi, selectedProviderName, effectiveAllowedTools, widgetData, providerType]);
|
|
29647
|
+
}(), [dashApi, selectedProviderName, effectiveAllowedTools, widgetData, providerType, workspace]);
|
|
29612
29648
|
|
|
29613
29649
|
/**
|
|
29614
29650
|
* Read a resource from the MCP server
|
|
@@ -29666,7 +29702,10 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29666
29702
|
|
|
29667
29703
|
// Decrement consumer count; only stop server if last consumer
|
|
29668
29704
|
if (connectedRef.current && dashApi && selectedProviderName) {
|
|
29669
|
-
var
|
|
29705
|
+
var _workspace$workspaceD5;
|
|
29706
|
+
var workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD5 = workspace.workspaceData) === null || _workspace$workspaceD5 === void 0 ? void 0 : _workspace$workspaceD5.id) || null;
|
|
29707
|
+
var stateKey = rendererStateKey(workspaceId, selectedProviderName);
|
|
29708
|
+
var state = serverStates.get(stateKey);
|
|
29670
29709
|
if (state) {
|
|
29671
29710
|
state.consumerCount = Math.max(0, state.consumerCount - 1);
|
|
29672
29711
|
if (state.consumerCount > 0) {
|
|
@@ -29675,12 +29714,12 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29675
29714
|
}
|
|
29676
29715
|
|
|
29677
29716
|
// Last consumer — stop the server
|
|
29678
|
-
serverStates["delete"](
|
|
29717
|
+
serverStates["delete"](stateKey);
|
|
29679
29718
|
}
|
|
29680
|
-
dashApi.mcpStopServer(selectedProviderName, function () {}, function () {});
|
|
29719
|
+
dashApi.mcpStopServer(selectedProviderName, function () {}, function () {}, workspaceId);
|
|
29681
29720
|
}
|
|
29682
29721
|
};
|
|
29683
|
-
}, [dashApi, selectedProviderName]);
|
|
29722
|
+
}, [dashApi, selectedProviderName, workspace]);
|
|
29684
29723
|
return {
|
|
29685
29724
|
isConnected: isConnected,
|
|
29686
29725
|
isConnecting: isConnecting,
|
|
@@ -48570,6 +48609,243 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
48570
48609
|
});
|
|
48571
48610
|
};
|
|
48572
48611
|
|
|
48612
|
+
var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
48613
|
+
var _useState = React.useState([]),
|
|
48614
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
48615
|
+
rows = _useState2[0],
|
|
48616
|
+
setRows = _useState2[1];
|
|
48617
|
+
var _useState3 = React.useState(true),
|
|
48618
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
48619
|
+
loading = _useState4[0],
|
|
48620
|
+
setLoading = _useState4[1];
|
|
48621
|
+
var _useState5 = React.useState(null),
|
|
48622
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
48623
|
+
error = _useState6[0],
|
|
48624
|
+
setError = _useState6[1];
|
|
48625
|
+
var reload = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
48626
|
+
var _api$widgetMcp, api, result, _t;
|
|
48627
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
48628
|
+
while (1) switch (_context.prev = _context.next) {
|
|
48629
|
+
case 0:
|
|
48630
|
+
setError(null);
|
|
48631
|
+
_context.prev = 1;
|
|
48632
|
+
api = typeof window !== "undefined" ? window.mainApi : null;
|
|
48633
|
+
if (api !== null && api !== void 0 && (_api$widgetMcp = api.widgetMcp) !== null && _api$widgetMcp !== void 0 && _api$widgetMcp.listAll) {
|
|
48634
|
+
_context.next = 2;
|
|
48635
|
+
break;
|
|
48636
|
+
}
|
|
48637
|
+
setRows([]);
|
|
48638
|
+
setLoading(false);
|
|
48639
|
+
return _context.abrupt("return");
|
|
48640
|
+
case 2:
|
|
48641
|
+
_context.next = 3;
|
|
48642
|
+
return api.widgetMcp.listAll();
|
|
48643
|
+
case 3:
|
|
48644
|
+
result = _context.sent;
|
|
48645
|
+
setRows(Array.isArray(result) ? result : []);
|
|
48646
|
+
_context.next = 5;
|
|
48647
|
+
break;
|
|
48648
|
+
case 4:
|
|
48649
|
+
_context.prev = 4;
|
|
48650
|
+
_t = _context["catch"](1);
|
|
48651
|
+
setError((_t === null || _t === void 0 ? void 0 : _t.message) || String(_t));
|
|
48652
|
+
case 5:
|
|
48653
|
+
_context.prev = 5;
|
|
48654
|
+
setLoading(false);
|
|
48655
|
+
return _context.finish(5);
|
|
48656
|
+
case 6:
|
|
48657
|
+
case "end":
|
|
48658
|
+
return _context.stop();
|
|
48659
|
+
}
|
|
48660
|
+
}, _callee, null, [[1, 4, 5, 6]]);
|
|
48661
|
+
})), []);
|
|
48662
|
+
React.useEffect(function () {
|
|
48663
|
+
reload();
|
|
48664
|
+
}, [reload]);
|
|
48665
|
+
var revokeWidget = /*#__PURE__*/function () {
|
|
48666
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(widgetId) {
|
|
48667
|
+
var _window$mainApi, _window$mainApi$revok, _t2;
|
|
48668
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
48669
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
48670
|
+
case 0:
|
|
48671
|
+
_context2.prev = 0;
|
|
48672
|
+
_context2.next = 1;
|
|
48673
|
+
return (_window$mainApi = window.mainApi) === null || _window$mainApi === void 0 || (_window$mainApi = _window$mainApi.widgetMcp) === null || _window$mainApi === void 0 || (_window$mainApi$revok = _window$mainApi.revoke) === null || _window$mainApi$revok === void 0 ? void 0 : _window$mainApi$revok.call(_window$mainApi, widgetId);
|
|
48674
|
+
case 1:
|
|
48675
|
+
reload();
|
|
48676
|
+
_context2.next = 3;
|
|
48677
|
+
break;
|
|
48678
|
+
case 2:
|
|
48679
|
+
_context2.prev = 2;
|
|
48680
|
+
_t2 = _context2["catch"](0);
|
|
48681
|
+
setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || String(_t2));
|
|
48682
|
+
case 3:
|
|
48683
|
+
case "end":
|
|
48684
|
+
return _context2.stop();
|
|
48685
|
+
}
|
|
48686
|
+
}, _callee2, null, [[0, 2]]);
|
|
48687
|
+
}));
|
|
48688
|
+
return function revokeWidget(_x) {
|
|
48689
|
+
return _ref2.apply(this, arguments);
|
|
48690
|
+
};
|
|
48691
|
+
}();
|
|
48692
|
+
var revokeServer = /*#__PURE__*/function () {
|
|
48693
|
+
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(widgetId, serverName) {
|
|
48694
|
+
var _window$mainApi2, _window$mainApi2$revo, _t3;
|
|
48695
|
+
return _regeneratorRuntime.wrap(function (_context3) {
|
|
48696
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
48697
|
+
case 0:
|
|
48698
|
+
_context3.prev = 0;
|
|
48699
|
+
_context3.next = 1;
|
|
48700
|
+
return (_window$mainApi2 = window.mainApi) === null || _window$mainApi2 === void 0 || (_window$mainApi2 = _window$mainApi2.widgetMcp) === null || _window$mainApi2 === void 0 || (_window$mainApi2$revo = _window$mainApi2.revokeServer) === null || _window$mainApi2$revo === void 0 ? void 0 : _window$mainApi2$revo.call(_window$mainApi2, widgetId, serverName);
|
|
48701
|
+
case 1:
|
|
48702
|
+
reload();
|
|
48703
|
+
_context3.next = 3;
|
|
48704
|
+
break;
|
|
48705
|
+
case 2:
|
|
48706
|
+
_context3.prev = 2;
|
|
48707
|
+
_t3 = _context3["catch"](0);
|
|
48708
|
+
setError((_t3 === null || _t3 === void 0 ? void 0 : _t3.message) || String(_t3));
|
|
48709
|
+
case 3:
|
|
48710
|
+
case "end":
|
|
48711
|
+
return _context3.stop();
|
|
48712
|
+
}
|
|
48713
|
+
}, _callee3, null, [[0, 2]]);
|
|
48714
|
+
}));
|
|
48715
|
+
return function revokeServer(_x2, _x3) {
|
|
48716
|
+
return _ref3.apply(this, arguments);
|
|
48717
|
+
};
|
|
48718
|
+
}();
|
|
48719
|
+
if (loading) {
|
|
48720
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48721
|
+
className: "flex flex-col p-6",
|
|
48722
|
+
children: /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48723
|
+
className: "text-sm opacity-60",
|
|
48724
|
+
children: "Loading\u2026"
|
|
48725
|
+
})
|
|
48726
|
+
});
|
|
48727
|
+
}
|
|
48728
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48729
|
+
className: "flex flex-col space-y-6 p-6",
|
|
48730
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48731
|
+
className: "flex flex-col space-y-2",
|
|
48732
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
|
|
48733
|
+
title: "Widget MCP permissions",
|
|
48734
|
+
padding: false
|
|
48735
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48736
|
+
className: "text-xs opacity-60",
|
|
48737
|
+
children: "Tools and paths each widget is allowed to call via MCP. Granted paths are visible to other widgets in the same dashboard that use the same MCP server. Revoke any time."
|
|
48738
|
+
})]
|
|
48739
|
+
}), error && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48740
|
+
className: "text-xs text-red-400 bg-red-900 bg-opacity-20 border border-red-700 rounded p-3",
|
|
48741
|
+
children: error
|
|
48742
|
+
}), rows.length === 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48743
|
+
className: "text-sm opacity-60",
|
|
48744
|
+
children: "No widgets have requested MCP permissions yet."
|
|
48745
|
+
}), rows.map(function (_ref4) {
|
|
48746
|
+
var widgetId = _ref4.widgetId,
|
|
48747
|
+
declared = _ref4.declared,
|
|
48748
|
+
granted = _ref4.granted;
|
|
48749
|
+
return /*#__PURE__*/jsxRuntime.jsx(WidgetGrantRow, {
|
|
48750
|
+
widgetId: widgetId,
|
|
48751
|
+
declared: declared,
|
|
48752
|
+
granted: granted,
|
|
48753
|
+
onRevokeWidget: function onRevokeWidget() {
|
|
48754
|
+
return revokeWidget(widgetId);
|
|
48755
|
+
},
|
|
48756
|
+
onRevokeServer: function onRevokeServer(serverName) {
|
|
48757
|
+
return revokeServer(widgetId, serverName);
|
|
48758
|
+
}
|
|
48759
|
+
}, widgetId);
|
|
48760
|
+
})]
|
|
48761
|
+
});
|
|
48762
|
+
};
|
|
48763
|
+
var WidgetGrantRow = function WidgetGrantRow(_ref5) {
|
|
48764
|
+
var widgetId = _ref5.widgetId,
|
|
48765
|
+
declared = _ref5.declared,
|
|
48766
|
+
granted = _ref5.granted,
|
|
48767
|
+
onRevokeWidget = _ref5.onRevokeWidget,
|
|
48768
|
+
onRevokeServer = _ref5.onRevokeServer;
|
|
48769
|
+
var declaredServers = declared && declared.servers || {};
|
|
48770
|
+
var grantedServers = granted && granted.servers || {};
|
|
48771
|
+
var allServerNames = Array.from(new Set([].concat(_toConsumableArray(Object.keys(declaredServers)), _toConsumableArray(Object.keys(grantedServers)))));
|
|
48772
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48773
|
+
className: "flex flex-col space-y-3 border border-gray-700 rounded p-3",
|
|
48774
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48775
|
+
className: "flex flex-row items-center justify-between",
|
|
48776
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48777
|
+
className: "text-sm font-mono break-all",
|
|
48778
|
+
children: widgetId
|
|
48779
|
+
}), Object.keys(grantedServers).length > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
|
|
48780
|
+
title: "Revoke all",
|
|
48781
|
+
onClick: onRevokeWidget
|
|
48782
|
+
})]
|
|
48783
|
+
}), !declared && !granted && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48784
|
+
className: "text-xs opacity-50",
|
|
48785
|
+
children: "(no manifest, no grant \u2014 should not happen)"
|
|
48786
|
+
}), allServerNames.map(function (serverName) {
|
|
48787
|
+
var decl = declaredServers[serverName] || {};
|
|
48788
|
+
var grant = grantedServers[serverName];
|
|
48789
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48790
|
+
className: "flex flex-col space-y-2 border-t border-gray-800 pt-2",
|
|
48791
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48792
|
+
className: "flex flex-row items-center justify-between",
|
|
48793
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
48794
|
+
className: "text-xs uppercase tracking-wider opacity-70",
|
|
48795
|
+
children: [serverName, !grant && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48796
|
+
className: "ml-2 text-amber-400 normal-case tracking-normal",
|
|
48797
|
+
children: "(declared, not granted)"
|
|
48798
|
+
})]
|
|
48799
|
+
}), grant && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
|
|
48800
|
+
title: "Revoke server",
|
|
48801
|
+
onClick: function onClick() {
|
|
48802
|
+
return onRevokeServer(serverName);
|
|
48803
|
+
}
|
|
48804
|
+
})]
|
|
48805
|
+
}), /*#__PURE__*/jsxRuntime.jsx(PermsList, {
|
|
48806
|
+
label: "Tools",
|
|
48807
|
+
declaredItems: decl.tools || [],
|
|
48808
|
+
grantedItems: (grant === null || grant === void 0 ? void 0 : grant.tools) || []
|
|
48809
|
+
}), /*#__PURE__*/jsxRuntime.jsx(PermsList, {
|
|
48810
|
+
label: "Read paths",
|
|
48811
|
+
declaredItems: decl.readPaths || [],
|
|
48812
|
+
grantedItems: (grant === null || grant === void 0 ? void 0 : grant.readPaths) || []
|
|
48813
|
+
}), /*#__PURE__*/jsxRuntime.jsx(PermsList, {
|
|
48814
|
+
label: "Write paths",
|
|
48815
|
+
declaredItems: decl.writePaths || [],
|
|
48816
|
+
grantedItems: (grant === null || grant === void 0 ? void 0 : grant.writePaths) || []
|
|
48817
|
+
})]
|
|
48818
|
+
}, serverName);
|
|
48819
|
+
})]
|
|
48820
|
+
});
|
|
48821
|
+
};
|
|
48822
|
+
var PermsList = function PermsList(_ref6) {
|
|
48823
|
+
var label = _ref6.label,
|
|
48824
|
+
declaredItems = _ref6.declaredItems,
|
|
48825
|
+
grantedItems = _ref6.grantedItems;
|
|
48826
|
+
if (declaredItems.length === 0 && grantedItems.length === 0) return null;
|
|
48827
|
+
var grantedSet = new Set(grantedItems);
|
|
48828
|
+
var declaredSet = new Set(declaredItems);
|
|
48829
|
+
var all = Array.from(new Set([].concat(_toConsumableArray(declaredItems), _toConsumableArray(grantedItems))));
|
|
48830
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48831
|
+
className: "flex flex-col space-y-1",
|
|
48832
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48833
|
+
className: "text-xs opacity-50",
|
|
48834
|
+
children: label
|
|
48835
|
+
}), all.map(function (item) {
|
|
48836
|
+
var isGranted = grantedSet.has(item);
|
|
48837
|
+
var isDeclared = declaredSet.has(item);
|
|
48838
|
+
return /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
48839
|
+
className: "text-xs font-mono break-all ".concat(isGranted ? "opacity-100" : isDeclared ? "opacity-50 line-through" : "opacity-100 text-amber-400"),
|
|
48840
|
+
children: [item, !isDeclared && isGranted && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48841
|
+
className: "ml-2 opacity-60",
|
|
48842
|
+
children: "(no longer declared)"
|
|
48843
|
+
})]
|
|
48844
|
+
}, item);
|
|
48845
|
+
})]
|
|
48846
|
+
});
|
|
48847
|
+
};
|
|
48848
|
+
|
|
48573
48849
|
var SECTIONS = [{
|
|
48574
48850
|
key: "general",
|
|
48575
48851
|
label: "General",
|
|
@@ -48610,6 +48886,10 @@ var SECTIONS = [{
|
|
|
48610
48886
|
key: "ai-assistant",
|
|
48611
48887
|
label: "AI Assistant",
|
|
48612
48888
|
icon: "wand-magic-sparkles"
|
|
48889
|
+
}, {
|
|
48890
|
+
key: "privacy-security",
|
|
48891
|
+
label: "Privacy & Security",
|
|
48892
|
+
icon: "shield-halved"
|
|
48613
48893
|
}];
|
|
48614
48894
|
var AppSettingsModal = function AppSettingsModal(_ref) {
|
|
48615
48895
|
var isOpen = _ref.isOpen,
|
|
@@ -48797,6 +49077,9 @@ var AppSettingsModal = function AppSettingsModal(_ref) {
|
|
|
48797
49077
|
}), activeSection === "ai-assistant" && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48798
49078
|
className: "flex-1 overflow-y-auto p-6 ".concat(panelStyles.textColor || "text-gray-200"),
|
|
48799
49079
|
children: /*#__PURE__*/jsxRuntime.jsx(AiAssistantSection, {})
|
|
49080
|
+
}), activeSection === "privacy-security" && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
49081
|
+
className: "flex-1 overflow-y-auto ".concat(panelStyles.textColor || "text-gray-200"),
|
|
49082
|
+
children: /*#__PURE__*/jsxRuntime.jsx(PrivacySecuritySection, {})
|
|
48800
49083
|
})]
|
|
48801
49084
|
}), /*#__PURE__*/jsxRuntime.jsx(DashReact.SettingsModal.Footer, {
|
|
48802
49085
|
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|