feat: CDP bridge batch support - cookies/tabs/cdp mixed commands, lazy attach, $N chain refs, file upload & screenshot verified
This commit is contained in:
@@ -10,6 +10,10 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
||||
handleCDP(msg, sender).then(sendResponse);
|
||||
return true;
|
||||
}
|
||||
if (msg.action === 'batch') {
|
||||
handleBatch(msg, sender).then(sendResponse);
|
||||
return true;
|
||||
}
|
||||
if (msg.action === 'tabs') {
|
||||
(async () => {
|
||||
try {
|
||||
@@ -44,6 +48,38 @@ async function handleCookies(msg, sender) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleBatch(msg, sender) {
|
||||
const R = [];
|
||||
let attached = null;
|
||||
const resolve$N = (params) => JSON.parse(JSON.stringify(params || {}).replace(/"\$(\d+)\.([^"]+)"/g,
|
||||
(_, i, path) => { let v = R[+i]; for (const k of path.split('.')) v = v[k]; return JSON.stringify(v); }));
|
||||
try {
|
||||
for (const c of msg.commands) {
|
||||
if (c.cmd === 'cookies') {
|
||||
R.push(await handleCookies(c, sender));
|
||||
} else if (c.cmd === 'tabs') {
|
||||
const tabs = await chrome.tabs.query({});
|
||||
R.push({ ok: true, data: tabs.map(t => ({ id: t.id, url: t.url, title: t.title, active: t.active, windowId: t.windowId })) });
|
||||
} else if (c.cmd === 'cdp') {
|
||||
const tabId = c.tabId || msg.tabId || sender.tab?.id;
|
||||
if (attached !== tabId) {
|
||||
if (attached) { await chrome.debugger.detach({ tabId: attached }); attached = null; }
|
||||
await chrome.debugger.attach({ tabId }, '1.3');
|
||||
attached = tabId;
|
||||
}
|
||||
R.push(await chrome.debugger.sendCommand({ tabId }, c.method, resolve$N(c.params)));
|
||||
} else {
|
||||
R.push({ ok: false, error: 'unknown cmd: ' + c.cmd });
|
||||
}
|
||||
}
|
||||
if (attached) await chrome.debugger.detach({ tabId: attached });
|
||||
return { ok: true, results: R };
|
||||
} catch (e) {
|
||||
if (attached) try { await chrome.debugger.detach({ tabId: attached }); } catch (_) {}
|
||||
return { ok: false, error: e.message, results: R };
|
||||
}
|
||||
}
|
||||
|
||||
async function handleCDP(msg, sender) {
|
||||
const tabId = msg.tabId || sender.tab?.id;
|
||||
if (!tabId) return { ok: false, error: 'no tabId' };
|
||||
|
||||
@@ -19,6 +19,8 @@ async function handle(el) {
|
||||
resp = await chrome.runtime.sendMessage({ action: 'cookies', url: req.url || location.href });
|
||||
} else if (cmd === 'cdp') {
|
||||
resp = await chrome.runtime.sendMessage({ action: 'cdp', method: req.method, params: req.params || {}, tabId: req.tabId });
|
||||
} else if (cmd === 'batch') {
|
||||
resp = await chrome.runtime.sendMessage({ action: 'batch', commands: req.commands, tabId: req.tabId });
|
||||
} else if (cmd === 'tabs') {
|
||||
resp = await chrome.runtime.sendMessage({ action: 'tabs', method: req.method, tabId: req.tabId });
|
||||
} else {
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
"description": "万能网页操控工具。通过执行 JavaScript 脚本实现对浏览器的完全控制(如点击、滚动、提取特定数据)。鼓励在有把握情况下(记忆中有selector/做法等)精准使用以减少web_scan调用。执行结果可选择保存到本地文件进行后续分析。",
|
||||
"parameters": {"type": "object", "properties": {
|
||||
"script": {"type": "string", "description": "要执行的 JavaScript 代码或JS文件路径。"},
|
||||
"save_to_file": {"type": "string", "description": "可选。将 JS 执行结果(js_return)保存到的文件路径。该功能不支持 await 等异步结果。"}}, "required": ["script"]}
|
||||
"save_to_file": {"type": "string", "description": "结果存文件,适合返回值较长时。不支持await。", "default": ""},
|
||||
"no_monitor": {"type": "boolean", "description": "跳过页面变更监控,仅读取信息时用,省2-3秒。", "default": false}}, "required": ["script"]}
|
||||
}},
|
||||
{"type": "function", "function": {
|
||||
"name": "update_working_checkpoint",
|
||||
|
||||
Reference in New Issue
Block a user