@jobshimo/browser-link 0.8.2 → 0.9.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.
- package/dist/agent-instructions/content.js +42 -27
- package/dist/agent-instructions/content.js.map +1 -1
- package/dist/agent-instructions/file-ops.js +7 -2
- package/dist/agent-instructions/file-ops.js.map +1 -1
- package/dist/bridge/events.d.ts +3 -0
- package/dist/bridge/events.js +8 -0
- package/dist/bridge/events.js.map +1 -1
- package/dist/commands/doctor.js +30 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/update-check.d.ts +25 -0
- package/dist/commands/update-check.js +108 -0
- package/dist/commands/update-check.js.map +1 -0
- package/dist/commands/welcome.d.ts +15 -0
- package/dist/commands/welcome.js +44 -2
- package/dist/commands/welcome.js.map +1 -1
- package/dist/extension/background.js +37 -1
- package/dist/extension/background.js.map +1 -1
- package/dist/extension/manifest.json +1 -1
- package/dist/extension/popup.d.ts +2 -1
- package/dist/extension/popup.html +128 -50
- package/dist/extension/popup.js +22 -3
- package/dist/extension/popup.js.map +1 -1
- package/dist/map/tools.d.ts +1 -5
- package/dist/map/tools.js +45 -0
- package/dist/map/tools.js.map +1 -1
- package/dist/server.js +42 -36
- package/dist/server.js.map +1 -1
- package/dist/tools/browser-definitions.d.ts +6 -0
- package/dist/tools/browser-definitions.js +150 -0
- package/dist/tools/browser-definitions.js.map +1 -1
- package/dist/tools/browser-dispatch.d.ts +8 -14
- package/dist/tools/browser-dispatch.js +10 -0
- package/dist/tools/browser-dispatch.js.map +1 -1
- package/dist/tools/server-instructions.d.ts +16 -2
- package/dist/tools/server-instructions.js +87 -68
- package/dist/tools/server-instructions.js.map +1 -1
- package/dist/tools/tab-claims.d.ts +5 -1
- package/dist/tools/tab-claims.js +17 -0
- package/dist/tools/tab-claims.js.map +1 -1
- package/dist/tools/types.d.ts +26 -1
- package/dist/ui/app.js +40 -5
- package/dist/ui/app.js.map +1 -1
- package/dist/ui/components.d.ts +15 -3
- package/dist/ui/components.js +34 -14
- package/dist/ui/components.js.map +1 -1
- package/dist/ui/hooks/use-update-check.d.ts +16 -0
- package/dist/ui/hooks/use-update-check.js +48 -0
- package/dist/ui/hooks/use-update-check.js.map +1 -0
- package/dist/ui/primitives/badge.d.ts +11 -0
- package/dist/ui/primitives/badge.js +35 -0
- package/dist/ui/primitives/badge.js.map +1 -0
- package/dist/ui/primitives/check-row.d.ts +11 -0
- package/dist/ui/primitives/check-row.js +10 -0
- package/dist/ui/primitives/check-row.js.map +1 -0
- package/dist/ui/primitives/footer-keys.d.ts +12 -0
- package/dist/ui/primitives/footer-keys.js +11 -0
- package/dist/ui/primitives/footer-keys.js.map +1 -0
- package/dist/ui/primitives/index.d.ts +8 -0
- package/dist/ui/primitives/index.js +13 -0
- package/dist/ui/primitives/index.js.map +1 -0
- package/dist/ui/primitives/inline-spinner.d.ts +7 -0
- package/dist/ui/primitives/inline-spinner.js +23 -0
- package/dist/ui/primitives/inline-spinner.js.map +1 -0
- package/dist/ui/primitives/key-cap.d.ts +6 -0
- package/dist/ui/primitives/key-cap.js +6 -0
- package/dist/ui/primitives/key-cap.js.map +1 -0
- package/dist/ui/primitives/menu-row.d.ts +17 -0
- package/dist/ui/primitives/menu-row.js +8 -0
- package/dist/ui/primitives/menu-row.js.map +1 -0
- package/dist/ui/primitives/section-head.d.ts +11 -0
- package/dist/ui/primitives/section-head.js +7 -0
- package/dist/ui/primitives/section-head.js.map +1 -0
- package/dist/ui/primitives/status-bar.d.ts +13 -0
- package/dist/ui/primitives/status-bar.js +17 -0
- package/dist/ui/primitives/status-bar.js.map +1 -0
- package/dist/ui/screens/about.js +13 -4
- package/dist/ui/screens/about.js.map +1 -1
- package/dist/ui/screens/agent-instructions.d.ts +7 -1
- package/dist/ui/screens/agent-instructions.js +62 -46
- package/dist/ui/screens/agent-instructions.js.map +1 -1
- package/dist/ui/screens/client-picker.js +64 -16
- package/dist/ui/screens/client-picker.js.map +1 -1
- package/dist/ui/screens/doctor.js +20 -7
- package/dist/ui/screens/doctor.js.map +1 -1
- package/dist/ui/screens/empty-clients.d.ts +8 -0
- package/dist/ui/screens/empty-clients.js +57 -0
- package/dist/ui/screens/empty-clients.js.map +1 -0
- package/dist/ui/screens/extension.js +25 -8
- package/dist/ui/screens/extension.js.map +1 -1
- package/dist/ui/screens/free-port.js +48 -33
- package/dist/ui/screens/free-port.js.map +1 -1
- package/dist/ui/screens/index.d.ts +2 -0
- package/dist/ui/screens/index.js +2 -0
- package/dist/ui/screens/index.js.map +1 -1
- package/dist/ui/screens/install-result.js +29 -6
- package/dist/ui/screens/install-result.js.map +1 -1
- package/dist/ui/screens/language.js +39 -18
- package/dist/ui/screens/language.js.map +1 -1
- package/dist/ui/screens/menu.d.ts +10 -1
- package/dist/ui/screens/menu.js +118 -30
- package/dist/ui/screens/menu.js.map +1 -1
- package/dist/ui/screens/multi-agent.js +24 -18
- package/dist/ui/screens/multi-agent.js.map +1 -1
- package/dist/ui/screens/permissions.js +145 -33
- package/dist/ui/screens/permissions.js.map +1 -1
- package/dist/ui/screens/port-collision.d.ts +18 -0
- package/dist/ui/screens/port-collision.js +95 -0
- package/dist/ui/screens/port-collision.js.map +1 -0
- package/dist/ui/screens/updates.js +44 -21
- package/dist/ui/screens/updates.js.map +1 -1
- package/dist/ui/screens/welcome.js +56 -26
- package/dist/ui/screens/welcome.js.map +1 -1
- package/dist/ui/tokens.d.ts +37 -0
- package/dist/ui/tokens.js +58 -0
- package/dist/ui/tokens.js.map +1 -0
- package/package.json +1 -1
package/dist/map/tools.js
CHANGED
|
@@ -19,6 +19,18 @@ export const MAP_TOOL_DEFINITIONS = [
|
|
|
19
19
|
required: ['origin'],
|
|
20
20
|
additionalProperties: false,
|
|
21
21
|
},
|
|
22
|
+
doc: {
|
|
23
|
+
purpose: 'Reload selectors, flows and gotchas you previously learned about an app, so you do not rediscover them every session.',
|
|
24
|
+
when_to_use: [
|
|
25
|
+
'On any non-trivial debugging session on a web app the user mentioned — call this with the tab origin BEFORE speculating.',
|
|
26
|
+
'When you arrive at a tab and need to know "what do I already know about this app".',
|
|
27
|
+
],
|
|
28
|
+
gotchas: [
|
|
29
|
+
'If recall returns entries with failed_at more recent than verified_at, treat them as suspect — re-verify with snapshot before reusing.',
|
|
30
|
+
'After every interaction that used a map entry, call browser.map.record_use with { entry_id, ok } so the map stays honest.',
|
|
31
|
+
],
|
|
32
|
+
example: 'browser.map.recall({ origin: "https://app.example.com" })',
|
|
33
|
+
},
|
|
22
34
|
},
|
|
23
35
|
{
|
|
24
36
|
name: 'browser.map.save',
|
|
@@ -52,6 +64,18 @@ export const MAP_TOOL_DEFINITIONS = [
|
|
|
52
64
|
required: ['origin', 'url_pattern', 'kind', 'purpose', 'payload'],
|
|
53
65
|
additionalProperties: false,
|
|
54
66
|
},
|
|
67
|
+
doc: {
|
|
68
|
+
purpose: 'Persist UI structure you just discovered — a selector, a multi-step flow, or a gotcha — keyed by app and url pattern.',
|
|
69
|
+
when_to_use: [
|
|
70
|
+
'After a non-trivial flow worked end-to-end (opened a dialog, completed a form, found a setting).',
|
|
71
|
+
],
|
|
72
|
+
gotchas: [
|
|
73
|
+
'NEVER save selectors or flows you have not just successfully executed.',
|
|
74
|
+
'NEVER store domain data (IDs, user names, dates, etc.). The map captures UI structure only.',
|
|
75
|
+
'Use url_pattern = exact pathname by default; only promote to a glob if you have evidence of a parametric route.',
|
|
76
|
+
'Give `purpose` a stable, reusable label ("open task detail dialog", not "open IB0311 detail").',
|
|
77
|
+
],
|
|
78
|
+
},
|
|
55
79
|
},
|
|
56
80
|
{
|
|
57
81
|
name: 'browser.map.record_use',
|
|
@@ -66,6 +90,13 @@ export const MAP_TOOL_DEFINITIONS = [
|
|
|
66
90
|
required: ['entry_id', 'ok'],
|
|
67
91
|
additionalProperties: false,
|
|
68
92
|
},
|
|
93
|
+
doc: {
|
|
94
|
+
purpose: 'Update verified_at / failed_at on a map entry after you reused it, so the next agent knows whether it still works.',
|
|
95
|
+
when_to_use: ['Right after using any selector or flow you got from browser.map.recall.'],
|
|
96
|
+
gotchas: [
|
|
97
|
+
'ok:true updates verified_at and clears failed_at. ok:false updates failed_at — keep the map honest about what works today.',
|
|
98
|
+
],
|
|
99
|
+
},
|
|
69
100
|
},
|
|
70
101
|
{
|
|
71
102
|
name: 'browser.map.forget',
|
|
@@ -79,6 +110,10 @@ export const MAP_TOOL_DEFINITIONS = [
|
|
|
79
110
|
},
|
|
80
111
|
additionalProperties: false,
|
|
81
112
|
},
|
|
113
|
+
doc: {
|
|
114
|
+
purpose: 'Delete a stale map entry, or wipe a whole app, after a refactor invalidated it.',
|
|
115
|
+
when_to_use: ['A whole app got refactored and the saved knowledge is now actively wrong.'],
|
|
116
|
+
},
|
|
82
117
|
},
|
|
83
118
|
{
|
|
84
119
|
name: 'browser.map.rename_app',
|
|
@@ -92,11 +127,21 @@ export const MAP_TOOL_DEFINITIONS = [
|
|
|
92
127
|
required: ['app_id', 'new_app_key'],
|
|
93
128
|
additionalProperties: false,
|
|
94
129
|
},
|
|
130
|
+
doc: {
|
|
131
|
+
purpose: 'Rename the app_key for an app row when the title-derived slug is wrong.',
|
|
132
|
+
when_to_use: [
|
|
133
|
+
'The initial slug derived from document.title is misleading (typo, generic name).',
|
|
134
|
+
],
|
|
135
|
+
},
|
|
95
136
|
},
|
|
96
137
|
{
|
|
97
138
|
name: 'browser.map.apps',
|
|
98
139
|
description: 'List apps currently tracked in the map, most recently used first. Use to discover known origins and their app_keys.',
|
|
99
140
|
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
141
|
+
doc: {
|
|
142
|
+
purpose: 'List every app currently tracked in the map, most recently used first.',
|
|
143
|
+
when_to_use: ['To discover which origins/app_keys the map already knows about.'],
|
|
144
|
+
},
|
|
100
145
|
},
|
|
101
146
|
];
|
|
102
147
|
export function isMapTool(name) {
|
package/dist/map/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/map/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,QAAQ,EACR,MAAM,EACN,SAAS,EACT,SAAS,EACT,SAAS,GAEV,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/map/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -26,41 +26,6 @@ function buildListTabs(tabs) {
|
|
|
26
26
|
title: t.title,
|
|
27
27
|
}));
|
|
28
28
|
}
|
|
29
|
-
/**
|
|
30
|
-
* When the MCP client (Claude / OpenCode / Copilot) closes the stdio pipe,
|
|
31
|
-
* the OS does NOT reliably deliver SIGTERM to this child — especially on
|
|
32
|
-
* Windows, where signal forwarding from parent to child is best-effort.
|
|
33
|
-
* Without this guard the server stays alive holding port 17529, and the
|
|
34
|
-
* next client crashes with EADDRINUSE.
|
|
35
|
-
*
|
|
36
|
-
* Listening on `end`/`close` of stdin covers both roles (primary and proxy)
|
|
37
|
-
* because both depend on the parent's stdio remaining open. The handler is
|
|
38
|
-
* installed at the very top of runServer() so it's active during any
|
|
39
|
-
* pre-bind awaits as well.
|
|
40
|
-
*/
|
|
41
|
-
function installParentDeathGuard() {
|
|
42
|
-
let exiting = false;
|
|
43
|
-
const onParentGone = () => {
|
|
44
|
-
if (exiting)
|
|
45
|
-
return;
|
|
46
|
-
exiting = true;
|
|
47
|
-
try {
|
|
48
|
-
closeDb();
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
// Best effort during shutdown — the OS reclaims the handle on exit.
|
|
52
|
-
}
|
|
53
|
-
process.exit(0);
|
|
54
|
-
};
|
|
55
|
-
process.stdin.once('end', onParentGone);
|
|
56
|
-
process.stdin.once('close', onParentGone);
|
|
57
|
-
// Some Node versions on Windows surface parent-closed-stdio as an EPIPE
|
|
58
|
-
// on stdout writes. Don't crash the process for that — exit cleanly.
|
|
59
|
-
process.stdout.on('error', (err) => {
|
|
60
|
-
if (err.code === 'EPIPE')
|
|
61
|
-
onParentGone();
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
29
|
/**
|
|
65
30
|
* Entry point used by the MCP client over stdio. Decides whether THIS
|
|
66
31
|
* process becomes the primary (binds 17529, runs the WS bridge + MCP
|
|
@@ -69,7 +34,13 @@ function installParentDeathGuard() {
|
|
|
69
34
|
* forwards MCP stdio frames to the primary over IPC.
|
|
70
35
|
*/
|
|
71
36
|
export async function runServer() {
|
|
72
|
-
|
|
37
|
+
// The bridge stays alive when the MCP client closes its stdio. The
|
|
38
|
+
// connected Chrome tabs keep talking to the WS bridge until the user
|
|
39
|
+
// explicitly disconnects them from the extension popup, or the WS
|
|
40
|
+
// hits its inactivity TTL on the client side. If a zombie ever holds
|
|
41
|
+
// 17529 after a crash, `runPrimary` falls back to proxy mode (when
|
|
42
|
+
// multi-agent is on) or surfaces a clean EADDRINUSE error pointing
|
|
43
|
+
// the user at `browser-link stop`.
|
|
73
44
|
const cfg = loadConfig();
|
|
74
45
|
try {
|
|
75
46
|
await runPrimary(cfg);
|
|
@@ -148,6 +119,41 @@ async function runPrimary(cfg) {
|
|
|
148
119
|
callBrowserTool: buildCallBrowserTool(tabs, pendingRequests),
|
|
149
120
|
recentEvents: (opts) => events.recent(opts),
|
|
150
121
|
tabClaims,
|
|
122
|
+
resetBridge: () => {
|
|
123
|
+
// Close every WS to the extension first so the client side flips to
|
|
124
|
+
// "Not connected" before we drop the local state. Best-effort: a tab
|
|
125
|
+
// whose socket already died just no-ops.
|
|
126
|
+
const droppedTabs = tabs.size;
|
|
127
|
+
for (const session of tabs.values()) {
|
|
128
|
+
try {
|
|
129
|
+
session.ws.close();
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
/* socket already gone */
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
tabs.clear();
|
|
136
|
+
// Reject every pending tool request so the caller does not hang.
|
|
137
|
+
for (const pending of pendingRequests.values()) {
|
|
138
|
+
clearTimeout(pending.timeout);
|
|
139
|
+
pending.reject(new Error('browser.reset: bridge state was wiped'));
|
|
140
|
+
}
|
|
141
|
+
pendingRequests.clear();
|
|
142
|
+
const releasedClaims = tabClaims.releaseAll().length;
|
|
143
|
+
const clearedEvents = events.clear();
|
|
144
|
+
// First event of the fresh state — keeps `browser.events` honest.
|
|
145
|
+
events.add('primary-elected', {
|
|
146
|
+
pid: process.pid,
|
|
147
|
+
multiAgent: cfg.multiAgent === true,
|
|
148
|
+
reason: 'reset',
|
|
149
|
+
});
|
|
150
|
+
log(`browser.reset: dropped ${droppedTabs} tab(s), released ${releasedClaims} claim(s), cleared ${clearedEvents} event(s).`);
|
|
151
|
+
return {
|
|
152
|
+
dropped_tabs: droppedTabs,
|
|
153
|
+
released_claims: releasedClaims,
|
|
154
|
+
cleared_events: clearedEvents,
|
|
155
|
+
};
|
|
156
|
+
},
|
|
151
157
|
};
|
|
152
158
|
// The primary's own MCP client (Claude/Copilot/OpenCode connecting via stdio
|
|
153
159
|
// directly to THIS process) always uses this caller identity. Proxies that
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,OAAO,EACP,OAAO,EACP,WAAW,EACX,eAAe,EACf,aAAa,GAGd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAE5B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,SAAS,GAAG,CAAC,GAAW;IACtB,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAA6B,EAC7B,eAA4C;IAE5C,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAG,kBAAkB,EAAE,EAAE,CAC7D,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,aAAa,CAAC,IAA6B;IAClD,OAAO,GAAG,EAAE,CACV,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,MAAM,EAAE,CAAC,CAAC,KAAK;QACf,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC,CAAC,CAAC;AACR,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
* MCP tool definitions for the browser-bridge family. Kept separate from
|
|
3
3
|
* the runtime dispatcher so the JSON schemas stay reviewable in one place
|
|
4
4
|
* and the dispatch logic stays small.
|
|
5
|
+
*
|
|
6
|
+
* Each entry carries a `doc` block (`ToolDoc`) with structured human-facing
|
|
7
|
+
* documentation. `buildServerInstructions()` reads those blocks to produce
|
|
8
|
+
* the SERVER_INSTRUCTIONS string the MCP host receives on `initialize`. The
|
|
9
|
+
* structured shape keeps the "when to use" copy beside the tool that owns
|
|
10
|
+
* it instead of drifting in a single monolithic string.
|
|
5
11
|
*/
|
|
6
12
|
import type { ToolDefinition } from './types.js';
|
|
7
13
|
export declare const BROWSER_TOOL_DEFINITIONS: ToolDefinition[];
|
|
@@ -2,12 +2,29 @@
|
|
|
2
2
|
* MCP tool definitions for the browser-bridge family. Kept separate from
|
|
3
3
|
* the runtime dispatcher so the JSON schemas stay reviewable in one place
|
|
4
4
|
* and the dispatch logic stays small.
|
|
5
|
+
*
|
|
6
|
+
* Each entry carries a `doc` block (`ToolDoc`) with structured human-facing
|
|
7
|
+
* documentation. `buildServerInstructions()` reads those blocks to produce
|
|
8
|
+
* the SERVER_INSTRUCTIONS string the MCP host receives on `initialize`. The
|
|
9
|
+
* structured shape keeps the "when to use" copy beside the tool that owns
|
|
10
|
+
* it instead of drifting in a single monolithic string.
|
|
5
11
|
*/
|
|
6
12
|
export const BROWSER_TOOL_DEFINITIONS = [
|
|
7
13
|
{
|
|
8
14
|
name: 'browser.list_tabs',
|
|
9
15
|
description: 'List Chrome tabs currently connected to browser-link. A tab is connected only after the user clicks Connect in the extension popup. Each entry includes tab_id, url, title, claimed_by (null when free, or { agent_id, pid, binary, label?, claimed_at, last_activity_at } when another agent owns it) and claimed_by_me (true when YOU hold the claim).',
|
|
10
16
|
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
17
|
+
doc: {
|
|
18
|
+
purpose: 'List the Chrome tabs the user has explicitly connected through the browser-link extension popup.',
|
|
19
|
+
when_to_use: [
|
|
20
|
+
'Before doing anything on a tab whose state you do not already own.',
|
|
21
|
+
'When the user mentions a UI bug, web page, or asks "does X work" — call this FIRST.',
|
|
22
|
+
'To see which tabs are claimed by other agents (claimed_by) and which are yours (claimed_by_me).',
|
|
23
|
+
],
|
|
24
|
+
gotchas: [
|
|
25
|
+
'Returns only tabs the user has connected manually. If the list is empty the user has not connected anything yet — ask them to open the extension popup.',
|
|
26
|
+
],
|
|
27
|
+
},
|
|
11
28
|
},
|
|
12
29
|
{
|
|
13
30
|
name: 'browser.claim_tab',
|
|
@@ -28,6 +45,18 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
28
45
|
required: ['tab_id'],
|
|
29
46
|
additionalProperties: false,
|
|
30
47
|
},
|
|
48
|
+
doc: {
|
|
49
|
+
purpose: 'Reserve a tab cooperatively so other MCP clients sharing the bridge see it is in use.',
|
|
50
|
+
when_to_use: [
|
|
51
|
+
'Before a multi-step flow on a tab in multi-agent mode, so other agents see you working on it.',
|
|
52
|
+
'To refresh the inactivity TTL or update the display label on a tab you already hold.',
|
|
53
|
+
],
|
|
54
|
+
gotchas: [
|
|
55
|
+
'Action tools (click/type/navigate/evaluate) auto-claim a free tab on first use, so explicit claim_tab is only required for early reservation.',
|
|
56
|
+
'On conflict the response includes the existing claim — do NOT spin-retry; pick a different tab or surface the conflict to the user.',
|
|
57
|
+
],
|
|
58
|
+
example: 'browser.claim_tab({ tab_id: "tab_1", label: "claude-code", ttl_minutes: 15 })',
|
|
59
|
+
},
|
|
31
60
|
},
|
|
32
61
|
{
|
|
33
62
|
name: 'browser.release_tab',
|
|
@@ -38,11 +67,27 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
38
67
|
required: ['tab_id'],
|
|
39
68
|
additionalProperties: false,
|
|
40
69
|
},
|
|
70
|
+
doc: {
|
|
71
|
+
purpose: 'Hand a previously claimed tab back so another agent can take it.',
|
|
72
|
+
when_to_use: [
|
|
73
|
+
'After you finished working on a tab and want to hand it off before the TTL expires.',
|
|
74
|
+
],
|
|
75
|
+
gotchas: [
|
|
76
|
+
'Claims also auto-release on agent disconnect and after the inactivity TTL (default 10 minutes) — explicit release is only for early hand-off.',
|
|
77
|
+
],
|
|
78
|
+
},
|
|
41
79
|
},
|
|
42
80
|
{
|
|
43
81
|
name: 'browser.my_tabs',
|
|
44
82
|
description: 'List the tabs YOU currently hold a claim on. Returns { claims: [{ tab_id, claimed_at, last_activity_at, ttl_ms, label? }] } sorted by claimed_at. Use this to answer the user when they ask which tabs you are working on.',
|
|
45
83
|
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
84
|
+
doc: {
|
|
85
|
+
purpose: 'Return the tabs the current agent has claimed, with timestamps and TTL.',
|
|
86
|
+
when_to_use: [
|
|
87
|
+
'When the user asks which tab you are using ("¿qué pestaña tenés?", "which tab are you on?").',
|
|
88
|
+
'To verify which tab is yours before performing an action in multi-agent mode.',
|
|
89
|
+
],
|
|
90
|
+
},
|
|
46
91
|
},
|
|
47
92
|
{
|
|
48
93
|
name: 'browser.ping',
|
|
@@ -53,6 +98,10 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
53
98
|
required: ['tab_id'],
|
|
54
99
|
additionalProperties: false,
|
|
55
100
|
},
|
|
101
|
+
doc: {
|
|
102
|
+
purpose: 'Confirm the bridge to a specific tab is healthy and read back its title/url.',
|
|
103
|
+
when_to_use: ['When you suspect a tab may have been closed or disconnected between calls.'],
|
|
104
|
+
},
|
|
56
105
|
},
|
|
57
106
|
{
|
|
58
107
|
name: 'browser.navigate',
|
|
@@ -67,6 +116,17 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
67
116
|
required: ['tab_id', 'url'],
|
|
68
117
|
additionalProperties: false,
|
|
69
118
|
},
|
|
119
|
+
doc: {
|
|
120
|
+
purpose: 'Drive a connected tab to a new URL.',
|
|
121
|
+
when_to_use: [
|
|
122
|
+
'The user asks you to open a page in the browser ("abrí esto en el navegador", "navigate to X").',
|
|
123
|
+
'You need to reach a specific route before snapshotting or interacting.',
|
|
124
|
+
],
|
|
125
|
+
gotchas: [
|
|
126
|
+
'Defaults to wait_for_load=true so the snapshot you take next reflects the loaded page.',
|
|
127
|
+
],
|
|
128
|
+
example: 'browser.navigate({ tab_id: "tab_1", url: "https://example.com" })',
|
|
129
|
+
},
|
|
70
130
|
},
|
|
71
131
|
{
|
|
72
132
|
name: 'browser.snapshot',
|
|
@@ -77,6 +137,17 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
77
137
|
required: ['tab_id'],
|
|
78
138
|
additionalProperties: false,
|
|
79
139
|
},
|
|
140
|
+
doc: {
|
|
141
|
+
purpose: 'Inspect what is currently on the tab — title, URL, visible text, interactive elements with selectors.',
|
|
142
|
+
when_to_use: [
|
|
143
|
+
'Before suggesting any code change to a UI component — verify the current state, do NOT speculate.',
|
|
144
|
+
'Before clicking or typing, to find a stable selector for the target element.',
|
|
145
|
+
'When the user reports a layout or visual issue and you need to ground your reasoning in what is actually rendered.',
|
|
146
|
+
],
|
|
147
|
+
gotchas: [
|
|
148
|
+
'The snapshot is the source of truth; the persistent map is a cache, not a substitute.',
|
|
149
|
+
],
|
|
150
|
+
},
|
|
80
151
|
},
|
|
81
152
|
{
|
|
82
153
|
name: 'browser.console',
|
|
@@ -90,6 +161,16 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
90
161
|
required: ['tab_id'],
|
|
91
162
|
additionalProperties: false,
|
|
92
163
|
},
|
|
164
|
+
doc: {
|
|
165
|
+
purpose: 'Read recent console messages from the tab — log, info, warn, error, debug.',
|
|
166
|
+
when_to_use: [
|
|
167
|
+
'When the user says "the button does not work" or "something is broken" — check console errors first.',
|
|
168
|
+
'After an action to see what the page logged in response.',
|
|
169
|
+
],
|
|
170
|
+
gotchas: [
|
|
171
|
+
'Rolling buffer of 200 entries — older logs are dropped. Snapshot console output early in a long session.',
|
|
172
|
+
],
|
|
173
|
+
},
|
|
93
174
|
},
|
|
94
175
|
{
|
|
95
176
|
name: 'browser.network',
|
|
@@ -103,6 +184,17 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
103
184
|
required: ['tab_id'],
|
|
104
185
|
additionalProperties: false,
|
|
105
186
|
},
|
|
187
|
+
doc: {
|
|
188
|
+
purpose: 'List recent network requests with status, mime, size and timing.',
|
|
189
|
+
when_to_use: [
|
|
190
|
+
'When the user reports a failed API call, slow request, or a 4xx/5xx response in the page.',
|
|
191
|
+
'To verify whether a request fired after a click or form submission.',
|
|
192
|
+
],
|
|
193
|
+
gotchas: [
|
|
194
|
+
'Rolling buffer of 200 entries — pair with url_filter to narrow the result.',
|
|
195
|
+
'Use browser.network_body with the request_id to fetch a specific response body.',
|
|
196
|
+
],
|
|
197
|
+
},
|
|
106
198
|
},
|
|
107
199
|
{
|
|
108
200
|
name: 'browser.network_body',
|
|
@@ -116,6 +208,12 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
116
208
|
required: ['tab_id', 'request_id'],
|
|
117
209
|
additionalProperties: false,
|
|
118
210
|
},
|
|
211
|
+
doc: {
|
|
212
|
+
purpose: 'Fetch the response body for one request_id returned by browser.network.',
|
|
213
|
+
when_to_use: [
|
|
214
|
+
'After identifying a suspicious request in browser.network, to see what the server returned.',
|
|
215
|
+
],
|
|
216
|
+
},
|
|
119
217
|
},
|
|
120
218
|
{
|
|
121
219
|
name: 'browser.click',
|
|
@@ -129,6 +227,16 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
129
227
|
required: ['tab_id', 'selector'],
|
|
130
228
|
additionalProperties: false,
|
|
131
229
|
},
|
|
230
|
+
doc: {
|
|
231
|
+
purpose: 'Click an element identified by a CSS selector.',
|
|
232
|
+
when_to_use: [
|
|
233
|
+
'After browser.snapshot returned a selector for the element the user asked you to interact with.',
|
|
234
|
+
],
|
|
235
|
+
gotchas: [
|
|
236
|
+
'Never click a selector you have not just verified via browser.snapshot or browser.map.recall — speculating wastes a turn.',
|
|
237
|
+
'Auto-claims the tab on first use in multi-agent mode.',
|
|
238
|
+
],
|
|
239
|
+
},
|
|
132
240
|
},
|
|
133
241
|
{
|
|
134
242
|
name: 'browser.type',
|
|
@@ -144,6 +252,15 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
144
252
|
required: ['tab_id', 'selector', 'text'],
|
|
145
253
|
additionalProperties: false,
|
|
146
254
|
},
|
|
255
|
+
doc: {
|
|
256
|
+
purpose: 'Focus an input element by selector and type text into it.',
|
|
257
|
+
when_to_use: [
|
|
258
|
+
'After browser.snapshot returned a selector for the input the user wants filled.',
|
|
259
|
+
],
|
|
260
|
+
gotchas: [
|
|
261
|
+
'Pass clear:true when you need to replace the current value instead of appending to it.',
|
|
262
|
+
],
|
|
263
|
+
},
|
|
147
264
|
},
|
|
148
265
|
{
|
|
149
266
|
name: 'browser.evaluate',
|
|
@@ -157,6 +274,13 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
157
274
|
required: ['tab_id', 'expression'],
|
|
158
275
|
additionalProperties: false,
|
|
159
276
|
},
|
|
277
|
+
doc: {
|
|
278
|
+
purpose: 'Execute a JavaScript expression in the page and return its value.',
|
|
279
|
+
when_to_use: [
|
|
280
|
+
'When snapshot/click/type are not expressive enough — pulling a computed value, reading a JS variable, or invoking page APIs.',
|
|
281
|
+
],
|
|
282
|
+
gotchas: ['Wrap multi-step logic in an IIFE that returns the value you want.'],
|
|
283
|
+
},
|
|
160
284
|
},
|
|
161
285
|
{
|
|
162
286
|
name: 'browser.events',
|
|
@@ -175,6 +299,32 @@ export const BROWSER_TOOL_DEFINITIONS = [
|
|
|
175
299
|
},
|
|
176
300
|
additionalProperties: false,
|
|
177
301
|
},
|
|
302
|
+
doc: {
|
|
303
|
+
purpose: 'Inspect bridge lifecycle events — primary elections, tab registrations, tab renames.',
|
|
304
|
+
when_to_use: [
|
|
305
|
+
'When a tool call returns "Tab not connected: …" — look for a tab-renamed entry to find the new tab_id.',
|
|
306
|
+
'To diagnose why a tab disappeared between calls.',
|
|
307
|
+
],
|
|
308
|
+
gotchas: [
|
|
309
|
+
'Pass latest_id from the previous call as since_id to page through new entries efficiently.',
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: 'browser.reset',
|
|
315
|
+
description: 'Soft-reset the bridge state. Drops every connected tab session, releases every claim, and clears the in-memory event log — but does NOT kill the MCP server itself. The user has to re-press Connect in the extension popup for each tab they want back. Use this when the bridge state looks inconsistent (stale tab_ids that browser.events does not explain, tab.click that hangs, claims you cannot release through normal means) and you are sure a clean slate is the right move.',
|
|
316
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
317
|
+
doc: {
|
|
318
|
+
purpose: 'Soft-reset the bridge: drop tab sessions + claims + event log, keep the MCP server alive.',
|
|
319
|
+
when_to_use: [
|
|
320
|
+
'Bridge state looks inconsistent (stale tab_ids, hung action tools, claims you cannot release).',
|
|
321
|
+
'You explicitly want to start the bridge state from scratch without killing the MCP server.',
|
|
322
|
+
],
|
|
323
|
+
gotchas: [
|
|
324
|
+
'This drops every tab the user had connected — they will need to re-press Connect in the extension popup for each one.',
|
|
325
|
+
'Use sparingly. Most "tab not connected" cases resolve via browser.events showing a tab-renamed entry, not via reset.',
|
|
326
|
+
],
|
|
327
|
+
},
|
|
178
328
|
},
|
|
179
329
|
];
|
|
180
330
|
//# sourceMappingURL=browser-definitions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-definitions.js","sourceRoot":"","sources":["../../src/tools/browser-definitions.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"browser-definitions.js","sourceRoot":"","sources":["../../src/tools/browser-definitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dispatcher for browser.* tools. Mirrors the shape of the map dispatcher
|
|
3
|
-
* (`handleMapTool` / `isMapTool`) so both families look the same from
|
|
4
|
-
* runServer().
|
|
5
|
-
*
|
|
6
|
-
* The handlers do not own state: they receive a `BrowserToolDeps` object
|
|
7
|
-
* with the live tab map, the call function, and the claim registry. This
|
|
8
|
-
* makes the dispatcher unit-testable with a fake `callBrowserTool` and a
|
|
9
|
-
* fresh `TabClaimRegistry`.
|
|
10
|
-
*
|
|
11
|
-
* Each invocation also receives an `AgentCaller` so claim/ownership
|
|
12
|
-
* decisions can be made per request. The bridge layers (primary's stdio
|
|
13
|
-
* handler + IPC server) are responsible for supplying it.
|
|
14
|
-
*/
|
|
15
1
|
import type { BridgeEvent } from '../bridge/events.js';
|
|
16
2
|
import { type AgentCaller, type TabClaimRegistry } from './tab-claims.js';
|
|
17
3
|
export interface TabSnapshot {
|
|
@@ -48,6 +34,14 @@ export interface BrowserToolDeps {
|
|
|
48
34
|
* absent the dispatcher behaves as before (no enforcement, list_tabs
|
|
49
35
|
* returns claimed_by:null for every tab). */
|
|
50
36
|
tabClaims?: TabClaimRegistry;
|
|
37
|
+
/** Soft-reset entry point for `browser.reset`. Drops every connected tab
|
|
38
|
+
* session, releases every claim, clears the event log — without killing
|
|
39
|
+
* the MCP server. Optional so unit tests can omit it. */
|
|
40
|
+
resetBridge?(): {
|
|
41
|
+
dropped_tabs: number;
|
|
42
|
+
released_claims: number;
|
|
43
|
+
cleared_events: number;
|
|
44
|
+
};
|
|
51
45
|
}
|
|
52
46
|
export declare function isBrowserTool(name: string): boolean;
|
|
53
47
|
/**
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
function handleReset(deps) {
|
|
2
|
+
if (!deps.resetBridge) {
|
|
3
|
+
return { ok: false, reason: 'reset-not-supported' };
|
|
4
|
+
}
|
|
5
|
+
const result = deps.resetBridge();
|
|
6
|
+
return { ok: true, ...result };
|
|
7
|
+
}
|
|
1
8
|
/**
|
|
2
9
|
* Dispatcher for browser.* tools. Mirrors the shape of the map dispatcher
|
|
3
10
|
* (`handleMapTool` / `isMapTool`) so both families look the same from
|
|
@@ -33,6 +40,7 @@ const BROWSER_TOOL_NAMES = [
|
|
|
33
40
|
'browser.type',
|
|
34
41
|
'browser.evaluate',
|
|
35
42
|
'browser.events',
|
|
43
|
+
'browser.reset',
|
|
36
44
|
];
|
|
37
45
|
const BROWSER_TOOL_NAME_SET = new Set(BROWSER_TOOL_NAMES);
|
|
38
46
|
export function isBrowserTool(name) {
|
|
@@ -180,6 +188,8 @@ export async function handleBrowserTool(name, args, deps, caller) {
|
|
|
180
188
|
}
|
|
181
189
|
case 'browser.events':
|
|
182
190
|
return handleEvents(args, deps);
|
|
191
|
+
case 'browser.reset':
|
|
192
|
+
return handleReset(deps);
|
|
183
193
|
default: {
|
|
184
194
|
// The earlier `isBrowserTool(name)` check makes this branch unreachable
|
|
185
195
|
// for any value within `BrowserToolName`. The exhaustive cast surfaces a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-dispatch.js","sourceRoot":"","sources":["../../src/tools/browser-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACL,mBAAmB,GAIpB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-dispatch.js","sourceRoot":"","sources":["../../src/tools/browser-dispatch.ts"],"names":[],"mappings":"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"}
|