@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.esm.js
CHANGED
|
@@ -1626,9 +1626,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1626
1626
|
key: "mcpStartServer",
|
|
1627
1627
|
value: function mcpStartServer(serverName, mcpConfig, credentials, onSuccess, onError) {
|
|
1628
1628
|
var _this20 = this;
|
|
1629
|
+
var workspaceId = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
|
|
1629
1630
|
if (this.api !== null) {
|
|
1630
1631
|
try {
|
|
1631
|
-
this.api.mcp.startServer(serverName, mcpConfig, credentials).then(function (result) {
|
|
1632
|
+
this.api.mcp.startServer(serverName, mcpConfig, credentials, workspaceId).then(function (result) {
|
|
1632
1633
|
onSuccess(_this20.events.MCP_START_SERVER_COMPLETE, result);
|
|
1633
1634
|
})["catch"](function (error) {
|
|
1634
1635
|
onError(_this20.events.MCP_START_SERVER_ERROR, error);
|
|
@@ -1647,9 +1648,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1647
1648
|
key: "mcpStopServer",
|
|
1648
1649
|
value: function mcpStopServer(serverName, onSuccess, onError) {
|
|
1649
1650
|
var _this21 = this;
|
|
1651
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1650
1652
|
if (this.api !== null) {
|
|
1651
1653
|
try {
|
|
1652
|
-
this.api.mcp.stopServer(serverName).then(function (result) {
|
|
1654
|
+
this.api.mcp.stopServer(serverName, workspaceId).then(function (result) {
|
|
1653
1655
|
onSuccess(_this21.events.MCP_STOP_SERVER_COMPLETE, result);
|
|
1654
1656
|
})["catch"](function (error) {
|
|
1655
1657
|
onError(_this21.events.MCP_STOP_SERVER_ERROR, error);
|
|
@@ -1668,9 +1670,13 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1668
1670
|
key: "mcpCallTool",
|
|
1669
1671
|
value: function mcpCallTool(serverName, toolName, args, allowedTools, onSuccess, onError) {
|
|
1670
1672
|
var _this22 = this;
|
|
1673
|
+
var workspaceId = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
|
|
1671
1674
|
if (this.api !== null) {
|
|
1672
1675
|
try {
|
|
1673
|
-
|
|
1676
|
+
// widgetId is not threaded here; mcpApi.callTool defaults it to
|
|
1677
|
+
// null. Slice 3a: workspaceId scopes the MCP server process per
|
|
1678
|
+
// workspace.
|
|
1679
|
+
this.api.mcp.callTool(serverName, toolName, args, allowedTools, null, workspaceId).then(function (result) {
|
|
1674
1680
|
onSuccess(_this22.events.MCP_CALL_TOOL_COMPLETE, result);
|
|
1675
1681
|
})["catch"](function (error) {
|
|
1676
1682
|
onError(_this22.events.MCP_CALL_TOOL_ERROR, error);
|
|
@@ -1689,9 +1695,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1689
1695
|
key: "mcpListTools",
|
|
1690
1696
|
value: function mcpListTools(serverName, onSuccess, onError) {
|
|
1691
1697
|
var _this23 = this;
|
|
1698
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1692
1699
|
if (this.api !== null) {
|
|
1693
1700
|
try {
|
|
1694
|
-
this.api.mcp.listTools(serverName).then(function (result) {
|
|
1701
|
+
this.api.mcp.listTools(serverName, workspaceId).then(function (result) {
|
|
1695
1702
|
onSuccess(_this23.events.MCP_LIST_TOOLS_COMPLETE, result);
|
|
1696
1703
|
})["catch"](function (error) {
|
|
1697
1704
|
onError(_this23.events.MCP_LIST_TOOLS_ERROR, error);
|
|
@@ -1710,9 +1717,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1710
1717
|
key: "mcpListResources",
|
|
1711
1718
|
value: function mcpListResources(serverName, onSuccess, onError) {
|
|
1712
1719
|
var _this24 = this;
|
|
1720
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1713
1721
|
if (this.api !== null) {
|
|
1714
1722
|
try {
|
|
1715
|
-
this.api.mcp.listResources(serverName).then(function (result) {
|
|
1723
|
+
this.api.mcp.listResources(serverName, workspaceId).then(function (result) {
|
|
1716
1724
|
onSuccess(_this24.events.MCP_LIST_RESOURCES_COMPLETE, result);
|
|
1717
1725
|
})["catch"](function (error) {
|
|
1718
1726
|
onError(_this24.events.MCP_LIST_RESOURCES_ERROR, error);
|
|
@@ -1731,9 +1739,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1731
1739
|
key: "mcpReadResource",
|
|
1732
1740
|
value: function mcpReadResource(serverName, uri, onSuccess, onError) {
|
|
1733
1741
|
var _this25 = this;
|
|
1742
|
+
var workspaceId = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
1734
1743
|
if (this.api !== null) {
|
|
1735
1744
|
try {
|
|
1736
|
-
this.api.mcp.readResource(serverName, uri).then(function (result) {
|
|
1745
|
+
this.api.mcp.readResource(serverName, uri, workspaceId).then(function (result) {
|
|
1737
1746
|
onSuccess(_this25.events.MCP_READ_RESOURCE_COMPLETE, result);
|
|
1738
1747
|
})["catch"](function (error) {
|
|
1739
1748
|
onError(_this25.events.MCP_READ_RESOURCE_ERROR, error);
|
|
@@ -1752,9 +1761,10 @@ var ElectronDashboardApi = /*#__PURE__*/function () {
|
|
|
1752
1761
|
key: "mcpGetServerStatus",
|
|
1753
1762
|
value: function mcpGetServerStatus(serverName, onSuccess, onError) {
|
|
1754
1763
|
var _this26 = this;
|
|
1764
|
+
var workspaceId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1755
1765
|
if (this.api !== null) {
|
|
1756
1766
|
try {
|
|
1757
|
-
this.api.mcp.getServerStatus(serverName).then(function (result) {
|
|
1767
|
+
this.api.mcp.getServerStatus(serverName, workspaceId).then(function (result) {
|
|
1758
1768
|
onSuccess(_this26.events.MCP_SERVER_STATUS_COMPLETE, result);
|
|
1759
1769
|
})["catch"](function (error) {
|
|
1760
1770
|
onError(_this26.events.MCP_SERVER_STATUS_ERROR, error);
|
|
@@ -29102,17 +29112,27 @@ var useWidgetProviders = function useWidgetProviders() {
|
|
|
29102
29112
|
|
|
29103
29113
|
/**
|
|
29104
29114
|
* Module-level shared state for MCP server connections.
|
|
29105
|
-
* Prevents multiple hook instances (e.g., 4 widgets
|
|
29106
|
-
* each firing their own IPC startServer call.
|
|
29115
|
+
* Prevents multiple hook instances (e.g., 4 widgets on the same dashboard
|
|
29116
|
+
* using "slack") from each firing their own IPC startServer call.
|
|
29107
29117
|
*
|
|
29108
|
-
*
|
|
29109
|
-
*
|
|
29118
|
+
* Slice 3a: keys are scoped per `(workspaceId, serverName)` so two
|
|
29119
|
+
* dashboards using the same provider name don't share renderer state
|
|
29120
|
+
* (the main process spawns separate server instances for each).
|
|
29121
|
+
*
|
|
29122
|
+
* serverStates: tracks connection result + consumer reference count
|
|
29123
|
+
* pendingConnects: deduplicates in-flight IPC calls
|
|
29110
29124
|
*/
|
|
29111
29125
|
var serverStates = new Map();
|
|
29112
|
-
// Map
|
|
29126
|
+
// Map<`${workspaceId}::${serverName}`, { status, tools, resources, consumerCount }>
|
|
29113
29127
|
|
|
29114
29128
|
var pendingConnects$1 = new Map();
|
|
29115
|
-
// Map
|
|
29129
|
+
// Map<`${workspaceId}::${serverName}`, Promise<result>>
|
|
29130
|
+
|
|
29131
|
+
var NO_WORKSPACE = "__no_workspace__";
|
|
29132
|
+
function rendererStateKey(workspaceId, serverName) {
|
|
29133
|
+
var wid = workspaceId && typeof workspaceId === "string" ? workspaceId : NO_WORKSPACE;
|
|
29134
|
+
return wid + "::" + serverName;
|
|
29135
|
+
}
|
|
29116
29136
|
|
|
29117
29137
|
/**
|
|
29118
29138
|
* useMcpProvider Hook
|
|
@@ -29281,7 +29301,8 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29281
29301
|
* even when multiple hook instances call connect() simultaneously.
|
|
29282
29302
|
*/
|
|
29283
29303
|
var connect = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
29284
|
-
var
|
|
29304
|
+
var _workspace$workspaceD2;
|
|
29305
|
+
var workspaceId, stateKey, cached, statusResult, result, state, connectPromise, _result, _t2, _t3;
|
|
29285
29306
|
return _regeneratorRuntime.wrap(function (_context) {
|
|
29286
29307
|
while (1) switch (_context.prev = _context.next) {
|
|
29287
29308
|
case 0:
|
|
@@ -29312,9 +29333,15 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29312
29333
|
setError("Provider \"".concat(selectedProviderName, "\" has no MCP configuration"));
|
|
29313
29334
|
return _context.abrupt("return");
|
|
29314
29335
|
case 4:
|
|
29315
|
-
//
|
|
29336
|
+
// Slice 3a: scope state per (workspace, provider). Two dashboards
|
|
29337
|
+
// using the same provider name get separate server instances in the
|
|
29338
|
+
// main process, so the renderer state must mirror that or one
|
|
29339
|
+
// dashboard's "connected" cache will short-circuit a second
|
|
29340
|
+
// dashboard's connect that needs its own backing process.
|
|
29341
|
+
workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD2 = workspace.workspaceData) === null || _workspace$workspaceD2 === void 0 ? void 0 : _workspace$workspaceD2.id) || null;
|
|
29342
|
+
stateKey = rendererStateKey(workspaceId, selectedProviderName); // 1. Already connected at module level? Verify with main process before trusting cache.
|
|
29316
29343
|
// The server may have been stopped externally (e.g., Test Connection in settings).
|
|
29317
|
-
cached = serverStates.get(
|
|
29344
|
+
cached = serverStates.get(stateKey);
|
|
29318
29345
|
if (!(cached && cached.status === "connected")) {
|
|
29319
29346
|
_context.next = 9;
|
|
29320
29347
|
break;
|
|
@@ -29326,7 +29353,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29326
29353
|
return resolve(result);
|
|
29327
29354
|
}, function (event, err) {
|
|
29328
29355
|
return reject(err);
|
|
29329
|
-
});
|
|
29356
|
+
}, workspaceId);
|
|
29330
29357
|
});
|
|
29331
29358
|
case 6:
|
|
29332
29359
|
statusResult = _context.sent;
|
|
@@ -29339,25 +29366,25 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29339
29366
|
return _context.abrupt("return");
|
|
29340
29367
|
case 7:
|
|
29341
29368
|
// Server was stopped externally — clear stale cache and reconnect
|
|
29342
|
-
serverStates["delete"](
|
|
29369
|
+
serverStates["delete"](stateKey);
|
|
29343
29370
|
_context.next = 9;
|
|
29344
29371
|
break;
|
|
29345
29372
|
case 8:
|
|
29346
29373
|
_context.prev = 8;
|
|
29347
29374
|
_context["catch"](5);
|
|
29348
|
-
serverStates["delete"](
|
|
29375
|
+
serverStates["delete"](stateKey);
|
|
29349
29376
|
case 9:
|
|
29350
29377
|
setIsConnecting(true);
|
|
29351
29378
|
setError(null);
|
|
29352
29379
|
|
|
29353
29380
|
// 2. Another hook instance already connecting? Piggyback on its promise
|
|
29354
|
-
if (!pendingConnects$1.has(
|
|
29381
|
+
if (!pendingConnects$1.has(stateKey)) {
|
|
29355
29382
|
_context.next = 17;
|
|
29356
29383
|
break;
|
|
29357
29384
|
}
|
|
29358
29385
|
_context.prev = 10;
|
|
29359
29386
|
_context.next = 11;
|
|
29360
|
-
return pendingConnects$1.get(
|
|
29387
|
+
return pendingConnects$1.get(stateKey);
|
|
29361
29388
|
case 11:
|
|
29362
29389
|
result = _context.sent;
|
|
29363
29390
|
if (mountedRef.current) {
|
|
@@ -29376,7 +29403,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29376
29403
|
return _context.abrupt("return");
|
|
29377
29404
|
case 13:
|
|
29378
29405
|
// Increment consumer count and apply
|
|
29379
|
-
state = serverStates.get(
|
|
29406
|
+
state = serverStates.get(stateKey);
|
|
29380
29407
|
if (state) state.consumerCount++;
|
|
29381
29408
|
applyResult(result);
|
|
29382
29409
|
_context.next = 16;
|
|
@@ -29399,9 +29426,9 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29399
29426
|
// 3. First caller — fire the IPC call and share the promise
|
|
29400
29427
|
connectPromise = new Promise(function (resolve, reject) {
|
|
29401
29428
|
dashApi.mcpStartServer(selectedProviderName, provider.mcpConfig, provider.credentials, function (event, result) {
|
|
29402
|
-
pendingConnects$1["delete"](
|
|
29429
|
+
pendingConnects$1["delete"](stateKey);
|
|
29403
29430
|
if (result.error) {
|
|
29404
|
-
serverStates.set(
|
|
29431
|
+
serverStates.set(stateKey, {
|
|
29405
29432
|
status: "error",
|
|
29406
29433
|
tools: [],
|
|
29407
29434
|
resources: [],
|
|
@@ -29412,7 +29439,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29412
29439
|
}
|
|
29413
29440
|
|
|
29414
29441
|
// Store in module-level shared state
|
|
29415
|
-
serverStates.set(
|
|
29442
|
+
serverStates.set(stateKey, {
|
|
29416
29443
|
status: "connected",
|
|
29417
29444
|
tools: result.tools || [],
|
|
29418
29445
|
resources: result.resources || [],
|
|
@@ -29420,17 +29447,17 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29420
29447
|
});
|
|
29421
29448
|
resolve(result);
|
|
29422
29449
|
}, function (event, err) {
|
|
29423
|
-
pendingConnects$1["delete"](
|
|
29424
|
-
serverStates.set(
|
|
29450
|
+
pendingConnects$1["delete"](stateKey);
|
|
29451
|
+
serverStates.set(stateKey, {
|
|
29425
29452
|
status: "error",
|
|
29426
29453
|
tools: [],
|
|
29427
29454
|
resources: [],
|
|
29428
29455
|
consumerCount: 0
|
|
29429
29456
|
});
|
|
29430
29457
|
reject(err);
|
|
29431
|
-
});
|
|
29458
|
+
}, workspaceId);
|
|
29432
29459
|
});
|
|
29433
|
-
pendingConnects$1.set(
|
|
29460
|
+
pendingConnects$1.set(stateKey, connectPromise);
|
|
29434
29461
|
_context.prev = 18;
|
|
29435
29462
|
_context.next = 19;
|
|
29436
29463
|
return connectPromise;
|
|
@@ -29471,14 +29498,15 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29471
29498
|
return _context.stop();
|
|
29472
29499
|
}
|
|
29473
29500
|
}, _callee, null, [[5, 8], [10, 14], [18, 22]]);
|
|
29474
|
-
})), [dashApi, provider, providerType, selectedProviderName, applyResult]);
|
|
29501
|
+
})), [dashApi, provider, providerType, selectedProviderName, applyResult, workspace]);
|
|
29475
29502
|
|
|
29476
29503
|
/**
|
|
29477
29504
|
* Disconnect from the MCP server.
|
|
29478
29505
|
* Only sends the IPC stop call when this is the last consumer.
|
|
29479
29506
|
*/
|
|
29480
29507
|
var disconnect = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
29481
|
-
var
|
|
29508
|
+
var _workspace$workspaceD3;
|
|
29509
|
+
var workspaceId, stateKey, state;
|
|
29482
29510
|
return _regeneratorRuntime.wrap(function (_context2) {
|
|
29483
29511
|
while (1) switch (_context2.prev = _context2.next) {
|
|
29484
29512
|
case 0:
|
|
@@ -29488,7 +29516,9 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29488
29516
|
}
|
|
29489
29517
|
return _context2.abrupt("return");
|
|
29490
29518
|
case 1:
|
|
29491
|
-
|
|
29519
|
+
workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD3 = workspace.workspaceData) === null || _workspace$workspaceD3 === void 0 ? void 0 : _workspace$workspaceD3.id) || null;
|
|
29520
|
+
stateKey = rendererStateKey(workspaceId, selectedProviderName);
|
|
29521
|
+
state = serverStates.get(stateKey);
|
|
29492
29522
|
if (!state) {
|
|
29493
29523
|
_context2.next = 3;
|
|
29494
29524
|
break;
|
|
@@ -29507,7 +29537,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29507
29537
|
return _context2.abrupt("return");
|
|
29508
29538
|
case 2:
|
|
29509
29539
|
// Last consumer — actually stop the server
|
|
29510
|
-
serverStates["delete"](
|
|
29540
|
+
serverStates["delete"](stateKey);
|
|
29511
29541
|
case 3:
|
|
29512
29542
|
// Clear state synchronously BEFORE the IPC call so that
|
|
29513
29543
|
// a subsequent connect() won't short-circuit on stale connectedRef
|
|
@@ -29516,29 +29546,31 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29516
29546
|
setResources([]);
|
|
29517
29547
|
setStatus("disconnected");
|
|
29518
29548
|
connectedRef.current = false;
|
|
29519
|
-
pendingConnects$1["delete"](
|
|
29549
|
+
pendingConnects$1["delete"](stateKey);
|
|
29520
29550
|
return _context2.abrupt("return", new Promise(function (resolve) {
|
|
29521
29551
|
dashApi.mcpStopServer(selectedProviderName, function () {
|
|
29522
29552
|
return resolve();
|
|
29523
29553
|
}, function (event, err) {
|
|
29524
29554
|
resolve();
|
|
29525
|
-
});
|
|
29555
|
+
}, workspaceId);
|
|
29526
29556
|
}));
|
|
29527
29557
|
case 4:
|
|
29528
29558
|
case "end":
|
|
29529
29559
|
return _context2.stop();
|
|
29530
29560
|
}
|
|
29531
29561
|
}, _callee2);
|
|
29532
|
-
})), [dashApi, selectedProviderName]);
|
|
29562
|
+
})), [dashApi, selectedProviderName, workspace]);
|
|
29533
29563
|
|
|
29534
29564
|
/**
|
|
29535
29565
|
* Call a tool on the MCP server
|
|
29536
29566
|
*/
|
|
29537
29567
|
var callTool = useCallback(/*#__PURE__*/function () {
|
|
29538
29568
|
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(toolName) {
|
|
29569
|
+
var _workspace$workspaceD4;
|
|
29539
29570
|
var args,
|
|
29540
29571
|
widgetRequiredTools,
|
|
29541
29572
|
isRequired,
|
|
29573
|
+
workspaceId,
|
|
29542
29574
|
_args3 = arguments;
|
|
29543
29575
|
return _regeneratorRuntime.wrap(function (_context3) {
|
|
29544
29576
|
while (1) switch (_context3.prev = _context3.next) {
|
|
@@ -29565,6 +29597,10 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29565
29597
|
isRequired = widgetRequiredTools === null || widgetRequiredTools === void 0 ? void 0 : widgetRequiredTools.includes(toolName);
|
|
29566
29598
|
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.") : ""));
|
|
29567
29599
|
case 2:
|
|
29600
|
+
// Slice 3a: scope the MCP server process per workspace. The
|
|
29601
|
+
// workspace UUID is the canonical "current dashboard" identity
|
|
29602
|
+
// (see useNotifications, useScheduler for the same pattern).
|
|
29603
|
+
workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD4 = workspace.workspaceData) === null || _workspace$workspaceD4 === void 0 ? void 0 : _workspace$workspaceD4.id) || null;
|
|
29568
29604
|
return _context3.abrupt("return", new Promise(function (resolve, reject) {
|
|
29569
29605
|
var timeout = setTimeout(function () {
|
|
29570
29606
|
reject(new Error("Tool call \"".concat(toolName, "\" timed out after 30s")));
|
|
@@ -29579,7 +29615,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29579
29615
|
}, function (event, err) {
|
|
29580
29616
|
clearTimeout(timeout);
|
|
29581
29617
|
reject(new Error((err === null || err === void 0 ? void 0 : err.message) || "Failed to call MCP tool"));
|
|
29582
|
-
});
|
|
29618
|
+
}, workspaceId);
|
|
29583
29619
|
}));
|
|
29584
29620
|
case 3:
|
|
29585
29621
|
case "end":
|
|
@@ -29590,7 +29626,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29590
29626
|
return function (_x) {
|
|
29591
29627
|
return _ref3.apply(this, arguments);
|
|
29592
29628
|
};
|
|
29593
|
-
}(), [dashApi, selectedProviderName, effectiveAllowedTools, widgetData, providerType]);
|
|
29629
|
+
}(), [dashApi, selectedProviderName, effectiveAllowedTools, widgetData, providerType, workspace]);
|
|
29594
29630
|
|
|
29595
29631
|
/**
|
|
29596
29632
|
* Read a resource from the MCP server
|
|
@@ -29648,7 +29684,10 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29648
29684
|
|
|
29649
29685
|
// Decrement consumer count; only stop server if last consumer
|
|
29650
29686
|
if (connectedRef.current && dashApi && selectedProviderName) {
|
|
29651
|
-
var
|
|
29687
|
+
var _workspace$workspaceD5;
|
|
29688
|
+
var workspaceId = (workspace === null || workspace === void 0 || (_workspace$workspaceD5 = workspace.workspaceData) === null || _workspace$workspaceD5 === void 0 ? void 0 : _workspace$workspaceD5.id) || null;
|
|
29689
|
+
var stateKey = rendererStateKey(workspaceId, selectedProviderName);
|
|
29690
|
+
var state = serverStates.get(stateKey);
|
|
29652
29691
|
if (state) {
|
|
29653
29692
|
state.consumerCount = Math.max(0, state.consumerCount - 1);
|
|
29654
29693
|
if (state.consumerCount > 0) {
|
|
@@ -29657,12 +29696,12 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
29657
29696
|
}
|
|
29658
29697
|
|
|
29659
29698
|
// Last consumer — stop the server
|
|
29660
|
-
serverStates["delete"](
|
|
29699
|
+
serverStates["delete"](stateKey);
|
|
29661
29700
|
}
|
|
29662
|
-
dashApi.mcpStopServer(selectedProviderName, function () {}, function () {});
|
|
29701
|
+
dashApi.mcpStopServer(selectedProviderName, function () {}, function () {}, workspaceId);
|
|
29663
29702
|
}
|
|
29664
29703
|
};
|
|
29665
|
-
}, [dashApi, selectedProviderName]);
|
|
29704
|
+
}, [dashApi, selectedProviderName, workspace]);
|
|
29666
29705
|
return {
|
|
29667
29706
|
isConnected: isConnected,
|
|
29668
29707
|
isConnecting: isConnecting,
|
|
@@ -48552,6 +48591,243 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
48552
48591
|
});
|
|
48553
48592
|
};
|
|
48554
48593
|
|
|
48594
|
+
var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
48595
|
+
var _useState = useState([]),
|
|
48596
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
48597
|
+
rows = _useState2[0],
|
|
48598
|
+
setRows = _useState2[1];
|
|
48599
|
+
var _useState3 = useState(true),
|
|
48600
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
48601
|
+
loading = _useState4[0],
|
|
48602
|
+
setLoading = _useState4[1];
|
|
48603
|
+
var _useState5 = useState(null),
|
|
48604
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
48605
|
+
error = _useState6[0],
|
|
48606
|
+
setError = _useState6[1];
|
|
48607
|
+
var reload = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
48608
|
+
var _api$widgetMcp, api, result, _t;
|
|
48609
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
48610
|
+
while (1) switch (_context.prev = _context.next) {
|
|
48611
|
+
case 0:
|
|
48612
|
+
setError(null);
|
|
48613
|
+
_context.prev = 1;
|
|
48614
|
+
api = typeof window !== "undefined" ? window.mainApi : null;
|
|
48615
|
+
if (api !== null && api !== void 0 && (_api$widgetMcp = api.widgetMcp) !== null && _api$widgetMcp !== void 0 && _api$widgetMcp.listAll) {
|
|
48616
|
+
_context.next = 2;
|
|
48617
|
+
break;
|
|
48618
|
+
}
|
|
48619
|
+
setRows([]);
|
|
48620
|
+
setLoading(false);
|
|
48621
|
+
return _context.abrupt("return");
|
|
48622
|
+
case 2:
|
|
48623
|
+
_context.next = 3;
|
|
48624
|
+
return api.widgetMcp.listAll();
|
|
48625
|
+
case 3:
|
|
48626
|
+
result = _context.sent;
|
|
48627
|
+
setRows(Array.isArray(result) ? result : []);
|
|
48628
|
+
_context.next = 5;
|
|
48629
|
+
break;
|
|
48630
|
+
case 4:
|
|
48631
|
+
_context.prev = 4;
|
|
48632
|
+
_t = _context["catch"](1);
|
|
48633
|
+
setError((_t === null || _t === void 0 ? void 0 : _t.message) || String(_t));
|
|
48634
|
+
case 5:
|
|
48635
|
+
_context.prev = 5;
|
|
48636
|
+
setLoading(false);
|
|
48637
|
+
return _context.finish(5);
|
|
48638
|
+
case 6:
|
|
48639
|
+
case "end":
|
|
48640
|
+
return _context.stop();
|
|
48641
|
+
}
|
|
48642
|
+
}, _callee, null, [[1, 4, 5, 6]]);
|
|
48643
|
+
})), []);
|
|
48644
|
+
useEffect(function () {
|
|
48645
|
+
reload();
|
|
48646
|
+
}, [reload]);
|
|
48647
|
+
var revokeWidget = /*#__PURE__*/function () {
|
|
48648
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(widgetId) {
|
|
48649
|
+
var _window$mainApi, _window$mainApi$revok, _t2;
|
|
48650
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
48651
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
48652
|
+
case 0:
|
|
48653
|
+
_context2.prev = 0;
|
|
48654
|
+
_context2.next = 1;
|
|
48655
|
+
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);
|
|
48656
|
+
case 1:
|
|
48657
|
+
reload();
|
|
48658
|
+
_context2.next = 3;
|
|
48659
|
+
break;
|
|
48660
|
+
case 2:
|
|
48661
|
+
_context2.prev = 2;
|
|
48662
|
+
_t2 = _context2["catch"](0);
|
|
48663
|
+
setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || String(_t2));
|
|
48664
|
+
case 3:
|
|
48665
|
+
case "end":
|
|
48666
|
+
return _context2.stop();
|
|
48667
|
+
}
|
|
48668
|
+
}, _callee2, null, [[0, 2]]);
|
|
48669
|
+
}));
|
|
48670
|
+
return function revokeWidget(_x) {
|
|
48671
|
+
return _ref2.apply(this, arguments);
|
|
48672
|
+
};
|
|
48673
|
+
}();
|
|
48674
|
+
var revokeServer = /*#__PURE__*/function () {
|
|
48675
|
+
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(widgetId, serverName) {
|
|
48676
|
+
var _window$mainApi2, _window$mainApi2$revo, _t3;
|
|
48677
|
+
return _regeneratorRuntime.wrap(function (_context3) {
|
|
48678
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
48679
|
+
case 0:
|
|
48680
|
+
_context3.prev = 0;
|
|
48681
|
+
_context3.next = 1;
|
|
48682
|
+
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);
|
|
48683
|
+
case 1:
|
|
48684
|
+
reload();
|
|
48685
|
+
_context3.next = 3;
|
|
48686
|
+
break;
|
|
48687
|
+
case 2:
|
|
48688
|
+
_context3.prev = 2;
|
|
48689
|
+
_t3 = _context3["catch"](0);
|
|
48690
|
+
setError((_t3 === null || _t3 === void 0 ? void 0 : _t3.message) || String(_t3));
|
|
48691
|
+
case 3:
|
|
48692
|
+
case "end":
|
|
48693
|
+
return _context3.stop();
|
|
48694
|
+
}
|
|
48695
|
+
}, _callee3, null, [[0, 2]]);
|
|
48696
|
+
}));
|
|
48697
|
+
return function revokeServer(_x2, _x3) {
|
|
48698
|
+
return _ref3.apply(this, arguments);
|
|
48699
|
+
};
|
|
48700
|
+
}();
|
|
48701
|
+
if (loading) {
|
|
48702
|
+
return /*#__PURE__*/jsx("div", {
|
|
48703
|
+
className: "flex flex-col p-6",
|
|
48704
|
+
children: /*#__PURE__*/jsx("span", {
|
|
48705
|
+
className: "text-sm opacity-60",
|
|
48706
|
+
children: "Loading\u2026"
|
|
48707
|
+
})
|
|
48708
|
+
});
|
|
48709
|
+
}
|
|
48710
|
+
return /*#__PURE__*/jsxs("div", {
|
|
48711
|
+
className: "flex flex-col space-y-6 p-6",
|
|
48712
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
48713
|
+
className: "flex flex-col space-y-2",
|
|
48714
|
+
children: [/*#__PURE__*/jsx(SubHeading3, {
|
|
48715
|
+
title: "Widget MCP permissions",
|
|
48716
|
+
padding: false
|
|
48717
|
+
}), /*#__PURE__*/jsx("span", {
|
|
48718
|
+
className: "text-xs opacity-60",
|
|
48719
|
+
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."
|
|
48720
|
+
})]
|
|
48721
|
+
}), error && /*#__PURE__*/jsx("div", {
|
|
48722
|
+
className: "text-xs text-red-400 bg-red-900 bg-opacity-20 border border-red-700 rounded p-3",
|
|
48723
|
+
children: error
|
|
48724
|
+
}), rows.length === 0 && /*#__PURE__*/jsx("div", {
|
|
48725
|
+
className: "text-sm opacity-60",
|
|
48726
|
+
children: "No widgets have requested MCP permissions yet."
|
|
48727
|
+
}), rows.map(function (_ref4) {
|
|
48728
|
+
var widgetId = _ref4.widgetId,
|
|
48729
|
+
declared = _ref4.declared,
|
|
48730
|
+
granted = _ref4.granted;
|
|
48731
|
+
return /*#__PURE__*/jsx(WidgetGrantRow, {
|
|
48732
|
+
widgetId: widgetId,
|
|
48733
|
+
declared: declared,
|
|
48734
|
+
granted: granted,
|
|
48735
|
+
onRevokeWidget: function onRevokeWidget() {
|
|
48736
|
+
return revokeWidget(widgetId);
|
|
48737
|
+
},
|
|
48738
|
+
onRevokeServer: function onRevokeServer(serverName) {
|
|
48739
|
+
return revokeServer(widgetId, serverName);
|
|
48740
|
+
}
|
|
48741
|
+
}, widgetId);
|
|
48742
|
+
})]
|
|
48743
|
+
});
|
|
48744
|
+
};
|
|
48745
|
+
var WidgetGrantRow = function WidgetGrantRow(_ref5) {
|
|
48746
|
+
var widgetId = _ref5.widgetId,
|
|
48747
|
+
declared = _ref5.declared,
|
|
48748
|
+
granted = _ref5.granted,
|
|
48749
|
+
onRevokeWidget = _ref5.onRevokeWidget,
|
|
48750
|
+
onRevokeServer = _ref5.onRevokeServer;
|
|
48751
|
+
var declaredServers = declared && declared.servers || {};
|
|
48752
|
+
var grantedServers = granted && granted.servers || {};
|
|
48753
|
+
var allServerNames = Array.from(new Set([].concat(_toConsumableArray(Object.keys(declaredServers)), _toConsumableArray(Object.keys(grantedServers)))));
|
|
48754
|
+
return /*#__PURE__*/jsxs("div", {
|
|
48755
|
+
className: "flex flex-col space-y-3 border border-gray-700 rounded p-3",
|
|
48756
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
48757
|
+
className: "flex flex-row items-center justify-between",
|
|
48758
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
48759
|
+
className: "text-sm font-mono break-all",
|
|
48760
|
+
children: widgetId
|
|
48761
|
+
}), Object.keys(grantedServers).length > 0 && /*#__PURE__*/jsx(Button, {
|
|
48762
|
+
title: "Revoke all",
|
|
48763
|
+
onClick: onRevokeWidget
|
|
48764
|
+
})]
|
|
48765
|
+
}), !declared && !granted && /*#__PURE__*/jsx("span", {
|
|
48766
|
+
className: "text-xs opacity-50",
|
|
48767
|
+
children: "(no manifest, no grant \u2014 should not happen)"
|
|
48768
|
+
}), allServerNames.map(function (serverName) {
|
|
48769
|
+
var decl = declaredServers[serverName] || {};
|
|
48770
|
+
var grant = grantedServers[serverName];
|
|
48771
|
+
return /*#__PURE__*/jsxs("div", {
|
|
48772
|
+
className: "flex flex-col space-y-2 border-t border-gray-800 pt-2",
|
|
48773
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
48774
|
+
className: "flex flex-row items-center justify-between",
|
|
48775
|
+
children: [/*#__PURE__*/jsxs("span", {
|
|
48776
|
+
className: "text-xs uppercase tracking-wider opacity-70",
|
|
48777
|
+
children: [serverName, !grant && /*#__PURE__*/jsx("span", {
|
|
48778
|
+
className: "ml-2 text-amber-400 normal-case tracking-normal",
|
|
48779
|
+
children: "(declared, not granted)"
|
|
48780
|
+
})]
|
|
48781
|
+
}), grant && /*#__PURE__*/jsx(Button, {
|
|
48782
|
+
title: "Revoke server",
|
|
48783
|
+
onClick: function onClick() {
|
|
48784
|
+
return onRevokeServer(serverName);
|
|
48785
|
+
}
|
|
48786
|
+
})]
|
|
48787
|
+
}), /*#__PURE__*/jsx(PermsList, {
|
|
48788
|
+
label: "Tools",
|
|
48789
|
+
declaredItems: decl.tools || [],
|
|
48790
|
+
grantedItems: (grant === null || grant === void 0 ? void 0 : grant.tools) || []
|
|
48791
|
+
}), /*#__PURE__*/jsx(PermsList, {
|
|
48792
|
+
label: "Read paths",
|
|
48793
|
+
declaredItems: decl.readPaths || [],
|
|
48794
|
+
grantedItems: (grant === null || grant === void 0 ? void 0 : grant.readPaths) || []
|
|
48795
|
+
}), /*#__PURE__*/jsx(PermsList, {
|
|
48796
|
+
label: "Write paths",
|
|
48797
|
+
declaredItems: decl.writePaths || [],
|
|
48798
|
+
grantedItems: (grant === null || grant === void 0 ? void 0 : grant.writePaths) || []
|
|
48799
|
+
})]
|
|
48800
|
+
}, serverName);
|
|
48801
|
+
})]
|
|
48802
|
+
});
|
|
48803
|
+
};
|
|
48804
|
+
var PermsList = function PermsList(_ref6) {
|
|
48805
|
+
var label = _ref6.label,
|
|
48806
|
+
declaredItems = _ref6.declaredItems,
|
|
48807
|
+
grantedItems = _ref6.grantedItems;
|
|
48808
|
+
if (declaredItems.length === 0 && grantedItems.length === 0) return null;
|
|
48809
|
+
var grantedSet = new Set(grantedItems);
|
|
48810
|
+
var declaredSet = new Set(declaredItems);
|
|
48811
|
+
var all = Array.from(new Set([].concat(_toConsumableArray(declaredItems), _toConsumableArray(grantedItems))));
|
|
48812
|
+
return /*#__PURE__*/jsxs("div", {
|
|
48813
|
+
className: "flex flex-col space-y-1",
|
|
48814
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
48815
|
+
className: "text-xs opacity-50",
|
|
48816
|
+
children: label
|
|
48817
|
+
}), all.map(function (item) {
|
|
48818
|
+
var isGranted = grantedSet.has(item);
|
|
48819
|
+
var isDeclared = declaredSet.has(item);
|
|
48820
|
+
return /*#__PURE__*/jsxs("span", {
|
|
48821
|
+
className: "text-xs font-mono break-all ".concat(isGranted ? "opacity-100" : isDeclared ? "opacity-50 line-through" : "opacity-100 text-amber-400"),
|
|
48822
|
+
children: [item, !isDeclared && isGranted && /*#__PURE__*/jsx("span", {
|
|
48823
|
+
className: "ml-2 opacity-60",
|
|
48824
|
+
children: "(no longer declared)"
|
|
48825
|
+
})]
|
|
48826
|
+
}, item);
|
|
48827
|
+
})]
|
|
48828
|
+
});
|
|
48829
|
+
};
|
|
48830
|
+
|
|
48555
48831
|
var SECTIONS = [{
|
|
48556
48832
|
key: "general",
|
|
48557
48833
|
label: "General",
|
|
@@ -48592,6 +48868,10 @@ var SECTIONS = [{
|
|
|
48592
48868
|
key: "ai-assistant",
|
|
48593
48869
|
label: "AI Assistant",
|
|
48594
48870
|
icon: "wand-magic-sparkles"
|
|
48871
|
+
}, {
|
|
48872
|
+
key: "privacy-security",
|
|
48873
|
+
label: "Privacy & Security",
|
|
48874
|
+
icon: "shield-halved"
|
|
48595
48875
|
}];
|
|
48596
48876
|
var AppSettingsModal = function AppSettingsModal(_ref) {
|
|
48597
48877
|
var isOpen = _ref.isOpen,
|
|
@@ -48779,6 +49059,9 @@ var AppSettingsModal = function AppSettingsModal(_ref) {
|
|
|
48779
49059
|
}), activeSection === "ai-assistant" && /*#__PURE__*/jsx("div", {
|
|
48780
49060
|
className: "flex-1 overflow-y-auto p-6 ".concat(panelStyles.textColor || "text-gray-200"),
|
|
48781
49061
|
children: /*#__PURE__*/jsx(AiAssistantSection, {})
|
|
49062
|
+
}), activeSection === "privacy-security" && /*#__PURE__*/jsx("div", {
|
|
49063
|
+
className: "flex-1 overflow-y-auto ".concat(panelStyles.textColor || "text-gray-200"),
|
|
49064
|
+
children: /*#__PURE__*/jsx(PrivacySecuritySection, {})
|
|
48782
49065
|
})]
|
|
48783
49066
|
}), /*#__PURE__*/jsx(SettingsModal.Footer, {
|
|
48784
49067
|
children: /*#__PURE__*/jsx("div", {
|