@trops/dash-core 0.1.638 → 0.1.640
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 +232 -21
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +597 -313
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +597 -313
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -983,6 +983,8 @@ const BOTS_PAUSE_BOT$1 = "bots-pause-bot";
|
|
|
983
983
|
const BOTS_RESUME_BOT$1 = "bots-resume-bot";
|
|
984
984
|
const BOTS_GET_PAUSE_STATE$1 = "bots-get-pause-state";
|
|
985
985
|
const BOTS_LIST_TOOL_SOURCES$1 = "bots-list-tool-sources";
|
|
986
|
+
const BOTS_GET_GRANTS$1 = "bots-get-grants";
|
|
987
|
+
const BOTS_REVOKE_GRANT$1 = "bots-revoke-grant";
|
|
986
988
|
|
|
987
989
|
// --- Main → Renderer (send) ---
|
|
988
990
|
const BOT_STREAM$2 = "bot-stream"; // { botId, event: BotEvent }
|
|
@@ -1010,6 +1012,8 @@ var botEvents$1 = {
|
|
|
1010
1012
|
BOTS_RESUME_BOT: BOTS_RESUME_BOT$1,
|
|
1011
1013
|
BOTS_GET_PAUSE_STATE: BOTS_GET_PAUSE_STATE$1,
|
|
1012
1014
|
BOTS_LIST_TOOL_SOURCES: BOTS_LIST_TOOL_SOURCES$1,
|
|
1015
|
+
BOTS_GET_GRANTS: BOTS_GET_GRANTS$1,
|
|
1016
|
+
BOTS_REVOKE_GRANT: BOTS_REVOKE_GRANT$1,
|
|
1013
1017
|
BOT_STREAM: BOT_STREAM$2,
|
|
1014
1018
|
BOT_APPROVAL_PENDING: BOT_APPROVAL_PENDING$2,
|
|
1015
1019
|
BOT_BUDGET_ALERT: BOT_BUDGET_ALERT$2,
|
|
@@ -19492,7 +19496,7 @@ util$E.isObject = isObject;
|
|
|
19492
19496
|
util$E.isPlainObject = isPlainObject;
|
|
19493
19497
|
util$E.numKeys = numKeys;
|
|
19494
19498
|
util$E.escapeRegex = escapeRegex;
|
|
19495
|
-
util$E.clone = clone;
|
|
19499
|
+
util$E.clone = clone$1;
|
|
19496
19500
|
util$E.normalizeParams = normalizeParams;
|
|
19497
19501
|
util$E.createTransparentProxy = createTransparentProxy;
|
|
19498
19502
|
util$E.stringifyPrimitive = stringifyPrimitive;
|
|
@@ -19715,7 +19719,7 @@ function escapeRegex(str) {
|
|
|
19715
19719
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
19716
19720
|
}
|
|
19717
19721
|
// zod-specific utils
|
|
19718
|
-
function clone(inst, def, params) {
|
|
19722
|
+
function clone$1(inst, def, params) {
|
|
19719
19723
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
19720
19724
|
if (!def || params?.parent)
|
|
19721
19725
|
cl._zod.parent = inst;
|
|
@@ -19805,7 +19809,7 @@ function pick$1(schema, mask) {
|
|
|
19805
19809
|
// pick key
|
|
19806
19810
|
newShape[key] = currDef.shape[key];
|
|
19807
19811
|
}
|
|
19808
|
-
return clone(schema, {
|
|
19812
|
+
return clone$1(schema, {
|
|
19809
19813
|
...schema._zod.def,
|
|
19810
19814
|
shape: newShape,
|
|
19811
19815
|
checks: [],
|
|
@@ -19822,7 +19826,7 @@ function omit(schema, mask) {
|
|
|
19822
19826
|
continue;
|
|
19823
19827
|
delete newShape[key];
|
|
19824
19828
|
}
|
|
19825
|
-
return clone(schema, {
|
|
19829
|
+
return clone$1(schema, {
|
|
19826
19830
|
...schema._zod.def,
|
|
19827
19831
|
shape: newShape,
|
|
19828
19832
|
checks: [],
|
|
@@ -19841,10 +19845,10 @@ function extend(schema, shape) {
|
|
|
19841
19845
|
},
|
|
19842
19846
|
checks: [], // delete existing checks
|
|
19843
19847
|
};
|
|
19844
|
-
return clone(schema, def);
|
|
19848
|
+
return clone$1(schema, def);
|
|
19845
19849
|
}
|
|
19846
19850
|
function merge(a, b) {
|
|
19847
|
-
return clone(a, {
|
|
19851
|
+
return clone$1(a, {
|
|
19848
19852
|
...a._zod.def,
|
|
19849
19853
|
get shape() {
|
|
19850
19854
|
const _shape = { ...a._zod.def.shape, ...b._zod.def.shape };
|
|
@@ -19885,7 +19889,7 @@ function partial(Class, schema, mask) {
|
|
|
19885
19889
|
: oldShape[key];
|
|
19886
19890
|
}
|
|
19887
19891
|
}
|
|
19888
|
-
return clone(schema, {
|
|
19892
|
+
return clone$1(schema, {
|
|
19889
19893
|
...schema._zod.def,
|
|
19890
19894
|
shape,
|
|
19891
19895
|
checks: [],
|
|
@@ -19917,7 +19921,7 @@ function required$3(Class, schema, mask) {
|
|
|
19917
19921
|
});
|
|
19918
19922
|
}
|
|
19919
19923
|
}
|
|
19920
|
-
return clone(schema, {
|
|
19924
|
+
return clone$1(schema, {
|
|
19921
19925
|
...schema._zod.def,
|
|
19922
19926
|
shape,
|
|
19923
19927
|
// optional: [],
|
|
@@ -36674,7 +36678,7 @@ function _resolveIdentity({ token, widgetId }) {
|
|
|
36674
36678
|
// Argument keys that look like paths. Different MCP servers use
|
|
36675
36679
|
// different conventions; this list covers the common filesystem-style
|
|
36676
36680
|
// servers. Extensible — add as new patterns surface.
|
|
36677
|
-
const PATH_ARG_KEYS = ["path", "uri", "filepath", "file", "directory"];
|
|
36681
|
+
const PATH_ARG_KEYS$1 = ["path", "uri", "filepath", "file", "directory"];
|
|
36678
36682
|
|
|
36679
36683
|
// Heuristic: tool names matching this regex are treated as writes for
|
|
36680
36684
|
// purposes of choosing readPaths vs writePaths. The match is intentionally
|
|
@@ -36683,7 +36687,7 @@ const PATH_ARG_KEYS = ["path", "uri", "filepath", "file", "directory"];
|
|
|
36683
36687
|
const WRITE_TOOL_PATTERN =
|
|
36684
36688
|
/(^|_)(write|create|edit|delete|remove|append|move|rename|chmod|chown|mkdir)/i;
|
|
36685
36689
|
|
|
36686
|
-
function isWriteTool(toolName) {
|
|
36690
|
+
function isWriteTool$1(toolName) {
|
|
36687
36691
|
if (typeof toolName !== "string") return false;
|
|
36688
36692
|
return WRITE_TOOL_PATTERN.test(toolName);
|
|
36689
36693
|
}
|
|
@@ -36757,7 +36761,7 @@ function _evaluateGrant({
|
|
|
36757
36761
|
|
|
36758
36762
|
// Path-argument containment. Only checked when the tool's args
|
|
36759
36763
|
// include a path-shaped key.
|
|
36760
|
-
const isWrite = isWriteTool(toolName);
|
|
36764
|
+
const isWrite = isWriteTool$1(toolName);
|
|
36761
36765
|
// Write tools must use writePaths; read tools may use either
|
|
36762
36766
|
// readPaths or writePaths (write access implies read access).
|
|
36763
36767
|
const allowedPaths = isWrite
|
|
@@ -36765,7 +36769,7 @@ function _evaluateGrant({
|
|
|
36765
36769
|
: [...serverPerms.readPaths, ...serverPerms.writePaths];
|
|
36766
36770
|
|
|
36767
36771
|
if (args && typeof args === "object") {
|
|
36768
|
-
for (const key of PATH_ARG_KEYS) {
|
|
36772
|
+
for (const key of PATH_ARG_KEYS$1) {
|
|
36769
36773
|
const v = args[key];
|
|
36770
36774
|
if (typeof v !== "string" || !v) continue;
|
|
36771
36775
|
if (allowedPaths.length === 0) {
|
|
@@ -37134,8 +37138,8 @@ var permissionGate = {
|
|
|
37134
37138
|
gateToolCall: gateToolCall$1,
|
|
37135
37139
|
gateBotToolCall,
|
|
37136
37140
|
gateToolCallWithJit: gateToolCallWithJit$1,
|
|
37137
|
-
isWriteTool,
|
|
37138
|
-
PATH_ARG_KEYS,
|
|
37141
|
+
isWriteTool: isWriteTool$1,
|
|
37142
|
+
PATH_ARG_KEYS: PATH_ARG_KEYS$1,
|
|
37139
37143
|
};
|
|
37140
37144
|
|
|
37141
37145
|
/**
|
|
@@ -75184,6 +75188,9 @@ var agentToolBridge = {
|
|
|
75184
75188
|
const { createEventStream } = eventStream;
|
|
75185
75189
|
const { BOT_MCP_SERVER, buildBotMcpServer } = agentToolBridge;
|
|
75186
75190
|
|
|
75191
|
+
// The SDK names bridged tools "mcp__<server>__<tool>".
|
|
75192
|
+
const BRIDGED_PREFIX = `mcp__${BOT_MCP_SERVER}__`;
|
|
75193
|
+
|
|
75187
75194
|
// Test seam: injected fake `query` implementation (see __setQueryForTest).
|
|
75188
75195
|
let _queryImpl = null;
|
|
75189
75196
|
|
|
@@ -75243,7 +75250,27 @@ function _makeCanUseTool(ctx) {
|
|
|
75243
75250
|
if (ctx.approvalPolicy === "allow") {
|
|
75244
75251
|
return { behavior: "allow", updatedInput: input };
|
|
75245
75252
|
}
|
|
75246
|
-
//
|
|
75253
|
+
// Bridged Dash provider tools go through the SAME Dash permission gate as
|
|
75254
|
+
// the tool-loop engine — grants, remembered approvals ("Always allow"),
|
|
75255
|
+
// and the approval queue all apply, keyed by the real provider.
|
|
75256
|
+
if (
|
|
75257
|
+
typeof toolName === "string" &&
|
|
75258
|
+
toolName.startsWith(BRIDGED_PREFIX) &&
|
|
75259
|
+
typeof ctx.requestPermission === "function"
|
|
75260
|
+
) {
|
|
75261
|
+
const decision = await ctx.requestPermission(
|
|
75262
|
+
toolName.slice(BRIDGED_PREFIX.length),
|
|
75263
|
+
input,
|
|
75264
|
+
);
|
|
75265
|
+
return decision && decision.allow
|
|
75266
|
+
? { behavior: "allow", updatedInput: input }
|
|
75267
|
+
: {
|
|
75268
|
+
behavior: "deny",
|
|
75269
|
+
message: (decision && decision.reason) || "not permitted",
|
|
75270
|
+
};
|
|
75271
|
+
}
|
|
75272
|
+
// Built-in tools (Bash, Write, …) ask every time via the approval queue
|
|
75273
|
+
// (shown in the Activity panel) — they're never remembered.
|
|
75247
75274
|
if (typeof ctx.createApproval !== "function") {
|
|
75248
75275
|
return { behavior: "deny", message: "no approval channel available" };
|
|
75249
75276
|
}
|
|
@@ -76422,6 +76449,19 @@ var memoryTools = { MEMORY_SERVER: MEMORY_SERVER$1, MEMORY_TOOLS: MEMORY_TOOLS$1
|
|
|
76422
76449
|
* Pure (NFR-006): no Electron, no I/O.
|
|
76423
76450
|
*/
|
|
76424
76451
|
|
|
76452
|
+
/**
|
|
76453
|
+
* Copied dashboards reuse widget ids, so one eventType can come from several
|
|
76454
|
+
* dashboards. A subscription picked in the bot form records its dashboard
|
|
76455
|
+
* (`source.workspaceId`); it then only matches events published from that
|
|
76456
|
+
* dashboard. Unstamped events and dashboard-less subscriptions still match.
|
|
76457
|
+
*/
|
|
76458
|
+
function sameDashboard(sub, event) {
|
|
76459
|
+
const want = sub.source && sub.source.workspaceId;
|
|
76460
|
+
const got = event.workspaceId;
|
|
76461
|
+
if (want == null || want === "" || got == null || got === "") return true;
|
|
76462
|
+
return String(want) === String(got);
|
|
76463
|
+
}
|
|
76464
|
+
|
|
76425
76465
|
/**
|
|
76426
76466
|
* @param {Array<object>} bots bot definitions (each may have `subscriptions`)
|
|
76427
76467
|
* @param {{ eventType: string, workspaceId?: string }} event
|
|
@@ -76436,7 +76476,9 @@ function matchSubscribedBots$1(bots, event, opts = {}) {
|
|
|
76436
76476
|
return bots.filter((bot) => {
|
|
76437
76477
|
if (!bot || bot.id === excludeBotId) return false;
|
|
76438
76478
|
const subs = Array.isArray(bot.subscriptions) ? bot.subscriptions : [];
|
|
76439
|
-
const subscribed = subs.some(
|
|
76479
|
+
const subscribed = subs.some(
|
|
76480
|
+
(s) => s && s.eventType === event.eventType && sameDashboard(s, event),
|
|
76481
|
+
);
|
|
76440
76482
|
if (!subscribed) return false;
|
|
76441
76483
|
|
|
76442
76484
|
// Workspace scoping (forward-compatible): only enforced once events carry a
|
|
@@ -76538,6 +76580,111 @@ function normalizeMcpResult$1(mcpResult) {
|
|
|
76538
76580
|
|
|
76539
76581
|
var mcpResult = { normalizeMcpResult: normalizeMcpResult$1 };
|
|
76540
76582
|
|
|
76583
|
+
/**
|
|
76584
|
+
* rememberGrant.js — turn an "Always allow" bot approval into a durable grant,
|
|
76585
|
+
* and revoke it.
|
|
76586
|
+
*
|
|
76587
|
+
* Bot grants live in the shared grant store (electron/mcp/grantedPermissions)
|
|
76588
|
+
* keyed by botId, shape `{ servers: { [provider]: { tools, readPaths,
|
|
76589
|
+
* writePaths } } }`, and are enforced by the bot permission gate
|
|
76590
|
+
* (gateBotToolCall). A remembered approval is scoped to this bot + this
|
|
76591
|
+
* provider + this tool, plus — when the tool call carries a path argument —
|
|
76592
|
+
* the folder of that path (write folder for write tools, read folder
|
|
76593
|
+
* otherwise). Nothing broader.
|
|
76594
|
+
*
|
|
76595
|
+
* Pure (NFR-006): the gate's path rules (isWriteTool, path arg keys) and
|
|
76596
|
+
* `dirname` are injected so this matches the real gate exactly.
|
|
76597
|
+
*/
|
|
76598
|
+
|
|
76599
|
+
const LISTING_TOOL = /(list|director|tree|search)/i;
|
|
76600
|
+
|
|
76601
|
+
/**
|
|
76602
|
+
* The folder to remember for a path argument: a `directory` arg, or a
|
|
76603
|
+
* directory-listing tool, names the folder itself; any other path is a file,
|
|
76604
|
+
* so its parent folder is remembered.
|
|
76605
|
+
*/
|
|
76606
|
+
function folderForPathArg(key, value, toolName, dirname) {
|
|
76607
|
+
if (key === "directory" || LISTING_TOOL.test(String(toolName || ""))) {
|
|
76608
|
+
return value;
|
|
76609
|
+
}
|
|
76610
|
+
return dirname(value);
|
|
76611
|
+
}
|
|
76612
|
+
|
|
76613
|
+
const clone = (perms) =>
|
|
76614
|
+
perms && typeof perms === "object" ? JSON.parse(JSON.stringify(perms)) : {};
|
|
76615
|
+
|
|
76616
|
+
const addUnique = (list, value) =>
|
|
76617
|
+
list.includes(value) ? list : [...list, value];
|
|
76618
|
+
|
|
76619
|
+
/**
|
|
76620
|
+
* @param {object|null} perms the bot's current grant (or null)
|
|
76621
|
+
* @param {{ serverName: string, toolName: string, args?: object }} call
|
|
76622
|
+
* @param {{ isWriteTool: Function, pathArgKeys: string[], dirname: Function }} helpers
|
|
76623
|
+
* @returns {object} the new grant (input is not mutated)
|
|
76624
|
+
*/
|
|
76625
|
+
function rememberToolGrant$1(perms, call, helpers) {
|
|
76626
|
+
const { serverName, toolName, args } = call;
|
|
76627
|
+
const next = clone(perms);
|
|
76628
|
+
next.grantOrigin = next.grantOrigin || "manual";
|
|
76629
|
+
next.servers = next.servers || {};
|
|
76630
|
+
const server = next.servers[serverName] || {
|
|
76631
|
+
tools: [],
|
|
76632
|
+
readPaths: [],
|
|
76633
|
+
writePaths: [],
|
|
76634
|
+
};
|
|
76635
|
+
server.tools = addUnique(server.tools || [], toolName);
|
|
76636
|
+
server.readPaths = server.readPaths || [];
|
|
76637
|
+
server.writePaths = server.writePaths || [];
|
|
76638
|
+
|
|
76639
|
+
if (args && typeof args === "object") {
|
|
76640
|
+
const isWrite = helpers.isWriteTool(toolName);
|
|
76641
|
+
for (const key of helpers.pathArgKeys) {
|
|
76642
|
+
const v = args[key];
|
|
76643
|
+
if (typeof v !== "string" || !v) continue;
|
|
76644
|
+
const folder = folderForPathArg(key, v, toolName, helpers.dirname);
|
|
76645
|
+
if (isWrite) server.writePaths = addUnique(server.writePaths, folder);
|
|
76646
|
+
else server.readPaths = addUnique(server.readPaths, folder);
|
|
76647
|
+
}
|
|
76648
|
+
}
|
|
76649
|
+
|
|
76650
|
+
next.servers[serverName] = server;
|
|
76651
|
+
return next;
|
|
76652
|
+
}
|
|
76653
|
+
|
|
76654
|
+
/**
|
|
76655
|
+
* Revoke one remembered tool. When it was the provider's last remembered
|
|
76656
|
+
* tool, the provider entry (and its folders) is removed entirely.
|
|
76657
|
+
*/
|
|
76658
|
+
function forgetToolGrant$1(perms, serverName, toolName) {
|
|
76659
|
+
const server = perms && perms.servers && perms.servers[serverName];
|
|
76660
|
+
if (!server || !(server.tools || []).includes(toolName)) return perms;
|
|
76661
|
+
const next = clone(perms);
|
|
76662
|
+
const tools = next.servers[serverName].tools.filter((t) => t !== toolName);
|
|
76663
|
+
if (tools.length) next.servers[serverName].tools = tools;
|
|
76664
|
+
else delete next.servers[serverName];
|
|
76665
|
+
return next;
|
|
76666
|
+
}
|
|
76667
|
+
|
|
76668
|
+
/** Remembered tools + folders per provider, for display in the bot form. */
|
|
76669
|
+
function summarizeGrants$1(perms) {
|
|
76670
|
+
const out = {};
|
|
76671
|
+
const servers = (perms && perms.servers) || {};
|
|
76672
|
+
for (const [name, s] of Object.entries(servers)) {
|
|
76673
|
+
out[name] = {
|
|
76674
|
+
tools: [...(s.tools || [])],
|
|
76675
|
+
folders: [...(s.readPaths || []), ...(s.writePaths || [])],
|
|
76676
|
+
};
|
|
76677
|
+
}
|
|
76678
|
+
return out;
|
|
76679
|
+
}
|
|
76680
|
+
|
|
76681
|
+
var rememberGrant = {
|
|
76682
|
+
rememberToolGrant: rememberToolGrant$1,
|
|
76683
|
+
forgetToolGrant: forgetToolGrant$1,
|
|
76684
|
+
summarizeGrants: summarizeGrants$1,
|
|
76685
|
+
folderForPathArg,
|
|
76686
|
+
};
|
|
76687
|
+
|
|
76541
76688
|
/**
|
|
76542
76689
|
* botController.js
|
|
76543
76690
|
*
|
|
@@ -76575,6 +76722,13 @@ const {
|
|
|
76575
76722
|
resolveBotTools,
|
|
76576
76723
|
checkToolCall,
|
|
76577
76724
|
} = toolSources;
|
|
76725
|
+
const {
|
|
76726
|
+
rememberToolGrant,
|
|
76727
|
+
forgetToolGrant,
|
|
76728
|
+
summarizeGrants,
|
|
76729
|
+
} = rememberGrant;
|
|
76730
|
+
const grantStore = grantedPermissions;
|
|
76731
|
+
const { isWriteTool, PATH_ARG_KEYS } = permissionGate;
|
|
76578
76732
|
const {
|
|
76579
76733
|
getProvider: getProvider$1,
|
|
76580
76734
|
getDefaultModel,
|
|
@@ -76802,6 +76956,8 @@ const botController$1 = {
|
|
|
76802
76956
|
|
|
76803
76957
|
delete(botId) {
|
|
76804
76958
|
this._scheduler.unregister(botId);
|
|
76959
|
+
// A deleted bot's remembered approvals go with it.
|
|
76960
|
+
grantStore.revokeGrant(botId);
|
|
76805
76961
|
return this._store.delete(botId);
|
|
76806
76962
|
},
|
|
76807
76963
|
|
|
@@ -76813,10 +76969,50 @@ const botController$1 = {
|
|
|
76813
76969
|
return { stopped: this._runner.abort(botId) };
|
|
76814
76970
|
},
|
|
76815
76971
|
|
|
76972
|
+
/**
|
|
76973
|
+
* Resolve a pending approval. `decision.remember` ("Always allow") also
|
|
76974
|
+
* saves a durable grant for this bot + provider + tool (+ the folder of a
|
|
76975
|
+
* path argument), so later runs use that tool without asking. Only provider
|
|
76976
|
+
* tool approvals can be remembered — built-in agent tools have no provider
|
|
76977
|
+
* and always ask.
|
|
76978
|
+
*/
|
|
76816
76979
|
approve(approvalId, decision = {}) {
|
|
76817
|
-
|
|
76818
|
-
|
|
76819
|
-
|
|
76980
|
+
if (!decision.allow) {
|
|
76981
|
+
return { ok: this._approvals.deny(approvalId, decision.reason) };
|
|
76982
|
+
}
|
|
76983
|
+
let remembered = false;
|
|
76984
|
+
if (decision.remember) {
|
|
76985
|
+
const pending = this._approvals.get(approvalId);
|
|
76986
|
+
const req = pending && pending.request;
|
|
76987
|
+
if (req && req.botId && req.serverName && req.toolName) {
|
|
76988
|
+
const next = rememberToolGrant(
|
|
76989
|
+
grantStore.getGrant(req.botId),
|
|
76990
|
+
{
|
|
76991
|
+
serverName: req.serverName,
|
|
76992
|
+
toolName: req.toolName,
|
|
76993
|
+
args: req.input,
|
|
76994
|
+
},
|
|
76995
|
+
{ isWriteTool, pathArgKeys: PATH_ARG_KEYS, dirname: path$2.dirname },
|
|
76996
|
+
);
|
|
76997
|
+
remembered = grantStore.setGrant(req.botId, next) === true;
|
|
76998
|
+
}
|
|
76999
|
+
}
|
|
77000
|
+
return { ok: this._approvals.resolve(approvalId, decision), remembered };
|
|
77001
|
+
},
|
|
77002
|
+
|
|
77003
|
+
/** Remembered approvals for a bot: { [provider]: { tools, folders } }. */
|
|
77004
|
+
getGrants(botId) {
|
|
77005
|
+
return summarizeGrants(grantStore.getGrant(botId));
|
|
77006
|
+
},
|
|
77007
|
+
|
|
77008
|
+
/** Revoke one remembered tool approval; returns the updated summary. */
|
|
77009
|
+
revokeGrant(botId, serverName, toolName) {
|
|
77010
|
+
const current = grantStore.getGrant(botId);
|
|
77011
|
+
if (current) {
|
|
77012
|
+
const next = forgetToolGrant(current, serverName, toolName);
|
|
77013
|
+
if (next !== current) grantStore.setGrant(botId, next);
|
|
77014
|
+
}
|
|
77015
|
+
return this.getGrants(botId);
|
|
76820
77016
|
},
|
|
76821
77017
|
|
|
76822
77018
|
listApprovals() {
|
|
@@ -80985,6 +81181,8 @@ const {
|
|
|
80985
81181
|
BOTS_RESUME_BOT,
|
|
80986
81182
|
BOTS_GET_PAUSE_STATE,
|
|
80987
81183
|
BOTS_LIST_TOOL_SOURCES,
|
|
81184
|
+
BOTS_GET_GRANTS,
|
|
81185
|
+
BOTS_REVOKE_GRANT,
|
|
80988
81186
|
BOT_STREAM,
|
|
80989
81187
|
BOT_APPROVAL_PENDING,
|
|
80990
81188
|
BOT_BUDGET_ALERT,
|
|
@@ -81037,6 +81235,12 @@ const botApi$1 = {
|
|
|
81037
81235
|
listToolSources: (workspaceId = null) =>
|
|
81038
81236
|
ipcRenderer$3.invoke(BOTS_LIST_TOOL_SOURCES, { workspaceId }),
|
|
81039
81237
|
|
|
81238
|
+
/** Remembered approvals ("Always allow"): { [provider]: { tools, folders } }. */
|
|
81239
|
+
getGrants: (botId) => ipcRenderer$3.invoke(BOTS_GET_GRANTS, { botId }),
|
|
81240
|
+
/** Revoke one remembered tool approval; resolves to the updated summary. */
|
|
81241
|
+
revokeGrant: (botId, serverName, toolName) =>
|
|
81242
|
+
ipcRenderer$3.invoke(BOTS_REVOKE_GRANT, { botId, serverName, toolName }),
|
|
81243
|
+
|
|
81040
81244
|
/** Subscribe to streamed run events: { botId, event }. */
|
|
81041
81245
|
onStream: (callback) => _addListener(BOT_STREAM, callback),
|
|
81042
81246
|
/** Subscribe to new pending approvals: { id, request }. */
|
|
@@ -82391,8 +82595,15 @@ function createMainApi$1(extensions = {}) {
|
|
|
82391
82595
|
mcpDashServer: mcpDashServerApi$1,
|
|
82392
82596
|
|
|
82393
82597
|
widgetEvent: {
|
|
82394
|
-
|
|
82395
|
-
|
|
82598
|
+
// meta.workspaceId = the publishing dashboard (bot subscriptions use it).
|
|
82599
|
+
publish: (eventType, content, meta) => {
|
|
82600
|
+
const workspaceId = meta && meta.workspaceId;
|
|
82601
|
+
ipcRenderer.send(
|
|
82602
|
+
"widget-event:publish",
|
|
82603
|
+
workspaceId
|
|
82604
|
+
? { eventType, content, workspaceId }
|
|
82605
|
+
: { eventType, content },
|
|
82606
|
+
);
|
|
82396
82607
|
},
|
|
82397
82608
|
getLastEvents: () => ipcRenderer.invoke("widget-event:get-last-events"),
|
|
82398
82609
|
},
|