@flrande/bak-extension 0.6.5 → 0.6.6

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-13T06:30:44.568Z
1
+ 2026-03-13T07:15:48.660Z
@@ -62,7 +62,7 @@
62
62
  // package.json
63
63
  var package_default = {
64
64
  name: "@flrande/bak-extension",
65
- version: "0.6.5",
65
+ version: "0.6.6",
66
66
  type: "module",
67
67
  scripts: {
68
68
  build: "tsup src/background.ts src/content.ts src/popup.ts --format iife --out-dir dist --clean && node scripts/copy-assets.mjs",
@@ -573,13 +573,14 @@
573
573
  state.activeTabId = null;
574
574
  state.primaryTabId = null;
575
575
  window2 = createdWindow;
576
- tabs = await this.waitForWindowTabs(createdWindow.id);
576
+ const initialTab = typeof createdWindow.initialTabId === "number" ? await this.waitForTrackedTab(createdWindow.initialTabId, createdWindow.id) : null;
577
+ tabs = initialTab ? [initialTab] : await this.waitForWindowTabs(createdWindow.id);
577
578
  state.tabIds = tabs.map((tab) => tab.id);
578
579
  if (state.primaryTabId === null) {
579
- state.primaryTabId = tabs[0]?.id ?? null;
580
+ state.primaryTabId = initialTab?.id ?? tabs[0]?.id ?? null;
580
581
  }
581
582
  if (state.activeTabId === null) {
582
- state.activeTabId = tabs.find((tab) => tab.active)?.id ?? tabs[0]?.id ?? null;
583
+ state.activeTabId = tabs.find((tab) => tab.active)?.id ?? initialTab?.id ?? tabs[0]?.id ?? null;
583
584
  }
584
585
  repairActions.push(created ? "created-window" : "recreated-window");
585
586
  }
@@ -1081,7 +1082,8 @@
1081
1082
  url: seedUrl || DEFAULT_SESSION_BINDING_URL,
1082
1083
  focused: false
1083
1084
  });
1084
- const recreatedTabs = await this.waitForWindowTabs(window2.id);
1085
+ const initialTab = typeof window2.initialTabId === "number" ? await this.waitForTrackedTab(window2.initialTabId, window2.id) : null;
1086
+ const recreatedTabs = initialTab ? [initialTab] : await this.waitForWindowTabs(window2.id);
1085
1087
  const firstTab = recreatedTabs[0] ?? null;
1086
1088
  const tabIdMap = /* @__PURE__ */ new Map();
1087
1089
  if (sourceTabs[0] && firstTab) {
@@ -1608,14 +1610,42 @@
1608
1610
  },
