@trops/dash-core 0.1.492 → 0.1.494
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 +506 -175
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +588 -41
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +588 -41
- package/dist/index.js.map +1 -1
- package/package.json +118 -114
- package/scripts/scanWidgetManifestCli.js +202 -0
package/dist/index.js
CHANGED
|
@@ -48733,6 +48733,223 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
48733
48733
|
});
|
|
48734
48734
|
};
|
|
48735
48735
|
|
|
48736
|
+
var GrantManuallyModal = function GrantManuallyModal(_ref) {
|
|
48737
|
+
var isOpen = _ref.isOpen,
|
|
48738
|
+
setIsOpen = _ref.setIsOpen,
|
|
48739
|
+
widgetId = _ref.widgetId,
|
|
48740
|
+
_ref$knownServerNames = _ref.knownServerNames,
|
|
48741
|
+
knownServerNames = _ref$knownServerNames === void 0 ? [] : _ref$knownServerNames,
|
|
48742
|
+
onGranted = _ref.onGranted;
|
|
48743
|
+
var _useState = React.useState(""),
|
|
48744
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
48745
|
+
serverName = _useState2[0],
|
|
48746
|
+
setServerName = _useState2[1];
|
|
48747
|
+
var _useState3 = React.useState(""),
|
|
48748
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
48749
|
+
toolsText = _useState4[0],
|
|
48750
|
+
setToolsText = _useState4[1];
|
|
48751
|
+
var _useState5 = React.useState(""),
|
|
48752
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
48753
|
+
readPathsText = _useState6[0],
|
|
48754
|
+
setReadPathsText = _useState6[1];
|
|
48755
|
+
var _useState7 = React.useState(""),
|
|
48756
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
48757
|
+
writePathsText = _useState8[0],
|
|
48758
|
+
setWritePathsText = _useState8[1];
|
|
48759
|
+
var _useState9 = React.useState(null),
|
|
48760
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
48761
|
+
error = _useState0[0],
|
|
48762
|
+
setError = _useState0[1];
|
|
48763
|
+
var _useState1 = React.useState(false),
|
|
48764
|
+
_useState10 = _slicedToArray(_useState1, 2),
|
|
48765
|
+
isSubmitting = _useState10[0],
|
|
48766
|
+
setIsSubmitting = _useState10[1];
|
|
48767
|
+
React.useEffect(function () {
|
|
48768
|
+
if (isOpen) {
|
|
48769
|
+
setServerName("");
|
|
48770
|
+
setToolsText("");
|
|
48771
|
+
setReadPathsText("");
|
|
48772
|
+
setWritePathsText("");
|
|
48773
|
+
setError(null);
|
|
48774
|
+
setIsSubmitting(false);
|
|
48775
|
+
}
|
|
48776
|
+
}, [isOpen]);
|
|
48777
|
+
var splitLines = function splitLines(s) {
|
|
48778
|
+
return s.split(/\r?\n/).map(function (l) {
|
|
48779
|
+
return l.trim();
|
|
48780
|
+
}).filter(Boolean);
|
|
48781
|
+
};
|
|
48782
|
+
var splitCsv = function splitCsv(s) {
|
|
48783
|
+
return s.split(",").map(function (t) {
|
|
48784
|
+
return t.trim();
|
|
48785
|
+
}).filter(Boolean);
|
|
48786
|
+
};
|
|
48787
|
+
var handleGrant = /*#__PURE__*/function () {
|
|
48788
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
48789
|
+
var tools, perms, _window$mainApi, _window$mainApi$setGr, ok, _t;
|
|
48790
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
48791
|
+
while (1) switch (_context.prev = _context.next) {
|
|
48792
|
+
case 0:
|
|
48793
|
+
setError(null);
|
|
48794
|
+
if (serverName.trim()) {
|
|
48795
|
+
_context.next = 1;
|
|
48796
|
+
break;
|
|
48797
|
+
}
|
|
48798
|
+
setError("Server name is required.");
|
|
48799
|
+
return _context.abrupt("return");
|
|
48800
|
+
case 1:
|
|
48801
|
+
tools = splitCsv(toolsText);
|
|
48802
|
+
if (!(tools.length === 0)) {
|
|
48803
|
+
_context.next = 2;
|
|
48804
|
+
break;
|
|
48805
|
+
}
|
|
48806
|
+
setError("At least one tool name is required.");
|
|
48807
|
+
return _context.abrupt("return");
|
|
48808
|
+
case 2:
|
|
48809
|
+
perms = {
|
|
48810
|
+
grantOrigin: "manual",
|
|
48811
|
+
servers: _defineProperty({}, serverName.trim(), {
|
|
48812
|
+
tools: tools,
|
|
48813
|
+
readPaths: splitLines(readPathsText),
|
|
48814
|
+
writePaths: splitLines(writePathsText)
|
|
48815
|
+
})
|
|
48816
|
+
};
|
|
48817
|
+
setIsSubmitting(true);
|
|
48818
|
+
_context.prev = 3;
|
|
48819
|
+
_context.next = 4;
|
|
48820
|
+
return typeof window !== "undefined" ? (_window$mainApi = window.mainApi) === null || _window$mainApi === void 0 || (_window$mainApi = _window$mainApi.widgetMcp) === null || _window$mainApi === void 0 || (_window$mainApi$setGr = _window$mainApi.setGrant) === null || _window$mainApi$setGr === void 0 ? void 0 : _window$mainApi$setGr.call(_window$mainApi, widgetId, perms) : null;
|
|
48821
|
+
case 4:
|
|
48822
|
+
ok = _context.sent;
|
|
48823
|
+
if (!(ok === false)) {
|
|
48824
|
+
_context.next = 5;
|
|
48825
|
+
break;
|
|
48826
|
+
}
|
|
48827
|
+
setError("Could not save grant.");
|
|
48828
|
+
setIsSubmitting(false);
|
|
48829
|
+
return _context.abrupt("return");
|
|
48830
|
+
case 5:
|
|
48831
|
+
if (typeof onGranted === "function") onGranted();
|
|
48832
|
+
setIsOpen(false);
|
|
48833
|
+
_context.next = 7;
|
|
48834
|
+
break;
|
|
48835
|
+
case 6:
|
|
48836
|
+
_context.prev = 6;
|
|
48837
|
+
_t = _context["catch"](3);
|
|
48838
|
+
setError((_t === null || _t === void 0 ? void 0 : _t.message) || String(_t));
|
|
48839
|
+
setIsSubmitting(false);
|
|
48840
|
+
case 7:
|
|
48841
|
+
case "end":
|
|
48842
|
+
return _context.stop();
|
|
48843
|
+
}
|
|
48844
|
+
}, _callee, null, [[3, 6]]);
|
|
48845
|
+
}));
|
|
48846
|
+
return function handleGrant() {
|
|
48847
|
+
return _ref2.apply(this, arguments);
|
|
48848
|
+
};
|
|
48849
|
+
}();
|
|
48850
|
+
if (!widgetId) return null;
|
|
48851
|
+
return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
|
|
48852
|
+
isOpen: isOpen,
|
|
48853
|
+
setIsOpen: setIsOpen,
|
|
48854
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48855
|
+
className: "flex flex-col w-full max-w-xl ring-2 ring-amber-500",
|
|
48856
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48857
|
+
className: "px-5 py-4 border-b border-gray-700",
|
|
48858
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48859
|
+
className: "text-base font-semibold",
|
|
48860
|
+
children: ["Grant manually: ", widgetId]
|
|
48861
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48862
|
+
className: "text-xs opacity-60 mt-1",
|
|
48863
|
+
children: "This widget did not declare its MCP needs and the install-time scanner found nothing. You are granting access based on your own judgment \u2014 be conservative. Revoke any time."
|
|
48864
|
+
})]
|
|
48865
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48866
|
+
className: "flex flex-col gap-4 px-5 py-4 max-h-96 overflow-y-auto",
|
|
48867
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48868
|
+
className: "flex flex-col gap-1",
|
|
48869
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("label", {
|
|
48870
|
+
className: "text-xs uppercase tracking-wider opacity-60",
|
|
48871
|
+
children: "Server name"
|
|
48872
|
+
}), /*#__PURE__*/jsxRuntime.jsx("input", {
|
|
48873
|
+
type: "text",
|
|
48874
|
+
list: "known-mcp-servers",
|
|
48875
|
+
value: serverName,
|
|
48876
|
+
onChange: function onChange(e) {
|
|
48877
|
+
return setServerName(e.target.value);
|
|
48878
|
+
},
|
|
48879
|
+
placeholder: "e.g. filesystem, github, slack",
|
|
48880
|
+
className: "text-xs px-2 py-1.5 rounded bg-gray-800 border border-gray-700"
|
|
48881
|
+
}), /*#__PURE__*/jsxRuntime.jsx("datalist", {
|
|
48882
|
+
id: "known-mcp-servers",
|
|
48883
|
+
children: knownServerNames.map(function (n) {
|
|
48884
|
+
return /*#__PURE__*/jsxRuntime.jsx("option", {
|
|
48885
|
+
value: n
|
|
48886
|
+
}, n);
|
|
48887
|
+
})
|
|
48888
|
+
})]
|
|
48889
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48890
|
+
className: "flex flex-col gap-1",
|
|
48891
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("label", {
|
|
48892
|
+
className: "text-xs uppercase tracking-wider opacity-60",
|
|
48893
|
+
children: "Tools (comma-separated)"
|
|
48894
|
+
}), /*#__PURE__*/jsxRuntime.jsx("input", {
|
|
48895
|
+
type: "text",
|
|
48896
|
+
value: toolsText,
|
|
48897
|
+
onChange: function onChange(e) {
|
|
48898
|
+
return setToolsText(e.target.value);
|
|
48899
|
+
},
|
|
48900
|
+
placeholder: "e.g. read_file, list_directory",
|
|
48901
|
+
className: "text-xs px-2 py-1.5 rounded bg-gray-800 border border-gray-700 font-mono"
|
|
48902
|
+
})]
|
|
48903
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48904
|
+
className: "flex flex-col gap-1",
|
|
48905
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("label", {
|
|
48906
|
+
className: "text-xs uppercase tracking-wider opacity-60",
|
|
48907
|
+
children: "Read paths (one per line, optional)"
|
|
48908
|
+
}), /*#__PURE__*/jsxRuntime.jsx("textarea", {
|
|
48909
|
+
value: readPathsText,
|
|
48910
|
+
onChange: function onChange(e) {
|
|
48911
|
+
return setReadPathsText(e.target.value);
|
|
48912
|
+
},
|
|
48913
|
+
placeholder: "/Users/jane/Documents\n/tmp/notes",
|
|
48914
|
+
rows: 3,
|
|
48915
|
+
className: "text-xs px-2 py-1.5 rounded bg-gray-800 border border-gray-700 font-mono"
|
|
48916
|
+
})]
|
|
48917
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48918
|
+
className: "flex flex-col gap-1",
|
|
48919
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("label", {
|
|
48920
|
+
className: "text-xs uppercase tracking-wider opacity-60",
|
|
48921
|
+
children: "Write paths (one per line, optional)"
|
|
48922
|
+
}), /*#__PURE__*/jsxRuntime.jsx("textarea", {
|
|
48923
|
+
value: writePathsText,
|
|
48924
|
+
onChange: function onChange(e) {
|
|
48925
|
+
return setWritePathsText(e.target.value);
|
|
48926
|
+
},
|
|
48927
|
+
placeholder: "/tmp/output",
|
|
48928
|
+
rows: 3,
|
|
48929
|
+
className: "text-xs px-2 py-1.5 rounded bg-gray-800 border border-gray-700 font-mono"
|
|
48930
|
+
})]
|
|
48931
|
+
}), error && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48932
|
+
className: "text-xs text-red-400 bg-red-900 bg-opacity-20 border border-red-700 rounded px-3 py-2",
|
|
48933
|
+
children: error
|
|
48934
|
+
})]
|
|
48935
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48936
|
+
className: "flex justify-end gap-2 px-5 py-3 border-t border-gray-700",
|
|
48937
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
|
|
48938
|
+
title: "Cancel",
|
|
48939
|
+
onClick: function onClick() {
|
|
48940
|
+
return setIsOpen(false);
|
|
48941
|
+
},
|
|
48942
|
+
disabled: isSubmitting
|
|
48943
|
+
}), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
|
|
48944
|
+
title: "Grant",
|
|
48945
|
+
onClick: handleGrant,
|
|
48946
|
+
disabled: isSubmitting
|
|
48947
|
+
})]
|
|
48948
|
+
})]
|
|
48949
|
+
})
|
|
48950
|
+
});
|
|
48951
|
+
};
|
|
48952
|
+
|
|
48736
48953
|
var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
48737
48954
|
var _useState = React.useState([]),
|
|
48738
48955
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -48746,6 +48963,14 @@ var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
|
48746
48963
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
48747
48964
|
error = _useState6[0],
|
|
48748
48965
|
setError = _useState6[1];
|
|
48966
|
+
var _useState7 = React.useState(null),
|
|
48967
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
48968
|
+
manualGrantWidgetId = _useState8[0],
|
|
48969
|
+
setManualGrantWidgetId = _useState8[1];
|
|
48970
|
+
var _useState9 = React.useState([]),
|
|
48971
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
48972
|
+
knownServerNames = _useState0[0],
|
|
48973
|
+
setKnownServerNames = _useState0[1];
|
|
48749
48974
|
var reload = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
48750
48975
|
var _api$widgetMcp, api, result, _t;
|
|
48751
48976
|
return _regeneratorRuntime.wrap(function (_context) {
|
|
@@ -48786,42 +49011,55 @@ var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
|
48786
49011
|
React.useEffect(function () {
|
|
48787
49012
|
reload();
|
|
48788
49013
|
}, [reload]);
|
|
48789
|
-
|
|
48790
|
-
|
|
48791
|
-
|
|
49014
|
+
|
|
49015
|
+
// Pull catalog server names once, used as a datalist hint in the
|
|
49016
|
+
// manual-grant modal. Best-effort — if the API isn't there, the
|
|
49017
|
+
// datalist is just empty.
|
|
49018
|
+
React.useEffect(function () {
|
|
49019
|
+
var cancelled = false;
|
|
49020
|
+
_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
49021
|
+
var _api$mcp, _api$mcp$getCatalog, api, result, servers;
|
|
48792
49022
|
return _regeneratorRuntime.wrap(function (_context2) {
|
|
48793
49023
|
while (1) switch (_context2.prev = _context2.next) {
|
|
48794
49024
|
case 0:
|
|
48795
49025
|
_context2.prev = 0;
|
|
49026
|
+
api = typeof window !== "undefined" ? window.mainApi : null;
|
|
48796
49027
|
_context2.next = 1;
|
|
48797
|
-
return
|
|
49028
|
+
return api === null || api === void 0 || (_api$mcp = api.mcp) === null || _api$mcp === void 0 || (_api$mcp$getCatalog = _api$mcp.getCatalog) === null || _api$mcp$getCatalog === void 0 ? void 0 : _api$mcp$getCatalog.call(_api$mcp);
|
|
48798
49029
|
case 1:
|
|
48799
|
-
|
|
49030
|
+
result = _context2.sent;
|
|
49031
|
+
servers = (result === null || result === void 0 ? void 0 : result.catalog) || [];
|
|
49032
|
+
if (!cancelled && Array.isArray(servers)) {
|
|
49033
|
+
setKnownServerNames(servers.map(function (s) {
|
|
49034
|
+
return s === null || s === void 0 ? void 0 : s.name;
|
|
49035
|
+
}).filter(function (n) {
|
|
49036
|
+
return typeof n === "string";
|
|
49037
|
+
}));
|
|
49038
|
+
}
|
|
48800
49039
|
_context2.next = 3;
|
|
48801
49040
|
break;
|
|
48802
49041
|
case 2:
|
|
48803
49042
|
_context2.prev = 2;
|
|
48804
|
-
|
|
48805
|
-
setError((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || String(_t2));
|
|
49043
|
+
_context2["catch"](0);
|
|
48806
49044
|
case 3:
|
|
48807
49045
|
case "end":
|
|
48808
49046
|
return _context2.stop();
|
|
48809
49047
|
}
|
|
48810
49048
|
}, _callee2, null, [[0, 2]]);
|
|
48811
|
-
}));
|
|
48812
|
-
return function
|
|
48813
|
-
|
|
49049
|
+
}))();
|
|
49050
|
+
return function () {
|
|
49051
|
+
cancelled = true;
|
|
48814
49052
|
};
|
|
48815
|
-
}
|
|
48816
|
-
var
|
|
48817
|
-
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(widgetId
|
|
48818
|
-
var _window$
|
|
49053
|
+
}, []);
|
|
49054
|
+
var revokeWidget = /*#__PURE__*/function () {
|
|
49055
|
+
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(widgetId) {
|
|
49056
|
+
var _window$mainApi, _window$mainApi$revok, _t3;
|
|
48819
49057
|
return _regeneratorRuntime.wrap(function (_context3) {
|
|
48820
49058
|
while (1) switch (_context3.prev = _context3.next) {
|
|
48821
49059
|
case 0:
|
|
48822
49060
|
_context3.prev = 0;
|
|
48823
49061
|
_context3.next = 1;
|
|
48824
|
-
return (_window$
|
|
49062
|
+
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);
|
|
48825
49063
|
case 1:
|
|
48826
49064
|
reload();
|
|
48827
49065
|
_context3.next = 3;
|
|
@@ -48836,10 +49074,37 @@ var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
|
48836
49074
|
}
|
|
48837
49075
|
}, _callee3, null, [[0, 2]]);
|
|
48838
49076
|
}));
|
|
48839
|
-
return function
|
|
49077
|
+
return function revokeWidget(_x) {
|
|
48840
49078
|
return _ref3.apply(this, arguments);
|
|
48841
49079
|
};
|
|
48842
49080
|
}();
|
|
49081
|
+
var revokeServer = /*#__PURE__*/function () {
|
|
49082
|
+
var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(widgetId, serverName) {
|
|
49083
|
+
var _window$mainApi2, _window$mainApi2$revo, _t4;
|
|
49084
|
+
return _regeneratorRuntime.wrap(function (_context4) {
|
|
49085
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
49086
|
+
case 0:
|
|
49087
|
+
_context4.prev = 0;
|
|
49088
|
+
_context4.next = 1;
|
|
49089
|
+
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);
|
|
49090
|
+
case 1:
|
|
49091
|
+
reload();
|
|
49092
|
+
_context4.next = 3;
|
|
49093
|
+
break;
|
|
49094
|
+
case 2:
|
|
49095
|
+
_context4.prev = 2;
|
|
49096
|
+
_t4 = _context4["catch"](0);
|
|
49097
|
+
setError((_t4 === null || _t4 === void 0 ? void 0 : _t4.message) || String(_t4));
|
|
49098
|
+
case 3:
|
|
49099
|
+
case "end":
|
|
49100
|
+
return _context4.stop();
|
|
49101
|
+
}
|
|
49102
|
+
}, _callee4, null, [[0, 2]]);
|
|
49103
|
+
}));
|
|
49104
|
+
return function revokeServer(_x2, _x3) {
|
|
49105
|
+
return _ref4.apply(this, arguments);
|
|
49106
|
+
};
|
|
49107
|
+
}();
|
|
48843
49108
|
if (loading) {
|
|
48844
49109
|
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48845
49110
|
className: "flex flex-col p-6",
|
|
@@ -48858,55 +49123,90 @@ var PrivacySecuritySection = function PrivacySecuritySection() {
|
|
|
48858
49123
|
padding: false
|
|
48859
49124
|
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48860
49125
|
className: "text-xs opacity-60",
|
|
48861
|
-
children: "
|
|
49126
|
+
children: "Granting access here is a trust signal about the widget \u2014 not a per-dashboard switch."
|
|
48862
49127
|
})]
|
|
48863
|
-
}), error && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
49128
|
+
}), /*#__PURE__*/jsxRuntime.jsx(HowThisWorksPanel, {}), error && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48864
49129
|
className: "text-xs text-red-400 bg-red-900 bg-opacity-20 border border-red-700 rounded p-3",
|
|
48865
49130
|
children: error
|
|
48866
49131
|
}), rows.length === 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
48867
49132
|
className: "text-sm opacity-60",
|
|
48868
|
-
children: "No widgets
|
|
48869
|
-
}), rows.map(function (
|
|
48870
|
-
var widgetId =
|
|
48871
|
-
declared =
|
|
48872
|
-
granted =
|
|
49133
|
+
children: "No widgets installed."
|
|
49134
|
+
}), rows.map(function (_ref5) {
|
|
49135
|
+
var widgetId = _ref5.widgetId,
|
|
49136
|
+
declared = _ref5.declared,
|
|
49137
|
+
granted = _ref5.granted,
|
|
49138
|
+
hasManifest = _ref5.hasManifest,
|
|
49139
|
+
grantOrigin = _ref5.grantOrigin;
|
|
48873
49140
|
return /*#__PURE__*/jsxRuntime.jsx(WidgetGrantRow, {
|
|
48874
49141
|
widgetId: widgetId,
|
|
48875
49142
|
declared: declared,
|
|
48876
49143
|
granted: granted,
|
|
49144
|
+
hasManifest: hasManifest,
|
|
49145
|
+
grantOrigin: grantOrigin,
|
|
48877
49146
|
onRevokeWidget: function onRevokeWidget() {
|
|
48878
49147
|
return revokeWidget(widgetId);
|
|
48879
49148
|
},
|
|
48880
49149
|
onRevokeServer: function onRevokeServer(serverName) {
|
|
48881
49150
|
return revokeServer(widgetId, serverName);
|
|
49151
|
+
},
|
|
49152
|
+
onGrantManually: function onGrantManually() {
|
|
49153
|
+
return setManualGrantWidgetId(widgetId);
|
|
48882
49154
|
}
|
|
48883
49155
|
}, widgetId);
|
|
49156
|
+
}), /*#__PURE__*/jsxRuntime.jsx(GrantManuallyModal, {
|
|
49157
|
+
isOpen: !!manualGrantWidgetId,
|
|
49158
|
+
setIsOpen: function setIsOpen(open) {
|
|
49159
|
+
if (!open) setManualGrantWidgetId(null);
|
|
49160
|
+
},
|
|
49161
|
+
widgetId: manualGrantWidgetId,
|
|
49162
|
+
knownServerNames: knownServerNames,
|
|
49163
|
+
onGranted: function onGranted() {
|
|
49164
|
+
setManualGrantWidgetId(null);
|
|
49165
|
+
reload();
|
|
49166
|
+
}
|
|
48884
49167
|
})]
|
|
48885
49168
|
});
|
|
48886
49169
|
};
|
|
48887
|
-
var WidgetGrantRow = function WidgetGrantRow(
|
|
48888
|
-
var widgetId =
|
|
48889
|
-
declared =
|
|
48890
|
-
granted =
|
|
48891
|
-
|
|
48892
|
-
|
|
49170
|
+
var WidgetGrantRow = function WidgetGrantRow(_ref6) {
|
|
49171
|
+
var widgetId = _ref6.widgetId,
|
|
49172
|
+
declared = _ref6.declared,
|
|
49173
|
+
granted = _ref6.granted,
|
|
49174
|
+
hasManifest = _ref6.hasManifest,
|
|
49175
|
+
grantOrigin = _ref6.grantOrigin,
|
|
49176
|
+
onRevokeWidget = _ref6.onRevokeWidget,
|
|
49177
|
+
onRevokeServer = _ref6.onRevokeServer,
|
|
49178
|
+
onGrantManually = _ref6.onGrantManually;
|
|
48893
49179
|
var declaredServers = declared && declared.servers || {};
|
|
48894
49180
|
var grantedServers = granted && granted.servers || {};
|
|
48895
49181
|
var allServerNames = Array.from(new Set([].concat(_toConsumableArray(Object.keys(declaredServers)), _toConsumableArray(Object.keys(grantedServers)))));
|
|
48896
49182
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48897
49183
|
className: "flex flex-col space-y-3 border border-gray-700 rounded p-3",
|
|
48898
49184
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
48899
|
-
className: "flex flex-row items-center justify-between",
|
|
48900
|
-
children: [/*#__PURE__*/jsxRuntime.
|
|
48901
|
-
className: "
|
|
48902
|
-
children:
|
|
48903
|
-
|
|
48904
|
-
|
|
48905
|
-
|
|
49185
|
+
className: "flex flex-row items-center justify-between gap-2",
|
|
49186
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49187
|
+
className: "flex flex-row items-center gap-2 min-w-0",
|
|
49188
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49189
|
+
className: "text-sm font-mono break-all",
|
|
49190
|
+
children: widgetId
|
|
49191
|
+
}), grantOrigin && /*#__PURE__*/jsxRuntime.jsx(GrantOriginBadge, {
|
|
49192
|
+
origin: grantOrigin
|
|
49193
|
+
}), !hasManifest && !granted && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49194
|
+
className: "text-xs uppercase tracking-wider text-amber-400",
|
|
49195
|
+
children: "no manifest"
|
|
49196
|
+
})]
|
|
49197
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49198
|
+
className: "flex flex-row gap-2",
|
|
49199
|
+
children: [!hasManifest && !granted && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
|
|
49200
|
+
title: "Grant manually",
|
|
49201
|
+
onClick: onGrantManually
|
|
49202
|
+
}), Object.keys(grantedServers).length > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
|
|
49203
|
+
title: "Revoke all",
|
|
49204
|
+
onClick: onRevokeWidget
|
|
49205
|
+
})]
|
|
48906
49206
|
})]
|
|
48907
49207
|
}), !declared && !granted && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
48908
49208
|
className: "text-xs opacity-50",
|
|
48909
|
-
children: "
|
|
49209
|
+
children: "This widget did not declare MCP permissions and the install-time scanner found nothing. Use Grant manually if you trust it."
|
|
48910
49210
|
}), allServerNames.map(function (serverName) {
|
|
48911
49211
|
var decl = declaredServers[serverName] || {};
|
|
48912
49212
|
var grant = grantedServers[serverName];
|
|
@@ -48943,10 +49243,10 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
|
|
|
48943
49243
|
})]
|
|
48944
49244
|
});
|
|
48945
49245
|
};
|
|
48946
|
-
var PermsList = function PermsList(
|
|
48947
|
-
var label =
|
|
48948
|
-
declaredItems =
|
|
48949
|
-
grantedItems =
|
|
49246
|
+
var PermsList = function PermsList(_ref7) {
|
|
49247
|
+
var label = _ref7.label,
|
|
49248
|
+
declaredItems = _ref7.declaredItems,
|
|
49249
|
+
grantedItems = _ref7.grantedItems;
|
|
48950
49250
|
if (declaredItems.length === 0 && grantedItems.length === 0) return null;
|
|
48951
49251
|
var grantedSet = new Set(grantedItems);
|
|
48952
49252
|
var declaredSet = new Set(declaredItems);
|
|
@@ -48970,6 +49270,253 @@ var PermsList = function PermsList(_ref6) {
|
|
|
48970
49270
|
});
|
|
48971
49271
|
};
|
|
48972
49272
|
|
|
49273
|
+
/**
|
|
49274
|
+
* Renders a small badge showing how the user got to this grant. Helps
|
|
49275
|
+
* the user audit grants that were approved against a scanner guess
|
|
49276
|
+
* rather than the developer's explicit declaration.
|
|
49277
|
+
*/
|
|
49278
|
+
var GrantOriginBadge = function GrantOriginBadge(_ref8) {
|
|
49279
|
+
var origin = _ref8.origin;
|
|
49280
|
+
var styles = {
|
|
49281
|
+
declared: {
|
|
49282
|
+
label: "declared",
|
|
49283
|
+
color: "text-green-400"
|
|
49284
|
+
},
|
|
49285
|
+
discovered: {
|
|
49286
|
+
label: "discovered",
|
|
49287
|
+
color: "text-amber-400"
|
|
49288
|
+
},
|
|
49289
|
+
manual: {
|
|
49290
|
+
label: "manual",
|
|
49291
|
+
color: "text-blue-400"
|
|
49292
|
+
}
|
|
49293
|
+
};
|
|
49294
|
+
var style = styles[origin];
|
|
49295
|
+
if (!style) return null;
|
|
49296
|
+
return /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49297
|
+
className: "text-xs uppercase tracking-wider ".concat(style.color),
|
|
49298
|
+
title: "Origin: ".concat(origin),
|
|
49299
|
+
children: style.label
|
|
49300
|
+
});
|
|
49301
|
+
};
|
|
49302
|
+
|
|
49303
|
+
// Mock fixtures for the "Example rows" section. These use the same
|
|
49304
|
+
// WidgetGrantRow component the real rows use, so the preview always
|
|
49305
|
+
// reflects the real rendering. Click handlers are no-ops — the panel is
|
|
49306
|
+
// for visualization only.
|
|
49307
|
+
var EXAMPLE_FIXTURES = [{
|
|
49308
|
+
caption: "Declared by the developer and granted by the user.",
|
|
49309
|
+
widgetId: "@example/notes-summarizer",
|
|
49310
|
+
hasManifest: true,
|
|
49311
|
+
grantOrigin: "declared",
|
|
49312
|
+
declared: {
|
|
49313
|
+
servers: {
|
|
49314
|
+
filesystem: {
|
|
49315
|
+
tools: ["read_file", "list_directory"],
|
|
49316
|
+
readPaths: ["~/Documents/notes"],
|
|
49317
|
+
writePaths: []
|
|
49318
|
+
}
|
|
49319
|
+
}
|
|
49320
|
+
},
|
|
49321
|
+
granted: {
|
|
49322
|
+
grantOrigin: "declared",
|
|
49323
|
+
servers: {
|
|
49324
|
+
filesystem: {
|
|
49325
|
+
tools: ["read_file", "list_directory"],
|
|
49326
|
+
readPaths: ["~/Documents/notes"],
|
|
49327
|
+
writePaths: []
|
|
49328
|
+
}
|
|
49329
|
+
}
|
|
49330
|
+
}
|
|
49331
|
+
}, {
|
|
49332
|
+
caption: "Declared by the developer — the user hasn't decided yet.",
|
|
49333
|
+
widgetId: "@example/code-search",
|
|
49334
|
+
hasManifest: true,
|
|
49335
|
+
grantOrigin: null,
|
|
49336
|
+
declared: {
|
|
49337
|
+
servers: {
|
|
49338
|
+
github: {
|
|
49339
|
+
tools: ["search_repositories", "get_file_contents"]
|
|
49340
|
+
}
|
|
49341
|
+
}
|
|
49342
|
+
},
|
|
49343
|
+
granted: null
|
|
49344
|
+
}, {
|
|
49345
|
+
caption: "Detected by the install-time scanner and granted.",
|
|
49346
|
+
widgetId: "@example/file-helper",
|
|
49347
|
+
hasManifest: false,
|
|
49348
|
+
grantOrigin: "discovered",
|
|
49349
|
+
declared: null,
|
|
49350
|
+
granted: {
|
|
49351
|
+
grantOrigin: "discovered",
|
|
49352
|
+
servers: {
|
|
49353
|
+
filesystem: {
|
|
49354
|
+
tools: ["read_file"],
|
|
49355
|
+
readPaths: [],
|
|
49356
|
+
writePaths: []
|
|
49357
|
+
}
|
|
49358
|
+
}
|
|
49359
|
+
}
|
|
49360
|
+
}, {
|
|
49361
|
+
caption: "Granted manually because the widget had no manifest.",
|
|
49362
|
+
widgetId: "@example/legacy-widget",
|
|
49363
|
+
hasManifest: false,
|
|
49364
|
+
grantOrigin: "manual",
|
|
49365
|
+
declared: null,
|
|
49366
|
+
granted: {
|
|
49367
|
+
grantOrigin: "manual",
|
|
49368
|
+
servers: {
|
|
49369
|
+
filesystem: {
|
|
49370
|
+
tools: ["read_file", "write_file"],
|
|
49371
|
+
readPaths: ["~/Downloads"],
|
|
49372
|
+
writePaths: ["/tmp/widget-output"]
|
|
49373
|
+
}
|
|
49374
|
+
}
|
|
49375
|
+
}
|
|
49376
|
+
}];
|
|
49377
|
+
var noop = function noop() {};
|
|
49378
|
+
|
|
49379
|
+
/**
|
|
49380
|
+
* Collapsible explainer that documents how grants flow per-widget vs
|
|
49381
|
+
* per-dashboard, with a concrete example table and rendered preview rows
|
|
49382
|
+
* for each grant state. Default-collapsed so users who don't care never
|
|
49383
|
+
* see it.
|
|
49384
|
+
*/
|
|
49385
|
+
var HowThisWorksPanel = function HowThisWorksPanel() {
|
|
49386
|
+
var _useState1 = React.useState(false),
|
|
49387
|
+
_useState10 = _slicedToArray(_useState1, 2),
|
|
49388
|
+
open = _useState10[0],
|
|
49389
|
+
setOpen = _useState10[1];
|
|
49390
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49391
|
+
className: "border border-gray-700 rounded",
|
|
49392
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("button", {
|
|
49393
|
+
type: "button",
|
|
49394
|
+
onClick: function onClick() {
|
|
49395
|
+
return setOpen(function (v) {
|
|
49396
|
+
return !v;
|
|
49397
|
+
});
|
|
49398
|
+
},
|
|
49399
|
+
className: "w-full flex flex-row items-center justify-between px-3 py-2 text-left text-sm hover:bg-gray-800",
|
|
49400
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49401
|
+
children: "How widget MCP permissions work"
|
|
49402
|
+
}), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
|
|
49403
|
+
icon: open ? "chevron-up" : "chevron-down",
|
|
49404
|
+
className: "h-3 w-3 opacity-60"
|
|
49405
|
+
})]
|
|
49406
|
+
}), open && /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49407
|
+
className: "flex flex-col space-y-4 px-3 py-3 border-t border-gray-800 text-xs leading-relaxed",
|
|
49408
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49409
|
+
className: "space-y-2",
|
|
49410
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("p", {
|
|
49411
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49412
|
+
className: "font-semibold",
|
|
49413
|
+
children: "The grant is about the widget, not the dashboard."
|
|
49414
|
+
}), " ", "When you grant ", /*#__PURE__*/jsxRuntime.jsx("code", {
|
|
49415
|
+
children: "@trops/notes-summarizer"
|
|
49416
|
+
}), " access to", " ", /*#__PURE__*/jsxRuntime.jsx("code", {
|
|
49417
|
+
children: "~/Documents"
|
|
49418
|
+
}), ", you're saying \"I trust this widget with this path, anywhere.\" Grants live one-per-widget, regardless of how many dashboards use it."]
|
|
49419
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("p", {
|
|
49420
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49421
|
+
className: "font-semibold",
|
|
49422
|
+
children: "Each dashboard automatically scopes its servers."
|
|
49423
|
+
}), " ", "When you open a dashboard, Dash spawns a separate MCP server process per dashboard. That server is configured with only the paths granted to widgets actually on that dashboard \u2014 nothing else. Two dashboards using the same widget share the same grant; two dashboards using different widgets get different effective scopes."]
|
|
49424
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("p", {
|
|
49425
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
49426
|
+
className: "font-semibold",
|
|
49427
|
+
children: "What this doesn't do."
|
|
49428
|
+
}), " ", "There's no way today to say \"this widget can use filesystem on Dashboard 1 but not Dashboard 2.\" Grants are per-widget; per-(widget, dashboard) granularity would need a bigger UX rework. If you don't want a widget to access a path on a particular dashboard, the workaround is to remove it from that dashboard or revoke the grant entirely."]
|
|
49429
|
+
})]
|
|
49430
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49431
|
+
className: "space-y-2",
|
|
49432
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49433
|
+
className: "font-semibold",
|
|
49434
|
+
children: ["Example: widget A granted ", /*#__PURE__*/jsxRuntime.jsx("code", {
|
|
49435
|
+
children: "/Documents"
|
|
49436
|
+
}), ", widget B granted ", /*#__PURE__*/jsxRuntime.jsx("code", {
|
|
49437
|
+
children: "/Code"
|
|
49438
|
+
})]
|
|
49439
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("table", {
|
|
49440
|
+
className: "w-full text-xs border border-gray-800",
|
|
49441
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("thead", {
|
|
49442
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("tr", {
|
|
49443
|
+
className: "bg-gray-900",
|
|
49444
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("th", {
|
|
49445
|
+
className: "text-left px-2 py-1 border-b border-gray-800",
|
|
49446
|
+
children: "Scenario"
|
|
49447
|
+
}), /*#__PURE__*/jsxRuntime.jsx("th", {
|
|
49448
|
+
className: "text-left px-2 py-1 border-b border-gray-800",
|
|
49449
|
+
children: "Dashboard 1 sees"
|
|
49450
|
+
}), /*#__PURE__*/jsxRuntime.jsx("th", {
|
|
49451
|
+
className: "text-left px-2 py-1 border-b border-gray-800",
|
|
49452
|
+
children: "Dashboard 2 sees"
|
|
49453
|
+
})]
|
|
49454
|
+
})
|
|
49455
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("tbody", {
|
|
49456
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("tr", {
|
|
49457
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49458
|
+
className: "px-2 py-1 border-b border-gray-800",
|
|
49459
|
+
children: "A on Dash 1, B on Dash 2"
|
|
49460
|
+
}), /*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49461
|
+
className: "px-2 py-1 border-b border-gray-800 font-mono",
|
|
49462
|
+
children: "/Documents"
|
|
49463
|
+
}), /*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49464
|
+
className: "px-2 py-1 border-b border-gray-800 font-mono",
|
|
49465
|
+
children: "/Code"
|
|
49466
|
+
})]
|
|
49467
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("tr", {
|
|
49468
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49469
|
+
className: "px-2 py-1 border-b border-gray-800",
|
|
49470
|
+
children: "A on both, B on Dash 2"
|
|
49471
|
+
}), /*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49472
|
+
className: "px-2 py-1 border-b border-gray-800 font-mono",
|
|
49473
|
+
children: "/Documents"
|
|
49474
|
+
}), /*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49475
|
+
className: "px-2 py-1 border-b border-gray-800 font-mono",
|
|
49476
|
+
children: "/Documents, /Code"
|
|
49477
|
+
})]
|
|
49478
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("tr", {
|
|
49479
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49480
|
+
className: "px-2 py-1",
|
|
49481
|
+
children: "A + B both on Dash 1"
|
|
49482
|
+
}), /*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49483
|
+
className: "px-2 py-1 font-mono",
|
|
49484
|
+
children: "/Documents, /Code"
|
|
49485
|
+
}), /*#__PURE__*/jsxRuntime.jsx("td", {
|
|
49486
|
+
className: "px-2 py-1 opacity-60",
|
|
49487
|
+
children: "(no server)"
|
|
49488
|
+
})]
|
|
49489
|
+
})]
|
|
49490
|
+
})]
|
|
49491
|
+
})]
|
|
49492
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49493
|
+
className: "space-y-3",
|
|
49494
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
49495
|
+
className: "font-semibold",
|
|
49496
|
+
children: "What each row state looks like"
|
|
49497
|
+
}), EXAMPLE_FIXTURES.map(function (f) {
|
|
49498
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
49499
|
+
className: "space-y-1",
|
|
49500
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
49501
|
+
className: "italic opacity-60",
|
|
49502
|
+
children: f.caption
|
|
49503
|
+
}), /*#__PURE__*/jsxRuntime.jsx(WidgetGrantRow, {
|
|
49504
|
+
widgetId: f.widgetId,
|
|
49505
|
+
declared: f.declared,
|
|
49506
|
+
granted: f.granted,
|
|
49507
|
+
hasManifest: f.hasManifest,
|
|
49508
|
+
grantOrigin: f.grantOrigin,
|
|
49509
|
+
onRevokeWidget: noop,
|
|
49510
|
+
onRevokeServer: noop,
|
|
49511
|
+
onGrantManually: noop
|
|
49512
|
+
})]
|
|
49513
|
+
}, f.widgetId);
|
|
49514
|
+
})]
|
|
49515
|
+
})]
|
|
49516
|
+
})]
|
|
49517
|
+
});
|
|
49518
|
+
};
|
|
49519
|
+
|
|
48973
49520
|
var SECTIONS = [{
|
|
48974
49521
|
key: "general",
|
|
48975
49522
|
label: "General",
|