aboutsummaryrefslogtreecommitdiff
path: root/src/domains/tabs.ts
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmal.com>2026-05-02 21:59:30 +0530
committeramankumarsingh77 <amankumarsingh7702@gmal.com>2026-05-02 21:59:30 +0530
commita1df2d3e0998e99176a4bfe3cffb83b9e6a2377e (patch)
treef84522e4f08fd6adeaf4954e09fc6e43a59d02f7 /src/domains/tabs.ts
parentc9d1605b1e3b8dbe88cd3674a9256aa0465f3e6d (diff)
release: v0.3.1 — audit fixes for list_tabs IDs, switch_tab prefix matching, download auto-mkdir, session recovery, docs updates
Bug fixes: - list_tabs: show full 32-char targetIds (was truncated to 8 chars) - switch_tab: prefix matching fallback for hex prefixes >= 8 chars - download: auto-create directory with mkdir -p - ensureAlive: Runtime.evaluate probe to recover from crashed page targets Docs: - dispatch_key: clarify DOM-only event behavior - navigate: warn about Google anti-bot limitation - network_log: update deprecated promptSnippet - SKILL.md: document actual daemon API (evaluateJs, pageInfo, session.call) - SKILL.md: add troubleshooting for sharp/maxDim and Google navigation - sharp: add to optionalDependencies for screenshot maxDim auto-resize
Diffstat (limited to 'src/domains/tabs.ts')
-rw-r--r--src/domains/tabs.ts42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/domains/tabs.ts b/src/domains/tabs.ts
index c9440fe..d2cd646 100644
--- a/src/domains/tabs.ts
+++ b/src/domains/tabs.ts
@@ -12,14 +12,15 @@ export const listTabsTool = defineBrowserTool({
description: "List all open browser tabs (page targets).",
promptSnippet: "List browser tabs",
promptGuidelines: [
- "Use to find a targetId for browser_switch_tab.",
+ "Use to find a full targetId for browser_switch_tab.",
"Internal tabs (chrome://) included by default; pass includeInternal=false to exclude them.",
+ "Each tab shows its full 32-char hex targetId — use the exact value with browser_switch_tab.",
],
parameters: ListTabsArgs,
async handler(args, { client }): Promise<Result<ToolOk, ToolErr>> {
const r = await client.listTabs(args.includeInternal ?? true);
if (!r.success) return err({ kind: "cdp_error", message: r.error.message });
- const lines = r.data.map((t, i) => ` [${i}] ${t.targetId.slice(0, 8)}… ${t.url}\n ${t.title}`);
+ const lines = r.data.map((t, i) => ` [${i}] ${t.targetId} ${t.url}\n ${t.title}`);
return ok({
text: `Tabs (${r.data.length}):\n${lines.join("\n")}`,
details: { tabs: r.data },
@@ -56,12 +57,43 @@ export const switchTabTool = defineBrowserTool({
label: "Browser Switch Tab",
description: "Switch to and attach to a different tab by targetId.",
promptSnippet: "Switch tabs",
- promptGuidelines: ["Get a targetId via browser_list_tabs first."],
+ promptGuidelines: [
+ "Get a targetId via browser_list_tabs first.",
+ "Accepts exact targetId or a unique prefix of at least 8 hex characters.",
+ ],
parameters: SwitchTabArgs,
async handler(args, { client }): Promise<Result<ToolOk, ToolErr>> {
- const r = await client.switchTab(args.targetId);
+ // Try exact match first
+ let r = await client.switchTab(args.targetId);
+ if (r.success) {
+ return ok({ text: `Switched to ${args.targetId}`, details: { targetId: args.targetId } });
+ }
+ // If exact match failed and input looks like a short prefix (≥8 hex chars), try prefix resolution
+ const isHexPrefix = /^[0-9A-Fa-f]{8,}$/.test(args.targetId);
+ if (!isHexPrefix) {
+ return err({ kind: "cdp_error", message: r.error.message });
+ }
+ const tabs = await client.listTabs(true);
+ if (!tabs.success) return err({ kind: "cdp_error", message: r.error.message });
+ const matches = tabs.data.filter((t) => t.targetId.startsWith(args.targetId));
+ if (matches.length === 0) {
+ return err({ kind: "cdp_error", message: `No tab found with prefix "${args.targetId}"` });
+ }
+ if (matches.length > 1) {
+ const ids = matches.map((t) => t.targetId).join(", ");
+ return err({
+ kind: "invalid_state",
+ message: `Ambiguous prefix "${args.targetId}" matches ${matches.length} tabs: ${ids}`,
+ details: { matches: matches.map((t) => ({ targetId: t.targetId, url: t.url })) },
+ });
+ }
+ const resolved = matches[0]!.targetId;
+ r = await client.switchTab(resolved);
if (!r.success) return err({ kind: "cdp_error", message: r.error.message });
- return ok({ text: `Switched to ${args.targetId}`, details: { targetId: args.targetId } });
+ return ok({
+ text: `Switched to ${resolved} (resolved from prefix "${args.targetId}")`,
+ details: { targetId: resolved, resolvedPrefix: args.targetId },
+ });
},
});