1609
1611
  async createWindow(options) {
1610
1612
  const previouslyFocusedWindow = options.focused === true ? null : (await chrome.windows.getAll()).find((window2) => window2.focused === true && typeof window2.id === "number") ?? null;
1611
- const previouslyFocusedTab = previouslyFocusedWindow?.id !== void 0 ? (await chrome.tabs.query({ windowId: previouslyFocusedWindow.id, active: true })).find((tab) => typeof tab.id === "number") ?? null : null;
1612
- const created = await chrome.windows.create({
1613
- url: options.url ?? "about:blank",
1613
+ const previouslyFocusedTabs = previouslyFocusedWindow?.id !== void 0 ? await chrome.tabs.query({ windowId: previouslyFocusedWindow.id }) : [];
1614
+ const previouslyFocusedTabIds = new Set(
1615
+ previouslyFocusedTabs.flatMap((tab) => typeof tab.id === "number" ? [tab.id] : [])
1616
+ );
1617
+ const previouslyFocusedTab = previouslyFocusedTabs.find((tab) => tab.active === true && typeof tab.id === "number") ?? null;
1618
+ const desiredUrl = options.url ?? "about:blank";
1619
+ let created = await chrome.windows.create({
1620
+ url: desiredUrl,
1614
1621
  focused: true
1615
1622
  });
1616
1623
  if (!created || typeof created.id !== "number") {
1617
1624
  throw new Error("Window missing id");
1618
1625
  }
1626
+ const pickSeedTab = async (windowId) => {
1627
+ const tabs = await chrome.tabs.query({ windowId });
1628
+ const newlyCreatedTab = windowId === previouslyFocusedWindow?.id ? tabs.find((tab) => typeof tab.id === "number" && !previouslyFocusedTabIds.has(tab.id)) : null;
1629
+ const normalizedDesiredUrl = normalizeComparableTabUrl(desiredUrl);
1630
+ return newlyCreatedTab ?? tabs.find((tab) => {
1631
+ const pendingUrl = "pendingUrl" in tab && typeof tab.pendingUrl === "string" ? tab.pendingUrl : "";
1632
+ return normalizeComparableTabUrl(tab.url ?? pendingUrl) === normalizedDesiredUrl;
1633
+ }) ?? tabs.find((tab) => tab.active === true && typeof tab.id === "number") ?? tabs.find((tab) => typeof tab.id === "number") ?? null;
1634
+ };
1635
+ let seedTab = await pickSeedTab(created.id);
1636
+ const createdWindowTabs = await chrome.tabs.query({ windowId: created.id });
1637
+ const createdWindowReusedFocusedWindow = previouslyFocusedWindow?.id === created.id;
1638
+ const createdWindowLooksDirty = createdWindowTabs.length > 1;
1639
+ if ((createdWindowReusedFocusedWindow || createdWindowLooksDirty) && typeof seedTab?.id === "number") {
1640
+ created = await chrome.windows.create({
1641
+ tabId: seedTab.id,
1642
+ focused: true
1643
+ });
1644
+ if (!created || typeof created.id !== "number") {
1645
+ throw new Error("Lifted window missing id");
1646
+ }
1647
+ seedTab = await pickSeedTab(created.id);
1648
+ }
1619
1649
  if (options.focused !== true && previouslyFocusedWindow?.id && previouslyFocusedWindow.id !== created.id) {
1620
1650
  await chrome.windows.update(previouslyFocusedWindow.id, { focused: true });
1621
1651
  if (typeof previouslyFocusedTab?.id === "number") {
@@ -1625,7 +1655,8 @@
1625
1655
  const finalWindow = await chrome.windows.get(created.id);
1626
1656
  return {
1627
1657
  id: finalWindow.id,
1628
- focused: Boolean(finalWindow.focused)
1658
+ focused: Boolean(finalWindow.focused),
1659
+ initialTabId: seedTab?.id ?? null
1629
1660
  };
1630
1661
  },
1631
1662
  async updateWindow(windowId, options) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Browser Agent Kit",
4
- "version": "0.6.5",
4
+ "version": "0.6.6",
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.6.5",
3
+ "version": "0.6.6",
4
4
  "type": "module",
5
5
  "dependencies": {
6
- "@flrande/bak-protocol": "0.6.5"
6
+ "@flrande/bak-protocol": "0.6.6"
7
7
  },
8
8
  "devDependencies": {
9
9
  "@types/chrome": "^0.1.14",
package/src/background.ts CHANGED
@@ -411,7 +411,7 @@ function emitSessionBindingUpdated(
411
411
  });
412
412
  }
413
413
 
414
- const sessionBindingBrowser: SessionBindingBrowser = {
414
+ const sessionBindingBrowser: SessionBindingBrowser = {
415
415
  async getTab(tabId) {
416
416
  try {
417
417
  return toTabInfo(await chrome.tabs.get(tabId));
@@ -468,34 +468,71 @@ const sessionBindingBrowser: SessionBindingBrowser = {
468
468
  return null;
469
469
  }
470
470
  },
471
- async createWindow(options) {
472
- const previouslyFocusedWindow =
473
- options.focused === true
474
- ? null
475
- : (await chrome.windows.getAll()).find((window) => window.focused === true && typeof window.id === 'number') ?? null;
476
- const previouslyFocusedTab =
477
- previouslyFocusedWindow?.id !== undefined
478
- ? (await chrome.tabs.query({ windowId: previouslyFocusedWindow.id, active: true })).find((tab) => typeof tab.id === 'number') ?? null
479
- : null;
480
- const created = await chrome.windows.create({
481
- url: options.url ?? 'about:blank',
482
- focused: true
483
- });
484
- if (!created || typeof created.id !== 'number') {
485
- throw new Error('Window missing id');
486
- }
487
- if (options.focused !== true && previouslyFocusedWindow?.id && previouslyFocusedWindow.id !== created.id) {
488
- await chrome.windows.update(previouslyFocusedWindow.id, { focused: true });
489
- if (typeof previouslyFocusedTab?.id === 'number') {
490
- await chrome.tabs.update(previouslyFocusedTab.id, { active: true });
491
- }
471
+ async createWindow(options) {
472
+ const previouslyFocusedWindow =
473
+ options.focused === true
474
+ ? null
475
+ : (await chrome.windows.getAll()).find((window) => window.focused === true && typeof window.id === 'number') ?? null;
476
+ const previouslyFocusedTabs =
477
+ previouslyFocusedWindow?.id !== undefined ? await chrome.tabs.query({ windowId: previouslyFocusedWindow.id }) : [];
478
+ const previouslyFocusedTabIds = new Set(
479
+ previouslyFocusedTabs.flatMap((tab) => (typeof tab.id === 'number' ? [tab.id] : []))
480
+ );
481
+ const previouslyFocusedTab =
482
+ previouslyFocusedTabs.find((tab) => tab.active === true && typeof tab.id === 'number') ?? null;
483
+ const desiredUrl = options.url ?? 'about:blank';
484
+ let created = await chrome.windows.create({
485
+ url: desiredUrl,
486
+ focused: true
487
+ });
488
+ if (!created || typeof created.id !== 'number') {
489
+ throw new Error('Window missing id');
490
+ }
491
+ const pickSeedTab = async (windowId: number): Promise<chrome.tabs.Tab | null> => {
492
+ const tabs = await chrome.tabs.query({ windowId });
493
+ const newlyCreatedTab =
494
+ windowId === previouslyFocusedWindow?.id
495
+ ? tabs.find((tab) => typeof tab.id === 'number' && !previouslyFocusedTabIds.has(tab.id))
496
+ : null;
497
+ const normalizedDesiredUrl = normalizeComparableTabUrl(desiredUrl);
498
+ return (
499
+ newlyCreatedTab ??
500
+ tabs.find((tab) => {
501
+ const pendingUrl = 'pendingUrl' in tab && typeof tab.pendingUrl === 'string' ? tab.pendingUrl : '';
502
+ return normalizeComparableTabUrl(tab.url ?? pendingUrl) === normalizedDesiredUrl;
503
+ }) ??
504
+ tabs.find((tab) => tab.active === true && typeof tab.id === 'number') ??
505
+ tabs.find((tab) => typeof tab.id === 'number') ??
506
+ null
507
+ );
508
+ };
509
+ let seedTab = await pickSeedTab(created.id);
510
+ const createdWindowTabs = await chrome.tabs.query({ windowId: created.id });
511
+ const createdWindowReusedFocusedWindow = previouslyFocusedWindow?.id === created.id;
512
+ const createdWindowLooksDirty = createdWindowTabs.length > 1;
513
+ if ((createdWindowReusedFocusedWindow || createdWindowLooksDirty) && typeof seedTab?.id === 'number') {
514
+ created = await chrome.windows.create({
515
+ tabId: seedTab.id,
516
+ focused: true
517
+ });
518
+ if (!created || typeof created.id !== 'number') {
519
+ throw new Error('Lifted window missing id');
520
+ }
521
+ seedTab = await pickSeedTab(created.id);
522
+ }
523
+ if (options.focused !== true && previouslyFocusedWindow?.id && previouslyFocusedWindow.id !== created.id) {
524
+ await chrome.windows.update(previouslyFocusedWindow.id, { focused: true });
525
+ if (typeof previouslyFocusedTab?.id === 'number') {
526
+ await chrome.tabs.update(previouslyFocusedTab.id, { active: true });
527
+ }
492
528
  }
493
529
  const finalWindow = await chrome.windows.get(created.id);
494
- return {
495
- id: finalWindow.id!,
496
- focused: Boolean(finalWindow.focused)
497
- };
498
- },
530
+ return {
531
+ id: finalWindow.id!,
532
+ focused: Boolean(finalWindow.focused),
533
+ initialTabId: seedTab?.id ?? null
534
+ };
535
+ },
499
536
  async updateWindow(windowId, options) {
500
537
  const updated = await chrome.windows.update(windowId, {
501
538
  focused: options.focused
@@ -16,10 +16,11 @@ export interface SessionBindingTab {
16
16
  groupId: number | null;
17
17
  }
18
18
 
19
- export interface SessionBindingWindow {
20
- id: number;
21
- focused: boolean;
22
- }
19
+ export interface SessionBindingWindow {
20
+ id: number;
21
+ focused: boolean;
22
+ initialTabId?: number | null;
23
+ }
23
24
 
24
25
  export interface SessionBindingGroup {
25
26
  id: number;
@@ -143,27 +144,31 @@ class SessionBindingManager {
143
144
  }
144
145
  }
145
146
  }
146
- if (!window) {
147
- const createdWindow = await this.browser.createWindow({
148
- url: initialUrl,
149
- focused: options.focus === true
150
- });
147
+ if (!window) {
148
+ const createdWindow = await this.browser.createWindow({
149
+ url: initialUrl,
150
+ focused: options.focus === true
151
+ });
151
152
  state.windowId = createdWindow.id;
152
- state.groupId = null;
153
- state.tabIds = [];
154
- state.activeTabId = null;
155
- state.primaryTabId = null;
156
- window = createdWindow;
157
- tabs = await this.waitForWindowTabs(createdWindow.id);
158
- state.tabIds = tabs.map((tab) => tab.id);
159
- if (state.primaryTabId === null) {
160
- state.primaryTabId = tabs[0]?.id ?? null;
161
- }
162
- if (state.activeTabId === null) {
163
- state.activeTabId = tabs.find((tab) => tab.active)?.id ?? tabs[0]?.id ?? null;
164
- }
165
- repairActions.push(created ? 'created-window' : 'recreated-window');
166
- }
153
+ state.groupId = null;
154
+ state.tabIds = [];
155
+ state.activeTabId = null;
156
+ state.primaryTabId = null;
157
+ window = createdWindow;
158
+ const initialTab =
159
+ typeof createdWindow.initialTabId === 'number'
160
+ ? await this.waitForTrackedTab(createdWindow.initialTabId, createdWindow.id)
161
+ : null;
162
+ tabs = initialTab ? [initialTab] : await this.waitForWindowTabs(createdWindow.id);
163
+ state.tabIds = tabs.map((tab) => tab.id);
164
+ if (state.primaryTabId === null) {
165
+ state.primaryTabId = initialTab?.id ?? tabs[0]?.id ?? null;
166
+ }
167
+ if (state.activeTabId === null) {
168
+ state.activeTabId = tabs.find((tab) => tab.active)?.id ?? initialTab?.id ?? tabs[0]?.id ?? null;
169
+ }
170
+ repairActions.push(created ? 'created-window' : 'recreated-window');
171
+ }
167
172
 
168
173
  tabs = tabs.length > 0 ? tabs : await this.readTrackedTabs(state.tabIds, state.windowId);
169
174
  const recoveredTabs = await this.recoverBindingTabs(state, tabs);
@@ -725,19 +730,21 @@ class SessionBindingManager {
725
730
  };
726
731
  }
727
732
 
728
- private async moveBindingIntoDedicatedWindow(
729
- state: SessionBindingRecord,
730
- ownership: SessionBindingWindowOwnership,
731
- initialUrl: string
732
- ): Promise<{ window: SessionBindingWindow; tabs: SessionBindingTab[] }> {
733
+ private async moveBindingIntoDedicatedWindow(
734
+ state: SessionBindingRecord,
735
+ ownership: SessionBindingWindowOwnership,
736
+ initialUrl: string
737
+ ): Promise<{ window: SessionBindingWindow; tabs: SessionBindingTab[] }> {
733
738
  const sourceTabs = this.orderSessionBindingTabsForMigration(state, ownership.bindingTabs);
734
739
  const seedUrl = sourceTabs[0]?.url ?? initialUrl;
735
- const window = await this.browser.createWindow({
736
- url: seedUrl || DEFAULT_SESSION_BINDING_URL,
737
- focused: false
738
- });
739
- const recreatedTabs = await this.waitForWindowTabs(window.id);
740
- const firstTab = recreatedTabs[0] ?? null;
740
+ const window = await this.browser.createWindow({
741
+ url: seedUrl || DEFAULT_SESSION_BINDING_URL,
742
+ focused: false
743
+ });
744
+ const initialTab =
745
+ typeof window.initialTabId === 'number' ? await this.waitForTrackedTab(window.initialTabId, window.id) : null;
746
+ const recreatedTabs = initialTab ? [initialTab] : await this.waitForWindowTabs(window.id);
747
+ const firstTab = recreatedTabs[0] ?? null;
741
748
  const tabIdMap = new Map<number, number>();
742
749
  if (sourceTabs[0] && firstTab) {
743
750
  tabIdMap.set(sourceTabs[0].id, firstTab.id);