pi-chrome 0.15.39 → 0.15.40
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
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-facing changes to `pi-chrome`.
|
|
4
4
|
|
|
5
|
+
## 0.15.40 — 2026-06-22
|
|
6
|
+
|
|
7
|
+
- **Automation targets reuse the session tab group.** When `chrome_navigate` / implicit page actions create a new pi-chrome automation tab, it is now created in this session's existing tab-group window when possible and joins that same group, avoiding duplicate same-title `Pi Session: ...` groups.
|
|
8
|
+
|
|
5
9
|
## 0.15.39 — 2026-06-07
|
|
6
10
|
|
|
7
11
|
- **Dedicated automation tab/window (no more hijacking your active tab).** When a chrome_* action runs without an explicit target, pi-chrome now opens and reuses a dedicated automation window it owns (falling back to a dedicated tab if a separate window can't be created) instead of navigating whatever tab you currently have open. Your existing tabs/windows are left untouched. Pass `targetId`/`urlIncludes`/`titleIncludes` to act on a specific existing tab.
|
|
@@ -86,9 +86,19 @@ function isPiChromeOwnedTarget(tabId, sessionKey) {
|
|
|
86
86
|
return false;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
// Create a fresh
|
|
90
|
-
//
|
|
91
|
-
|
|
89
|
+
// Create a fresh automation target for `sessionKey`. If this session already has a tab group,
|
|
90
|
+
// create the tab inside that group's window so one Pi session keeps one Chrome tab group (Chrome
|
|
91
|
+
// groups cannot span windows). If no group exists yet, prefer an isolated window; fall back to a
|
|
92
|
+
// tab. When the tab is created in a pre-existing group window, leave windowId unset so cleanup only
|
|
93
|
+
// closes our tab, never that whole window.
|
|
94
|
+
async function createAutomationTarget(sessionKey, groupTitle) {
|
|
95
|
+
const existingGroup = groupTitle ? await findGroupRecordByTitle(groupTitle) : null;
|
|
96
|
+
if (existingGroup && typeof existingGroup.windowId === "number") {
|
|
97
|
+
const tab = await chrome.tabs.create({ url: "about:blank", active: false, windowId: existingGroup.windowId });
|
|
98
|
+
automationTargets.set(sessionKey, { windowId: undefined, tabId: typeof tab.id === "number" ? tab.id : undefined });
|
|
99
|
+
await persistAutomationTargets();
|
|
100
|
+
return tab;
|
|
101
|
+
}
|
|
92
102
|
if (chrome.windows && typeof chrome.windows.create === "function") {
|
|
93
103
|
try {
|
|
94
104
|
const win = await chrome.windows.create({ url: "about:blank", focused: false });
|
|
@@ -125,8 +135,8 @@ async function resolveOwnedAutomationTarget(sessionKey) {
|
|
|
125
135
|
|
|
126
136
|
// Return the session's dedicated automation target, creating it on first use (or after the user
|
|
127
137
|
// closed it). Used by page/navigation actions that need a live surface to drive.
|
|
128
|
-
async function getOrCreateAutomationTarget(sessionKey) {
|
|
129
|
-
return (await resolveOwnedAutomationTarget(sessionKey)) || createAutomationTarget(sessionKey);
|
|
138
|
+
async function getOrCreateAutomationTarget(sessionKey, groupTitle) {
|
|
139
|
+
return (await resolveOwnedAutomationTarget(sessionKey)) || createAutomationTarget(sessionKey, groupTitle);
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
// Close only the session's pi-chrome-owned window/tab, and only if it still exists. Never touches
|
|
@@ -1317,7 +1327,7 @@ async function getTabByParams(params, { createOwnedTarget = true } = {}) {
|
|
|
1317
1327
|
// existing tab pass targetId/urlIncludes/titleIncludes above.
|
|
1318
1328
|
const sessionKey = sessionKeyOf(params);
|
|
1319
1329
|
tab = createOwnedTarget
|
|
1320
|
-
? await getOrCreateAutomationTarget(sessionKey)
|
|
1330
|
+
? await getOrCreateAutomationTarget(sessionKey, params.sessionGroupTitle)
|
|
1321
1331
|
: await resolveOwnedAutomationTarget(sessionKey);
|
|
1322
1332
|
if (!tab) {
|
|
1323
1333
|
throw new Error(
|
package/package.json
CHANGED
|
@@ -232,6 +232,14 @@ async function run() {
|
|
|
232
232
|
const blankTitle = await w.dispatch("tab.new", { url: "https://pi.test/blank-title", groupTitle: "", group: false, sessionKey: SK });
|
|
233
233
|
ok(typeof blankTitle.tab.groupId === "number" && blankTitle.tab.groupId >= 0, "tab.new-group: groupTitle:'' still creates a grouped tab");
|
|
234
234
|
ok(blankTitle.group.title === "Pi", "tab.new-group: blank groupTitle falls back to a group instead of opting out");
|
|
235
|
+
|
|
236
|
+
const nav2 = await w.dispatch("page.navigate", {
|
|
237
|
+
url: "https://pi.test/new-automation-target", waitUntilLoad: false,
|
|
238
|
+
sessionKey: "session:beta", joinSessionGroup: true, sessionGroupTitle: groupTitle,
|
|
239
|
+
});
|
|
240
|
+
ok(state.groups.size === groupsBefore + 1, "automation-target-group: reused the existing session group, only blank-title Pi group was extra");
|
|
241
|
+
ok(nav2.groupId === groupId, "automation-target-group: new automation target joined the existing session group");
|
|
242
|
+
ok(nav2.windowId === nav.windowId, "automation-target-group: new automation target was created in the existing group's window");
|
|
235
243
|
}
|
|
236
244
|
|
|
237
245
|
// ===== tab.new never leaves an ungrouped tab behind when grouping fails. =====
|