@flrande/bak-extension 0.3.8 → 0.5.0

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.
@@ -1 +1 @@
1
- 2026-03-09T16:21:56.905Z
1
+ 2026-03-11T07:35:54.292Z
@@ -30,26 +30,79 @@
30
30
  return Math.min(maxDelayMs, baseDelayMs * 2 ** safeAttempt);
31
31
  }
32
32
 
33
+ // src/session-binding-storage.ts
34
+ var STORAGE_KEY_SESSION_BINDINGS = "sessionBindings";
35
+ var LEGACY_STORAGE_KEY_WORKSPACES = "agentWorkspaces";
36
+ var LEGACY_STORAGE_KEY_WORKSPACE = "agentWorkspace";
37
+ function isWorkspaceRecord(value) {
38
+ if (typeof value !== "object" || value === null) {
39
+ return false;
40
+ }
41
+ const candidate = value;
42
+ return typeof candidate.id === "string" && Array.isArray(candidate.tabIds) && (typeof candidate.windowId === "number" || candidate.windowId === null) && (typeof candidate.groupId === "number" || candidate.groupId === null) && (typeof candidate.activeTabId === "number" || candidate.activeTabId === null) && (typeof candidate.primaryTabId === "number" || candidate.primaryTabId === null);
43
+ }
44
+ function cloneWorkspaceRecord(state) {
45
+ return {
46
+ ...state,
47
+ tabIds: [...state.tabIds]
48
+ };
49
+ }
50
+ function normalizeWorkspaceRecordMap(value) {
51
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
52
+ return {
53
+ found: false,
54
+ map: {}
55
+ };
56
+ }
57
+ const normalizedEntries = [];
58
+ for (const [workspaceId, entry] of Object.entries(value)) {
59
+ if (!isWorkspaceRecord(entry)) {
60
+ continue;
61
+ }
62
+ normalizedEntries.push([workspaceId, cloneWorkspaceRecord(entry)]);
63
+ }
64
+ return {
65
+ found: true,
66
+ map: Object.fromEntries(normalizedEntries)
67
+ };
68
+ }
69
+ function resolveSessionBindingStateMap(stored) {
70
+ const current = normalizeWorkspaceRecordMap(stored[STORAGE_KEY_SESSION_BINDINGS]);
71
+ if (current.found) {
72
+ return current.map;
73
+ }
74
+ const legacyMap = normalizeWorkspaceRecordMap(stored[LEGACY_STORAGE_KEY_WORKSPACES]);
75
+ if (legacyMap.found) {
76
+ return legacyMap.map;
77
+ }
78
+ const legacySingle = stored[LEGACY_STORAGE_KEY_WORKSPACE];
79
+ if (isWorkspaceRecord(legacySingle)) {
80
+ return {
81
+ [legacySingle.id]: cloneWorkspaceRecord(legacySingle)
82
+ };
83
+ }
84
+ return {};
85
+ }
86
+
33
87
  // src/workspace.ts
34
- var DEFAULT_WORKSPACE_ID = "default";
35
88
  var DEFAULT_WORKSPACE_LABEL = "bak agent";
36
89
  var DEFAULT_WORKSPACE_COLOR = "blue";
37
90
  var DEFAULT_WORKSPACE_URL = "about:blank";
