@aliceshimada/mica 1.1.0 → 1.1.1
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/CHANGELOG.md +6 -0
- package/dist/src/bun/httpServer.js +1 -1
- package/dist/src/bun/index.js +1 -1
- package/dist/src/cli/index.js +13 -8
- package/dist/src/mcp/prompts.js +1 -1
- package/package.json +1 -1
- package/paclet/Kernel/MMAAgentBridge.wl +72 -39
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.1 - 2026-06-16
|
|
4
|
+
|
|
5
|
+
- Fix `RestartKernelRequest`: kill kernel via `Quit[]` before restarting.
|
|
6
|
+
- Fix `realpathSync` crash when `process.argv[1]` doesn't resolve.
|
|
7
|
+
- Fix `$BridgeNotebookPermissions` memory leak: prune on notebook close.
|
|
8
|
+
|
|
3
9
|
## 1.1.0 - 2026-06-09
|
|
4
10
|
|
|
5
11
|
- Add `mma_kill_kernel` tool: quit a notebook's Wolfram kernel (control agent kernel is protected).
|
|
@@ -3,7 +3,7 @@ import http from "node:http";
|
|
|
3
3
|
import { executeBackendMcpTool } from "../mcp/backendTools.js";
|
|
4
4
|
import { renderDashboard } from "./dashboard.js";
|
|
5
5
|
const JSON_BODY_LIMIT_BYTES = 1024 * 1024;
|
|
6
|
-
const DEFAULT_VERSION = "1.1.
|
|
6
|
+
const DEFAULT_VERSION = "1.1.1";
|
|
7
7
|
export async function createBunHttpApp({ state, host = "127.0.0.1", port, authToken, version = DEFAULT_VERSION }) {
|
|
8
8
|
const runtimeInfo = {
|
|
9
9
|
host,
|
package/dist/src/bun/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { loadRuntimeConfig } from "../runtime/config.js";
|
|
|
8
8
|
import { writeSessionFile } from "../runtime/session.js";
|
|
9
9
|
import { createBunHttpApp } from "./httpServer.js";
|
|
10
10
|
const MCP_SERVER_NAME = "mica-bun";
|
|
11
|
-
const MICA_PACKAGE_VERSION = "1.1.
|
|
11
|
+
const MICA_PACKAGE_VERSION = "1.1.1";
|
|
12
12
|
export async function startBunRuntime(deps = {}) {
|
|
13
13
|
const config = deps.runtimeConfig ?? loadRuntimeConfig();
|
|
14
14
|
const bridgeOnly = deps.bridgeOnly ?? config.bridgeOnly;
|
package/dist/src/cli/index.js
CHANGED
|
@@ -223,13 +223,18 @@ async function main() {
|
|
|
223
223
|
process.exitCode = exitCode;
|
|
224
224
|
}
|
|
225
225
|
if (process.argv[1]) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
226
|
+
try {
|
|
227
|
+
const scriptReal = realpathSync(fileURLToPath(import.meta.url));
|
|
228
|
+
const argReal = realpathSync(process.argv[1]);
|
|
229
|
+
if (scriptReal === argReal) {
|
|
230
|
+
main().catch((error) => {
|
|
231
|
+
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
232
|
+
process.stderr.write(`${message}\n`);
|
|
233
|
+
process.exitCode = 1;
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// process.argv[1] may not resolve (e.g. node -e, shebang edge cases)
|
|
234
239
|
}
|
|
235
240
|
}
|
package/dist/src/mcp/prompts.js
CHANGED
|
@@ -35,7 +35,7 @@ export const MICA_AGENT_INSTRUCTIONS = [
|
|
|
35
35
|
"Tools:",
|
|
36
36
|
...TOOL_GUIDE.map(([name, description]) => `- ${name}: ${description}`),
|
|
37
37
|
].join("\n");
|
|
38
|
-
export function createMicaMcpServer(name, version = "1.1.
|
|
38
|
+
export function createMicaMcpServer(name, version = "1.1.1") {
|
|
39
39
|
return new McpServer({ name, version }, { instructions: MICA_AGENT_INSTRUCTIONS });
|
|
40
40
|
}
|
|
41
41
|
export function registerMicaPrompts(server) {
|
package/package.json
CHANGED
|
@@ -122,11 +122,31 @@ If[!AssociationQ[Quiet @ Check[$BridgePermissions, None]],
|
|
|
122
122
|
$BridgePermissions = $DefaultBridgePermissions
|
|
123
123
|
];
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
If[!AssociationQ[Quiet @ Check[$BridgeNotebookPermissions, None]],
|
|
126
|
+
$BridgeNotebookPermissions = <||>
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
NotebookPermissions[notebookId_String] := Lookup[$BridgeNotebookPermissions, notebookId, $DefaultBridgePermissions];
|
|
130
|
+
|
|
131
|
+
SetNotebookPermissions[notebookId_String, perms_Association] := (
|
|
132
|
+
$BridgeNotebookPermissions[notebookId] = perms
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
PalettePermissionRow[label_String, key_String, notebookId_:None] := Module[{perms, setter},
|
|
136
|
+
perms = If[StringQ[notebookId] && StringLength[notebookId] > 0,
|
|
137
|
+
NotebookPermissions[notebookId],
|
|
138
|
+
$BridgePermissions
|
|
139
|
+
];
|
|
140
|
+
setter = If[StringQ[notebookId] && StringLength[notebookId] > 0,
|
|
141
|
+
Function[val, SetNotebookPermissions[notebookId, Join[perms, <|key -> val|>]]],
|
|
142
|
+
Function[val, $BridgePermissions[key] = val; Quiet @ Check[PostPermissions[], Null]]
|
|
143
|
+
];
|
|
144
|
+
Row[{
|
|
145
|
+
Checkbox[Dynamic[perms[key], (setter[#]) &]],
|
|
146
|
+
Spacer[8],
|
|
147
|
+
Style[label, 11]
|
|
148
|
+
}]
|
|
149
|
+
];
|
|
130
150
|
|
|
131
151
|
PaletteStatusSummary[] := Module[{server, paletteConnected, notebookAttached, pendingRequests, attachedNotebook, error},
|
|
132
152
|
server = Lookup[$LastStatus, "server", "unknown"];
|
|
@@ -332,14 +352,14 @@ PermissionsPanel[] := Panel[
|
|
|
332
352
|
Column[
|
|
333
353
|
{
|
|
334
354
|
Style["Permissions", Bold],
|
|
335
|
-
Grid[
|
|
355
|
+
Dynamic @ Grid[
|
|
336
356
|
{
|
|
337
|
-
{PalettePermissionRow["Read notebook", "ReadNotebook"]},
|
|
338
|
-
{PalettePermissionRow["Insert cell", "InsertCell"]},
|
|
339
|
-
{PalettePermissionRow["Modify cell", "ModifyCell"]},
|
|
340
|
-
{PalettePermissionRow["Delete cell", "DeleteCell"]},
|
|
341
|
-
{PalettePermissionRow["Run cell", "RunCell"]},
|
|
342
|
-
{PalettePermissionRow["Save notebook", "SaveNotebook"]}
|
|
357
|
+
{PalettePermissionRow["Read notebook", "ReadNotebook", $ActiveNotebookId]},
|
|
358
|
+
{PalettePermissionRow["Insert cell", "InsertCell", $ActiveNotebookId]},
|
|
359
|
+
{PalettePermissionRow["Modify cell", "ModifyCell", $ActiveNotebookId]},
|
|
360
|
+
{PalettePermissionRow["Delete cell", "DeleteCell", $ActiveNotebookId]},
|
|
361
|
+
{PalettePermissionRow["Run cell", "RunCell", $ActiveNotebookId]},
|
|
362
|
+
{PalettePermissionRow["Save notebook", "SaveNotebook", $ActiveNotebookId]}
|
|
343
363
|
},
|
|
344
364
|
Alignment -> Left,
|
|
345
365
|
Spacings -> {1, 0.35}
|
|
@@ -590,10 +610,16 @@ PostPermissions[] := Module[{payload = <|"permissions" -> $BridgePermissions|>},
|
|
|
590
610
|
Quiet @ Check[BridgePost["/permissions", payload], $Failed]
|
|
591
611
|
];
|
|
592
612
|
|
|
593
|
-
NeedsConfirmationQ[action_String] :=
|
|
613
|
+
NeedsConfirmationQ[action_String, notebookId_:None] := Module[{perms},
|
|
614
|
+
perms = If[StringQ[notebookId] && StringLength[notebookId] > 0,
|
|
615
|
+
NotebookPermissions[notebookId],
|
|
616
|
+
$BridgePermissions
|
|
617
|
+
];
|
|
618
|
+
Not @ TrueQ[perms[action]]
|
|
619
|
+
];
|
|
594
620
|
|
|
595
|
-
ConfirmAction[action_String, message_String] := If[
|
|
596
|
-
NeedsConfirmationQ[action],
|
|
621
|
+
ConfirmAction[action_String, message_String, notebookId_:None] := If[
|
|
622
|
+
NeedsConfirmationQ[action, notebookId],
|
|
597
623
|
ChoiceDialog[message, {"Allow" -> True, "Deny" -> False}],
|
|
598
624
|
True
|
|
599
625
|
];
|
|
@@ -606,8 +632,8 @@ FailedRequestCode[failure_Failure] := Module[{code = failure[[1]]},
|
|
|
606
632
|
|
|
607
633
|
FailedRequestMessage[failure_Failure] := Lookup[failure[[2]], "Message", Lookup[failure[[2]], "message", "The Wolfram bridge rejected the request."]];
|
|
608
634
|
|
|
609
|
-
RequireReadPermission[] := If[
|
|
610
|
-
Not @ ConfirmAction["ReadNotebook", "AI requests reading the notebook. Allow?"],
|
|
635
|
+
RequireReadPermission[notebookId_:None] := If[
|
|
636
|
+
Not @ ConfirmAction["ReadNotebook", "AI requests reading the notebook. Allow?", notebookId],
|
|
611
637
|
$Canceled,
|
|
612
638
|
True
|
|
613
639
|
];
|
|
@@ -628,7 +654,7 @@ NotebookInfo[nb_NotebookObject, notebookId_String] := <|
|
|
|
628
654
|
"wolframVersion" -> ToString @ $VersionNumber,
|
|
629
655
|
"platform" -> $OperatingSystem,
|
|
630
656
|
"paletteId" -> $PaletteId,
|
|
631
|
-
"permissions" ->
|
|
657
|
+
"permissions" -> NotebookPermissions[notebookId]
|
|
632
658
|
|>;
|
|
633
659
|
|
|
634
660
|
NotebookRecord[notebookId_String] := Lookup[$BridgeNotebooks, notebookId, <||>];
|
|
@@ -1137,9 +1163,9 @@ RefreshCellMap[notebookId_String] := Module[{record, nb, cells, idByCell, previo
|
|
|
1137
1163
|
payload
|
|
1138
1164
|
];
|
|
1139
1165
|
|
|
1140
|
-
ReadCellById[args_Association] := Module[{notebookId, record, cellId, cell, maxBytes, payload},
|
|
1141
|
-
|
|
1142
|
-
notebookId
|
|
1166
|
+
ReadCellById[args_Association] := Module[{notebookId, record, cellId, cell, maxBytes, payload},
|
|
1167
|
+
notebookId = TargetNotebookId[args];
|
|
1168
|
+
If[RequireReadPermission[notebookId] === $Canceled, Return[$Canceled]];
|
|
1143
1169
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1144
1170
|
record = NotebookRecord[notebookId];
|
|
1145
1171
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1158,9 +1184,9 @@ ReadCellById[args_Association] := Module[{notebookId, record, cellId, cell, maxB
|
|
|
1158
1184
|
]
|
|
1159
1185
|
];
|
|
1160
1186
|
|
|
1161
|
-
GetCellOutputById[args_Association] := Module[{notebookId, record, cellId, cell, artifacts, maxBytes, payload},
|
|
1162
|
-
|
|
1163
|
-
notebookId
|
|
1187
|
+
GetCellOutputById[args_Association] := Module[{notebookId, record, cellId, cell, artifacts, maxBytes, payload},
|
|
1188
|
+
notebookId = TargetNotebookId[args];
|
|
1189
|
+
If[RequireReadPermission[notebookId] === $Canceled, Return[$Canceled]];
|
|
1164
1190
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1165
1191
|
record = NotebookRecord[notebookId];
|
|
1166
1192
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1178,9 +1204,9 @@ GetCellOutputById[args_Association] := Module[{notebookId, record, cellId, cell,
|
|
|
1178
1204
|
]
|
|
1179
1205
|
];
|
|
1180
1206
|
|
|
1181
|
-
ReadArtifactById[args_Association] := Module[{notebookId, record, artifactId, parts, cellId, kind, indexText, index, cell, artifacts, artifactList, text, offset, limit, page, nextOffset, done},
|
|
1182
|
-
|
|
1183
|
-
notebookId
|
|
1207
|
+
ReadArtifactById[args_Association] := Module[{notebookId, record, artifactId, parts, cellId, kind, indexText, index, cell, artifacts, artifactList, text, offset, limit, page, nextOffset, done},
|
|
1208
|
+
notebookId = TargetNotebookId[args];
|
|
1209
|
+
If[RequireReadPermission[notebookId] === $Canceled, Return[$Canceled]];
|
|
1184
1210
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1185
1211
|
record = NotebookRecord[notebookId];
|
|
1186
1212
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1255,8 +1281,8 @@ InsertCellAtBeginning[notebook_NotebookObject, newCell_] := Module[{beforeCount,
|
|
|
1255
1281
|
];
|
|
1256
1282
|
|
|
1257
1283
|
InsertCellRequest[args_Association] := Module[{notebookId, record, afterId, style, content, newCell, notebook, anchor, cells, inserted, refreshed},
|
|
1258
|
-
If[Not @ ConfirmAction["InsertCell", "AI requests inserting 1 cell. Allow?"], Return[$Canceled]];
|
|
1259
1284
|
notebookId = TargetNotebookId[args];
|
|
1285
|
+
If[Not @ ConfirmAction["InsertCell", "AI requests inserting 1 cell. Allow?", notebookId], Return[$Canceled]];
|
|
1260
1286
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1261
1287
|
record = NotebookRecord[notebookId];
|
|
1262
1288
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1291,8 +1317,8 @@ InsertCellRequest[args_Association] := Module[{notebookId, record, afterId, styl
|
|
|
1291
1317
|
];
|
|
1292
1318
|
|
|
1293
1319
|
ModifyCellRequest[args_Association] := Module[{notebookId, record, notebook, cellId, cellMap, cell, content, style, newCell, cells, cellIndex, updatedCells, updatedCell, writeResult},
|
|
1294
|
-
If[Not @ ConfirmAction["ModifyCell", "AI requests modifying 1 cell. Allow?"], Return[$Canceled]];
|
|
1295
1320
|
notebookId = TargetNotebookId[args];
|
|
1321
|
+
If[Not @ ConfirmAction["ModifyCell", "AI requests modifying 1 cell. Allow?", notebookId], Return[$Canceled]];
|
|
1296
1322
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1297
1323
|
record = NotebookRecord[notebookId];
|
|
1298
1324
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1322,8 +1348,8 @@ ModifyCellRequest[args_Association] := Module[{notebookId, record, notebook, cel
|
|
|
1322
1348
|
];
|
|
1323
1349
|
|
|
1324
1350
|
DeleteCellRequest[args_Association] := Module[{notebookId, record, notebook, cellId, cell, cellMap, artifacts, artifactIds, newCellMap},
|
|
1325
|
-
If[Not @ ConfirmAction["DeleteCell", "AI requests deleting 1 cell. Allow?"], Return[$Canceled]];
|
|
1326
1351
|
notebookId = TargetNotebookId[args];
|
|
1352
|
+
If[Not @ ConfirmAction["DeleteCell", "AI requests deleting 1 cell. Allow?", notebookId], Return[$Canceled]];
|
|
1327
1353
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1328
1354
|
record = NotebookRecord[notebookId];
|
|
1329
1355
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1345,8 +1371,8 @@ DeleteCellRequest[args_Association] := Module[{notebookId, record, notebook, cel
|
|
|
1345
1371
|
];
|
|
1346
1372
|
|
|
1347
1373
|
RunCellRequest[args_Association] := Module[{notebookId, record, notebook, cellId, cell, timeoutSec = Lookup[args, "timeoutSec", 120], installedEpilog, evaluateResult},
|
|
1348
|
-
If[Not @ ConfirmAction["RunCell", "AI requests running 1 cell. Allow?"], Return[$Canceled]];
|
|
1349
1374
|
notebookId = TargetNotebookId[args];
|
|
1375
|
+
If[Not @ ConfirmAction["RunCell", "AI requests running 1 cell. Allow?", notebookId], Return[$Canceled]];
|
|
1350
1376
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1351
1377
|
record = NotebookRecord[notebookId];
|
|
1352
1378
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1384,8 +1410,8 @@ RunCellRequest[args_Association] := Module[{notebookId, record, notebook, cellId
|
|
|
1384
1410
|
];
|
|
1385
1411
|
|
|
1386
1412
|
AbortEvaluationRequest[args_Association] := Module[{notebookId, record, notebook, runningCellId, runningRequestId, wasRunning},
|
|
1387
|
-
If[Not @ ConfirmAction["RunCell", "AI requests aborting the running evaluation. Allow?"], Return[$Canceled]];
|
|
1388
1413
|
notebookId = TargetNotebookId[args];
|
|
1414
|
+
If[Not @ ConfirmAction["RunCell", "AI requests aborting the running evaluation. Allow?", notebookId], Return[$Canceled]];
|
|
1389
1415
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1390
1416
|
record = NotebookRecord[notebookId];
|
|
1391
1417
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1435,13 +1461,15 @@ RestartKernelRequest[args_Association] := Module[{notebookId, record, notebook,
|
|
|
1435
1461
|
If[evaluatorName === $ControlAgentEvaluatorName,
|
|
1436
1462
|
Return[Failure["PROTECTED_EVALUATOR", <|"message" -> "Cannot restart the MICA control agent evaluator."|>]]
|
|
1437
1463
|
];
|
|
1464
|
+
Quiet @ Check[NotebookEvaluate[notebook, "Quit[]", InsertResults -> False], Null];
|
|
1465
|
+
Pause[0.5];
|
|
1438
1466
|
Quiet @ Check[NotebookEvaluate[notebook, "Null", InsertResults -> False], Null];
|
|
1439
1467
|
<|"status" -> "restarted", "notebookId" -> notebookId|>
|
|
1440
1468
|
];
|
|
1441
1469
|
|
|
1442
|
-
SaveNotebookRequest[args_Association] := Module[{notebookId, record, notebook},
|
|
1443
|
-
If[Not @ ConfirmAction["SaveNotebook", "AI requests saving the notebook. Allow?"], Return[$Canceled]];
|
|
1470
|
+
SaveNotebookRequest[args_Association] := Module[{notebookId, record, notebook},
|
|
1444
1471
|
notebookId = TargetNotebookId[args];
|
|
1472
|
+
If[Not @ ConfirmAction["SaveNotebook", "AI requests saving the notebook. Allow?", notebookId], Return[$Canceled]];
|
|
1445
1473
|
If[!StringQ[notebookId] || StringLength[notebookId] == 0, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
1446
1474
|
record = NotebookRecord[notebookId];
|
|
1447
1475
|
If[!AssociationQ[record] || record === <||>, Return[Failure["BAD_REQUEST", <|"message" -> "No notebook is selected."|>]]];
|
|
@@ -1496,11 +1524,15 @@ AgentHeartbeat[] := BridgePost[
|
|
|
1496
1524
|
|>
|
|
1497
1525
|
];
|
|
1498
1526
|
|
|
1499
|
-
NotebookHeartbeatPayload[nb_NotebookObject] := Module[{savedPath, windowTitle, displayName, frontendObjectKey},
|
|
1527
|
+
NotebookHeartbeatPayload[nb_NotebookObject, notebookId_:None] := Module[{savedPath, windowTitle, displayName, frontendObjectKey, perms},
|
|
1500
1528
|
savedPath = Quiet @ Check[ToString[Replace[NotebookFileName[nb], $Failed -> ""]], ""];
|
|
1501
1529
|
frontendObjectKey = FrontendObjectKey[nb];
|
|
1502
1530
|
windowTitle = NotebookWindowTitle[nb];
|
|
1503
1531
|
displayName = NotebookDisplayNameForHeartbeat[nb, savedPath, frontendObjectKey];
|
|
1532
|
+
perms = If[StringQ[notebookId] && StringLength[notebookId] > 0,
|
|
1533
|
+
NotebookPermissions[notebookId],
|
|
1534
|
+
$DefaultBridgePermissions
|
|
1535
|
+
];
|
|
1504
1536
|
<|
|
|
1505
1537
|
"agentSessionId" -> $AgentSessionId,
|
|
1506
1538
|
"frontendObjectKey" -> frontendObjectKey,
|
|
@@ -1510,7 +1542,7 @@ NotebookHeartbeatPayload[nb_NotebookObject] := Module[{savedPath, windowTitle, d
|
|
|
1510
1542
|
"savedPath" -> savedPath,
|
|
1511
1543
|
"wolframVersion" -> ToString[$VersionNumber],
|
|
1512
1544
|
"platform" -> $OperatingSystem,
|
|
1513
|
-
"permissions" ->
|
|
1545
|
+
"permissions" -> perms,
|
|
1514
1546
|
"seenAt" -> UnixTimeMilliseconds[]
|
|
1515
1547
|
|>
|
|
1516
1548
|
];
|
|
@@ -1544,7 +1576,8 @@ AgentHeartbeatNotebookClosure[notebookId_String] := Module[{record = Lookup[$Bri
|
|
|
1544
1576
|
response = Quiet @ Check[BridgePost["/notebooks/" <> URLComponentEncodeString[notebookId] <> "/closed", <|"agentSessionId" -> $AgentSessionId|>], $Failed];
|
|
1545
1577
|
If[AssociationQ[record] && AssociationQ[response] && TrueQ[Lookup[response, "ok", False]],
|
|
1546
1578
|
If[!TrueQ[Lookup[record, "closed", False]],
|
|
1547
|
-
$BridgeNotebooks[notebookId] = Join[record, <|"closed" -> True|>]
|
|
1579
|
+
$BridgeNotebooks[notebookId] = Join[record, <|"closed" -> True|>];
|
|
1580
|
+
KeyDropFrom[$BridgeNotebookPermissions, notebookId]
|
|
1548
1581
|
]
|
|
1549
1582
|
];
|
|
1550
1583
|
response
|
|
@@ -1568,7 +1601,7 @@ HeartbeatNotebooks[] := Module[{notebooks = AgentVisibleNotebooks[], visibleNote
|
|
|
1568
1601
|
None
|
|
1569
1602
|
];
|
|
1570
1603
|
If[StringQ[localNotebookId] && StringLength[localNotebookId] > 0, AppendTo[visibleNotebookIds, localNotebookId]];
|
|
1571
|
-
payload = NotebookHeartbeatPayload[nb];
|
|
1604
|
+
payload = NotebookHeartbeatPayload[nb, localNotebookId];
|
|
1572
1605
|
response = Quiet @ Check[BridgePost["/notebooks/heartbeat", payload], $Failed];
|
|
1573
1606
|
If[AssociationQ[response],
|
|
1574
1607
|
notebookId = Lookup[Lookup[response, "notebook", <||>], "notebookId", Lookup[response, "notebookId", None]];
|
|
@@ -1801,7 +1834,7 @@ ExecuteRequest[request_Association] := Module[{requestId, tool, args, result},
|
|
|
1801
1834
|
!AssociationQ[args], Failure["BAD_REQUEST", <|"Message" -> "Request arguments must be an association."|>],
|
|
1802
1835
|
True,
|
|
1803
1836
|
Switch[tool,
|
|
1804
|
-
"mma_list_cells", If[RequireReadPermission[] === $Canceled, $Canceled, Module[{notebookId = TargetNotebookId[args], refresh}, If[!StringQ[notebookId] || StringLength[notebookId] == 0, Failure["BAD_REQUEST", <|"Message" -> "No notebook is selected."|>], refresh = RefreshCellMap[notebookId]; If[MatchQ[refresh, _Failure], refresh, <|"cells" -> refresh|>]]]],
|
|
1837
|
+
"mma_list_cells", If[RequireReadPermission[TargetNotebookId[args]] === $Canceled, $Canceled, Module[{notebookId = TargetNotebookId[args], refresh}, If[!StringQ[notebookId] || StringLength[notebookId] == 0, Failure["BAD_REQUEST", <|"Message" -> "No notebook is selected."|>], refresh = RefreshCellMap[notebookId]; If[MatchQ[refresh, _Failure], refresh, <|"cells" -> refresh|>]]]],
|
|
1805
1838
|
"mma_read_cell", ReadCellById[args],
|
|
1806
1839
|
"mma_insert_cell", InsertCellRequest[args],
|
|
1807
1840
|
"mma_modify_cell", ModifyCellRequest[args],
|