38
- var WorkspaceManager = class {
91
+ var SessionBindingManager = class {
39
92
  storage;
40
93
  browser;
41
94
  constructor(storage, browser) {
42
95
  this.storage = storage;
43
96
  this.browser = browser;
44
97
  }
45
- async getWorkspaceInfo(workspaceId = DEFAULT_WORKSPACE_ID) {
98
+ async getWorkspaceInfo(workspaceId) {
46
99
  return this.inspectWorkspace(workspaceId);
47
100
  }
48
101
  async ensureWorkspace(options = {}) {
49
102
  const workspaceId = this.normalizeWorkspaceId(options.workspaceId);
50
103
  const repairActions = [];
51
104
  const initialUrl = options.initialUrl ?? DEFAULT_WORKSPACE_URL;
52
- const persisted = await this.storage.load();
105
+ const persisted = await this.storage.load(workspaceId);
53
106
  const created = !persisted;
54
107
  let state = this.normalizeState(persisted, workspaceId);
55
108
  const originalWindowId = state.windowId;
@@ -263,7 +316,7 @@
263
316
  tab
264
317
  };
265
318
  }
266
- async listTabs(workspaceId = DEFAULT_WORKSPACE_ID) {
319
+ async listTabs(workspaceId) {
267
320
  const ensured = await this.inspectWorkspace(workspaceId);
268
321
  if (!ensured) {
269
322
  throw new Error(`Workspace ${workspaceId} does not exist`);
@@ -273,7 +326,7 @@
273
326
  tabs: ensured.tabs
274
327
  };
275
328
  }
276
- async getActiveTab(workspaceId = DEFAULT_WORKSPACE_ID) {
329
+ async getActiveTab(workspaceId) {
277
330
  const ensured = await this.inspectWorkspace(workspaceId);
278
331
  if (!ensured) {
279
332
  const normalizedWorkspaceId = this.normalizeWorkspaceId(workspaceId);
@@ -290,7 +343,7 @@
290
343
  tab: ensured.tabs.find((tab) => tab.id === ensured.activeTabId) ?? null
291
344
  };
292
345
  }
293
- async setActiveTab(tabId, workspaceId = DEFAULT_WORKSPACE_ID) {
346
+ async setActiveTab(tabId, workspaceId) {
294
347
  const ensured = await this.ensureWorkspace({ workspaceId });
295
348
  if (!ensured.workspace.tabIds.includes(tabId)) {
296
349
  throw new Error(`Tab ${tabId} does not belong to workspace ${workspaceId}`);
@@ -319,7 +372,7 @@
319
372
  tab
320
373
  };
321
374
  }
322
- async focus(workspaceId = DEFAULT_WORKSPACE_ID) {
375
+ async focus(workspaceId) {
323
376
  const ensured = await this.ensureWorkspace({ workspaceId, focus: false });
324
377
  if (ensured.workspace.activeTabId !== null) {
325
378
  await this.browser.updateTab(ensured.workspace.activeTabId, { active: true });
@@ -331,16 +384,20 @@
331
384
  return { ok: true, workspace: refreshed.workspace };
332
385
  }
333
386
  async reset(options = {}) {
334
- await this.close(options.workspaceId);
335
- return this.ensureWorkspace(options);
387
+ const workspaceId = this.normalizeWorkspaceId(options.workspaceId);
388
+ await this.close(workspaceId);
389
+ return this.ensureWorkspace({
390
+ ...options,
391
+ workspaceId
392
+ });
336
393
  }
337
- async close(workspaceId = DEFAULT_WORKSPACE_ID) {
338
- const state = await this.storage.load();
339
- if (!state || state.id !== workspaceId) {
340
- await this.storage.save(null);
394
+ async close(workspaceId) {
395
+ const state = await this.loadWorkspaceRecord(workspaceId);
396
+ if (!state) {
397
+ await this.storage.delete(workspaceId);
341
398
  return { ok: true };
342
399
  }
343
- await this.storage.save(null);
400
+ await this.storage.delete(workspaceId);
344
401
  if (state.windowId !== null) {
345
402
  const existingWindow = await this.browser.getWindow(state.windowId);
346
403
  if (existingWindow) {
@@ -366,19 +423,11 @@
366
423
  }
367
424
  const explicitWorkspaceId = typeof options.workspaceId === "string" ? this.normalizeWorkspaceId(options.workspaceId) : void 0;
368
425
  if (explicitWorkspaceId) {
369
- const ensured2 = await this.ensureWorkspace({
426
+ const ensured = await this.ensureWorkspace({
370
427
  workspaceId: explicitWorkspaceId,
371
428
  focus: false
372
429
  });
373
- return this.buildWorkspaceResolution(ensured2, "explicit-workspace");
374
- }
375
- const existingWorkspace = await this.loadWorkspaceRecord(DEFAULT_WORKSPACE_ID);
376
- if (existingWorkspace) {
377
- const ensured2 = await this.ensureWorkspace({
378
- workspaceId: existingWorkspace.id,
379
- focus: false
380
- });
381
- return this.buildWorkspaceResolution(ensured2, "default-workspace");
430
+ return this.buildWorkspaceResolution(ensured, "explicit-workspace");
382
431
  }
383
432
  if (options.createIfMissing !== true) {
384
433
  const activeTab = await this.browser.getActiveTab();
@@ -394,19 +443,12 @@
394
443
  repairActions: []
395
444
  };
396
445
  }
397
- const ensured = await this.ensureWorkspace({
398
- workspaceId: DEFAULT_WORKSPACE_ID,
399
- focus: false
400
- });
401
- return this.buildWorkspaceResolution(ensured, "default-workspace");
446
+ throw new Error("workspaceId is required when createIfMissing is true");
402
447
  }
403
448
  normalizeWorkspaceId(workspaceId) {
404
449
  const candidate = workspaceId?.trim();
405
450
  if (!candidate) {
406
- return DEFAULT_WORKSPACE_ID;
407
- }
408
- if (candidate !== DEFAULT_WORKSPACE_ID) {
409
- throw new Error(`Unsupported workspace id: ${candidate}`);
451
+ throw new Error("workspaceId is required");
410
452
  }
411
453
  return candidate;
412
454
  }
@@ -422,9 +464,12 @@
422
464
  primaryTabId: state?.primaryTabId ?? null
423
465
  };
424
466
  }
425
- async loadWorkspaceRecord(workspaceId = DEFAULT_WORKSPACE_ID) {
467
+ async listWorkspaceRecords() {
468
+ return await this.storage.list();
469
+ }
470
+ async loadWorkspaceRecord(workspaceId) {
426
471
  const normalizedWorkspaceId = this.normalizeWorkspaceId(workspaceId);
427
- const state = await this.storage.load();
472
+ const state = await this.storage.load(normalizedWorkspaceId);
428
473
  if (!state || state.id !== normalizedWorkspaceId) {
429
474
  return null;
430
475
  }
@@ -659,7 +704,7 @@
659
704
  }
660
705
  throw lastError2 ?? new Error(`No window with id: ${options.windowId}.`);
661
706
  }
662
- async inspectWorkspace(workspaceId = DEFAULT_WORKSPACE_ID) {
707
+ async inspectWorkspace(workspaceId) {
663
708
  const state = await this.loadWorkspaceRecord(workspaceId);
664
709
  if (!state) {
665
710
  return null;
@@ -755,7 +800,6 @@
755
800
  var STORAGE_KEY_TOKEN = "pairToken";
756
801
  var STORAGE_KEY_PORT = "cliPort";
757
802
  var STORAGE_KEY_DEBUG_RICH_TEXT = "debugRichText";
758
- var STORAGE_KEY_WORKSPACE = "agentWorkspace";
759
803
  var DEFAULT_TAB_LOAD_TIMEOUT_MS = 4e4;
760
804
  var ws = null;
761
805
  var reconnectTimer = null;
@@ -817,6 +861,12 @@
817
861
  if (lower.includes("no tab with id") || lower.includes("no window with id")) {
818
862
  return toError("E_NOT_FOUND", message);
819
863
  }
864
+ if (lower.includes("workspace") && lower.includes("does not exist")) {
865
+ return toError("E_NOT_FOUND", message);
866
+ }
867
+ if (lower.includes("does not belong to workspace") || lower.includes("is missing from workspace")) {
868
+ return toError("E_NOT_FOUND", message);
869
+ }
820
870
  if (lower.includes("invalid url") || lower.includes("url is invalid")) {
821
871
  return toError("E_INVALID_PARAMS", message);
822
872
  }
@@ -838,20 +888,36 @@
838
888
  groupId: typeof tab.groupId === "number" && tab.groupId >= 0 ? tab.groupId : null
839
889
  };
840
890
  }
841
- async function loadWorkspaceState() {
842
- const stored = await chrome.storage.local.get(STORAGE_KEY_WORKSPACE);
843
- const state = stored[STORAGE_KEY_WORKSPACE];
844
- if (!state || typeof state !== "object") {
845
- return null;
846
- }
847
- return state;
891
+ async function loadWorkspaceStateMap() {
892
+ const stored = await chrome.storage.local.get([
893
+ STORAGE_KEY_SESSION_BINDINGS,
894
+ LEGACY_STORAGE_KEY_WORKSPACES,
895
+ LEGACY_STORAGE_KEY_WORKSPACE
896
+ ]);
897
+ return resolveSessionBindingStateMap(stored);
898
+ }
899
+ async function loadWorkspaceState(workspaceId) {
900
+ const stateMap = await loadWorkspaceStateMap();
901
+ return stateMap[workspaceId] ?? null;
902
+ }
903
+ async function listWorkspaceStates() {
904
+ return Object.values(await loadWorkspaceStateMap());
848
905
  }
849
906
  async function saveWorkspaceState(state) {
850
- if (state === null) {
851
- await chrome.storage.local.remove(STORAGE_KEY_WORKSPACE);
907
+ const stateMap = await loadWorkspaceStateMap();
908
+ stateMap[state.id] = state;
909
+ await chrome.storage.local.set({ [STORAGE_KEY_SESSION_BINDINGS]: stateMap });
910
+ await chrome.storage.local.remove([LEGACY_STORAGE_KEY_WORKSPACES, LEGACY_STORAGE_KEY_WORKSPACE]);
911
+ }
912
+ async function deleteWorkspaceState(workspaceId) {
913
+ const stateMap = await loadWorkspaceStateMap();
914
+ delete stateMap[workspaceId];
915
+ if (Object.keys(stateMap).length === 0) {
916
+ await chrome.storage.local.remove([STORAGE_KEY_SESSION_BINDINGS, LEGACY_STORAGE_KEY_WORKSPACES, LEGACY_STORAGE_KEY_WORKSPACE]);
852
917
  return;
853
918
  }
854
- await chrome.storage.local.set({ [STORAGE_KEY_WORKSPACE]: state });
919
+ await chrome.storage.local.set({ [STORAGE_KEY_SESSION_BINDINGS]: stateMap });
920
+ await chrome.storage.local.remove([LEGACY_STORAGE_KEY_WORKSPACES, LEGACY_STORAGE_KEY_WORKSPACE]);
855
921
  }
856
922
  var workspaceBrowser = {
857
923
  async getTab(tabId) {
@@ -983,10 +1049,12 @@
983
1049
  };
984
1050
  }
985
1051
  };
986
- var workspaceManager = new WorkspaceManager(
1052
+ var bindingManager = new SessionBindingManager(
987
1053
  {
988
1054
  load: loadWorkspaceState,
989
- save: saveWorkspaceState
1055
+ save: saveWorkspaceState,
1056
+ delete: deleteWorkspaceState,
1057
+ list: listWorkspaceStates
990
1058
  },
991
1059
  workspaceBrowser
992
1060
  );
@@ -1094,7 +1162,7 @@
1094
1162
  } catch {
1095
1163
  refreshedTab = await workspaceBrowser.getTab(opened.tab.id) ?? opened.tab;
1096
1164
  }
1097
- const refreshedWorkspace = await workspaceManager.getWorkspaceInfo(opened.workspace.id) ?? {
1165
+ const refreshedWorkspace = await bindingManager.getWorkspaceInfo(opened.workspace.id) ?? {
1098
1166
  ...opened.workspace,
1099
1167
  tabs: opened.workspace.tabs.map((tab) => tab.id === refreshedTab.id ? refreshedTab : tab)
1100
1168
  };
@@ -1121,7 +1189,7 @@
1121
1189
  const tab2 = await chrome.tabs.get(target.tabId);
1122
1190
  return validate(tab2);
1123
1191
  }
1124
- const resolved = await workspaceManager.resolveTarget({
1192
+ const resolved = await bindingManager.resolveTarget({
1125
1193
  tabId: target.tabId,
1126
1194
  workspaceId: typeof target.workspaceId === "string" ? target.workspaceId : void 0,
1127
1195
  createIfMissing: false
@@ -1254,6 +1322,8 @@
1254
1322
  "mouse.click",
1255
1323
  "mouse.wheel",
1256
1324
  "file.upload",
1325
+ "context.get",
1326
+ "context.set",
1257
1327
  "context.enterFrame",
1258
1328
  "context.exitFrame",
1259
1329
  "context.enterShadow",
@@ -1301,24 +1371,6 @@
1301
1371
  return { ok: true };
1302
1372
  }
1303
1373
  case "tabs.new": {
1304
- if (typeof params.workspaceId === "string" || params.windowId === void 0) {
1305
- const expectedUrl = params.url ?? "about:blank";
1306
- const opened = await preserveHumanFocus(true, async () => {
1307
- return await workspaceManager.openTab({
1308
- workspaceId: typeof params.workspaceId === "string" ? params.workspaceId : DEFAULT_WORKSPACE_ID,
1309
- url: expectedUrl,
1310
- active: params.active === true,
1311
- focus: false
1312
- });
1313
- });
1314
- const stabilized = await finalizeOpenedWorkspaceTab(opened, expectedUrl);
1315
- return {
1316
- tabId: stabilized.tab.id,
1317
- windowId: stabilized.tab.windowId,
1318
- groupId: stabilized.workspace.groupId,
1319
- workspaceId: stabilized.workspace.id
1320
- };
1321
- }
1322
1374
  const tab = await chrome.tabs.create({
1323
1375
  url: params.url ?? "about:blank",
1324
1376
  windowId: typeof params.windowId === "number" ? params.windowId : void 0,
@@ -1344,8 +1396,8 @@
1344
1396
  }
1345
1397
  case "workspace.ensure": {
1346
1398
  return preserveHumanFocus(params.focus !== true, async () => {
1347
- return await workspaceManager.ensureWorkspace({
1348
- workspaceId: typeof params.workspaceId === "string" ? params.workspaceId : void 0,
1399
+ return await bindingManager.ensureWorkspace({
1400
+ workspaceId: String(params.workspaceId ?? ""),
1349
1401
  focus: params.focus === true,
1350
1402
  initialUrl: typeof params.url === "string" ? params.url : void 0
1351
1403
  });
@@ -1353,14 +1405,14 @@
1353
1405
  }
1354
1406
  case "workspace.info": {
1355
1407
  return {
1356
- workspace: await workspaceManager.getWorkspaceInfo(typeof params.workspaceId === "string" ? params.workspaceId : void 0)
1408
+ workspace: await bindingManager.getWorkspaceInfo(String(params.workspaceId ?? ""))
1357
1409
  };
1358
1410
  }
1359
1411
  case "workspace.openTab": {
1360
1412
  const expectedUrl = typeof params.url === "string" ? params.url : void 0;
1361
1413
  const opened = await preserveHumanFocus(params.focus !== true, async () => {
1362
- return await workspaceManager.openTab({
1363
- workspaceId: typeof params.workspaceId === "string" ? params.workspaceId : void 0,
1414
+ return await bindingManager.openTab({
1415
+ workspaceId: String(params.workspaceId ?? ""),
1364
1416
  url: expectedUrl,
1365
1417
  active: params.active === true,
1366
1418
  focus: params.focus === true
@@ -1369,28 +1421,28 @@
1369
1421
  return await finalizeOpenedWorkspaceTab(opened, expectedUrl);
1370
1422
  }
1371
1423
  case "workspace.listTabs": {
1372
- return await workspaceManager.listTabs(typeof params.workspaceId === "string" ? params.workspaceId : void 0);
1424
+ return await bindingManager.listTabs(String(params.workspaceId ?? ""));
1373
1425
  }
1374
1426
  case "workspace.getActiveTab": {
1375
- return await workspaceManager.getActiveTab(typeof params.workspaceId === "string" ? params.workspaceId : void 0);
1427
+ return await bindingManager.getActiveTab(String(params.workspaceId ?? ""));
1376
1428
  }
1377
1429
  case "workspace.setActiveTab": {
1378
- return await workspaceManager.setActiveTab(Number(params.tabId), typeof params.workspaceId === "string" ? params.workspaceId : void 0);
1430
+ return await bindingManager.setActiveTab(Number(params.tabId), String(params.workspaceId ?? ""));
1379
1431
  }
1380
1432
  case "workspace.focus": {
1381
- return await workspaceManager.focus(typeof params.workspaceId === "string" ? params.workspaceId : void 0);
1433
+ return await bindingManager.focus(String(params.workspaceId ?? ""));
1382
1434
  }
1383
1435
  case "workspace.reset": {
1384
1436
  return await preserveHumanFocus(params.focus !== true, async () => {
1385
- return await workspaceManager.reset({
1386
- workspaceId: typeof params.workspaceId === "string" ? params.workspaceId : void 0,
1437
+ return await bindingManager.reset({
1438
+ workspaceId: String(params.workspaceId ?? ""),
1387
1439
  focus: params.focus === true,
1388
1440
  initialUrl: typeof params.url === "string" ? params.url : void 0
1389
1441
  });
1390
1442
  });
1391
1443
  }
1392
1444
  case "workspace.close": {
1393
- return await workspaceManager.close(typeof params.workspaceId === "string" ? params.workspaceId : void 0);
1445
+ return await bindingManager.close(String(params.workspaceId ?? ""));
1394
1446
  }
1395
1447
  case "page.goto": {
1396
1448
  return await preserveHumanFocus(typeof target.tabId !== "number", async () => {
@@ -1619,7 +1671,7 @@
1619
1671
  ws?.send(JSON.stringify({
1620
1672
  type: "hello",
1621
1673
  role: "extension",
1622
- version: "0.3.8",
1674
+ version: "0.5.0",
1623
1675
  ts: Date.now()
1624
1676
  }));
1625
1677
  });
@@ -1654,43 +1706,49 @@
1654
1706
  });
1655
1707
  }
1656
1708
  chrome.tabs.onRemoved.addListener((tabId) => {
1657
- void loadWorkspaceState().then(async (state) => {
1658
- if (!state || !state.tabIds.includes(tabId)) {
1659
- return;
1709
+ void listWorkspaceStates().then(async (states) => {
1710
+ for (const state of states) {
1711
+ if (!state.tabIds.includes(tabId)) {
1712
+ continue;
1713
+ }
1714
+ const nextTabIds = state.tabIds.filter((id) => id !== tabId);
1715
+ await saveWorkspaceState({
1716
+ ...state,
1717
+ tabIds: nextTabIds,
1718
+ activeTabId: state.activeTabId === tabId ? null : state.activeTabId,
1719
+ primaryTabId: state.primaryTabId === tabId ? null : state.primaryTabId
1720
+ });
1660
1721
  }
1661
- const nextTabIds = state.tabIds.filter((id) => id !== tabId);
1662
- await saveWorkspaceState({
1663
- ...state,
1664
- tabIds: nextTabIds,
1665
- activeTabId: state.activeTabId === tabId ? null : state.activeTabId,
1666
- primaryTabId: state.primaryTabId === tabId ? null : state.primaryTabId
1667
- });
1668
1722
  });
1669
1723
  });
1670
1724
  chrome.tabs.onActivated.addListener((activeInfo) => {
1671
- void loadWorkspaceState().then(async (state) => {
1672
- if (!state || state.windowId !== activeInfo.windowId || !state.tabIds.includes(activeInfo.tabId)) {
1673
- return;
1725
+ void listWorkspaceStates().then(async (states) => {
1726
+ for (const state of states) {
1727
+ if (state.windowId !== activeInfo.windowId || !state.tabIds.includes(activeInfo.tabId)) {
1728
+ continue;
1729
+ }
1730
+ await saveWorkspaceState({
1731
+ ...state,
1732
+ activeTabId: activeInfo.tabId
1733
+ });
1674
1734
  }
1675
- await saveWorkspaceState({
1676
- ...state,
1677
- activeTabId: activeInfo.tabId
1678
- });
1679
1735
  });
1680
1736
  });
1681
1737
  chrome.windows.onRemoved.addListener((windowId) => {
1682
- void loadWorkspaceState().then(async (state) => {
1683
- if (!state || state.windowId !== windowId) {
1684
- return;
1738
+ void listWorkspaceStates().then(async (states) => {
1739
+ for (const state of states) {
1740
+ if (state.windowId !== windowId) {
1741
+ continue;
1742
+ }
1743
+ await saveWorkspaceState({
1744
+ ...state,
1745
+ windowId: null,
1746
+ groupId: null,
1747
+ tabIds: [],
1748
+ activeTabId: null,
1749
+ primaryTabId: null
1750
+ });
1685
1751
  }
1686
- await saveWorkspaceState({
1687
- ...state,
1688
- windowId: null,
1689
- groupId: null,
1690
- tabIds: [],
1691
- activeTabId: null,
1692
- primaryTabId: null
1693
- });
1694
1752
  });
1695
1753
  });
1696
1754
  chrome.runtime.onInstalled.addListener(() => {
@@ -1962,6 +1962,35 @@
1962
1962
  dispatchInputEvents(target);
1963
1963
  return { ok: true, fileCount: transfer.files.length };
1964
1964
  }
1965
+ case "context.get":
1966
+ return {
1967
+ ok: true,
1968
+ frameDepth: contextState.framePath.length,
1969
+ shadowDepth: contextState.shadowPath.length,
1970
+ framePath: [...contextState.framePath],
1971
+ shadowPath: [...contextState.shadowPath]
1972
+ };
1973
+ case "context.set": {
1974
+ const framePath = Array.isArray(params.framePath) ? params.framePath.map(String) : [];
1975
+ const shadowPath = Array.isArray(params.shadowPath) ? params.shadowPath.map(String) : [];
1976
+ const frameResult = resolveFrameDocument(framePath);
1977
+ if (!frameResult.ok) {
1978
+ throw frameResult.error;
1979
+ }
1980
+ const shadowResult = resolveShadowRoot(frameResult.document, shadowPath);
1981
+ if (!shadowResult.ok) {
1982
+ throw shadowResult.error;
1983
+ }
1984
+ contextState.framePath = framePath;
1985
+ contextState.shadowPath = shadowPath;
1986
+ return {
1987
+ ok: true,
1988
+ frameDepth: contextState.framePath.length,
1989
+ shadowDepth: contextState.shadowPath.length,
1990
+ framePath: [...contextState.framePath],
1991
+ shadowPath: [...contextState.shadowPath]
1992
+ };
1993
+ }
1965
1994
  case "context.enterFrame": {
1966
1995
  if (params.reset === true) {
1967
1996
  contextState.framePath = [];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Browser Agent Kit",
4
- "version": "0.3.8",
4
+ "version": "0.5.0",
5
5
  "action": {
6
6
  "default_popup": "popup.html"
7
7
  },
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@flrande/bak-extension",
3
- "version": "0.3.8",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "dependencies": {
6
- "@flrande/bak-protocol": "0.3.8"
6
+ "@flrande/bak-protocol": "0.5.0"
7
7
  },
8
8
  "devDependencies": {
9
9
  "@types/chrome": "^0.1.14",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Browser Agent Kit",
4
- "version": "0.3.8",
4
+ "version": "0.5.0",
5
5
  "action": {
6
6
  "default_popup": "popup.html"
7
7
  },