@amaster.ai/pi-browser-use 0.1.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/LICENSE +201 -0
- package/README.md +156 -0
- package/dist/analyze-screenshot.d.ts +33 -0
- package/dist/analyze-screenshot.d.ts.map +1 -0
- package/dist/analyze-screenshot.js +140 -0
- package/dist/analyze-screenshot.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +133 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +239 -0
- package/dist/index.js.map +1 -0
- package/dist/tool-augment.d.ts +14 -0
- package/dist/tool-augment.d.ts.map +1 -0
- package/dist/tool-augment.js +68 -0
- package/dist/tool-augment.js.map +1 -0
- package/package.json +71 -0
- package/preview.png +0 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standalone MCP server mode.
|
|
4
|
+
*
|
|
5
|
+
* Runs pi-browser-use as a standalone process that speaks MCP over stdio.
|
|
6
|
+
* Used when pi-browser-use is configured as an external MCP server (e.g. in mcp.json)
|
|
7
|
+
* rather than loaded as a pi-coding-agent extension.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
11
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
13
|
+
import { createFetchVisionCaller, handleAnalyzeScreenshot } from './analyze-screenshot.js';
|
|
14
|
+
import { DevToolsClient } from './index.js';
|
|
15
|
+
import { augmentToolDescription, extractTextContent, postProcessToolResult, } from './tool-augment.js';
|
|
16
|
+
const TOOL_PREFIX = 'browser_';
|
|
17
|
+
const EXCLUDED_TOOLS = new Set([
|
|
18
|
+
'lighthouse_audit',
|
|
19
|
+
'performance_analyze_insight',
|
|
20
|
+
'performance_start_trace',
|
|
21
|
+
'performance_stop_trace',
|
|
22
|
+
'screencast_start',
|
|
23
|
+
'screencast_stop',
|
|
24
|
+
'install_extension',
|
|
25
|
+
'list_extensions',
|
|
26
|
+
'reload_extension',
|
|
27
|
+
'trigger_extension_action',
|
|
28
|
+
'uninstall_extension',
|
|
29
|
+
]);
|
|
30
|
+
export function parseArgs(argv) {
|
|
31
|
+
const config = {};
|
|
32
|
+
let i = 0;
|
|
33
|
+
while (i < argv.length) {
|
|
34
|
+
const arg = argv[i];
|
|
35
|
+
if (arg === '--config' && argv[i + 1] != null) {
|
|
36
|
+
const raw = readFileSync(argv[i + 1], 'utf-8');
|
|
37
|
+
const parsed = JSON.parse(raw);
|
|
38
|
+
const section = (parsed['pi-browser-use'] ?? parsed);
|
|
39
|
+
Object.assign(config, section);
|
|
40
|
+
i += 2;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const match = arg.match(/^--([a-z-]+)(?:=(.+))?$/);
|
|
44
|
+
if (match) {
|
|
45
|
+
const key = match[1];
|
|
46
|
+
const value = match[2];
|
|
47
|
+
const camelKey = key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
48
|
+
if (value === undefined || value === 'true') {
|
|
49
|
+
config[camelKey] = true;
|
|
50
|
+
}
|
|
51
|
+
else if (value === 'false') {
|
|
52
|
+
config[camelKey] = false;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
config[camelKey] = value;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
i++;
|
|
59
|
+
}
|
|
60
|
+
return config;
|
|
61
|
+
}
|
|
62
|
+
async function main() {
|
|
63
|
+
const config = parseArgs(process.argv.slice(2));
|
|
64
|
+
const client = new DevToolsClient(config);
|
|
65
|
+
await client.connect();
|
|
66
|
+
const toolNameMap = new Map();
|
|
67
|
+
const server = new Server({ name: 'pi-browser-use', version: '0.1.0' }, { capabilities: { tools: {} } });
|
|
68
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
69
|
+
const upstreamTools = await client.listAllTools();
|
|
70
|
+
const tools = [];
|
|
71
|
+
toolNameMap.clear();
|
|
72
|
+
for (const tool of upstreamTools) {
|
|
73
|
+
if (EXCLUDED_TOOLS.has(tool.name))
|
|
74
|
+
continue;
|
|
75
|
+
const prefixedName = `${TOOL_PREFIX}${tool.name}`;
|
|
76
|
+
toolNameMap.set(prefixedName, tool.name);
|
|
77
|
+
tools.push({
|
|
78
|
+
...tool,
|
|
79
|
+
name: prefixedName,
|
|
80
|
+
description: augmentToolDescription(tool.name, tool.description ?? ''),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (config.visionModel) {
|
|
84
|
+
const name = `${TOOL_PREFIX}analyze_screenshot`;
|
|
85
|
+
toolNameMap.set(name, 'analyze_screenshot');
|
|
86
|
+
tools.push({
|
|
87
|
+
name,
|
|
88
|
+
description: 'Analyze the current page visually using a screenshot.',
|
|
89
|
+
inputSchema: {
|
|
90
|
+
type: 'object',
|
|
91
|
+
properties: {
|
|
92
|
+
instruction: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
description: 'What to identify or analyze visually.',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
required: ['instruction'],
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return { tools };
|
|
102
|
+
});
|
|
103
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
104
|
+
const { name, arguments: args } = request.params;
|
|
105
|
+
const originalName = toolNameMap.get(name);
|
|
106
|
+
if (!originalName)
|
|
107
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
108
|
+
if (originalName === 'analyze_screenshot' && config.visionModel) {
|
|
109
|
+
const callVision = createFetchVisionCaller(config.visionModel);
|
|
110
|
+
return await handleAnalyzeScreenshot(client, callVision, args ?? {});
|
|
111
|
+
}
|
|
112
|
+
const result = await client.callTool(originalName, args ?? {});
|
|
113
|
+
const textContent = extractTextContent(result.content);
|
|
114
|
+
const processed = postProcessToolResult(originalName, textContent);
|
|
115
|
+
if (processed !== textContent) {
|
|
116
|
+
const newContent = (result.content ?? []).map((item) => {
|
|
117
|
+
if (item.type === 'text') {
|
|
118
|
+
return { ...item, text: processed };
|
|
119
|
+
}
|
|
120
|
+
return item;
|
|
121
|
+
});
|
|
122
|
+
return { ...result, content: newContent };
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
});
|
|
126
|
+
const transport = new StdioServerTransport();
|
|
127
|
+
await server.connect(transport);
|
|
128
|
+
}
|
|
129
|
+
main().catch((error) => {
|
|
130
|
+
console.error(`[pi-browser-use] Fatal error: ${error}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Vision model used by the optional analyze_screenshot tool. */
|
|
2
|
+
export interface VisionModelConfig {
|
|
3
|
+
provider: string;
|
|
4
|
+
model: string;
|
|
5
|
+
}
|
|
6
|
+
export type BrowserSessionMode = 'persistent' | 'isolated' | 'existing';
|
|
7
|
+
/** Configuration for the chrome-devtools-mcp upstream process. */
|
|
8
|
+
export interface BrowserUseConfig {
|
|
9
|
+
sessionMode?: BrowserSessionMode;
|
|
10
|
+
headless?: boolean;
|
|
11
|
+
channel?: 'canary' | 'dev' | 'beta' | 'stable';
|
|
12
|
+
browserUrl?: string;
|
|
13
|
+
wsEndpoint?: string;
|
|
14
|
+
wsHeaders?: string;
|
|
15
|
+
executablePath?: string;
|
|
16
|
+
viewport?: string;
|
|
17
|
+
isolated?: boolean;
|
|
18
|
+
userDataDir?: string;
|
|
19
|
+
autoConnect?: boolean;
|
|
20
|
+
categoryPerformance?: boolean;
|
|
21
|
+
categoryNetwork?: boolean;
|
|
22
|
+
categoryEmulation?: boolean;
|
|
23
|
+
categoryExtensions?: boolean;
|
|
24
|
+
experimentalVision?: boolean;
|
|
25
|
+
experimentalScreencast?: boolean;
|
|
26
|
+
experimentalMemory?: boolean;
|
|
27
|
+
visionModel?: VisionModelConfig;
|
|
28
|
+
usageStatistics?: boolean;
|
|
29
|
+
performanceCrux?: boolean;
|
|
30
|
+
slim?: boolean;
|
|
31
|
+
extraArgs?: string[];
|
|
32
|
+
}
|
|
33
|
+
/** Merge user config over sane defaults. */
|
|
34
|
+
export declare function resolveConfig(config?: BrowserUseConfig): BrowserUseConfig;
|
|
35
|
+
/** Convert config into CLI flags for the chrome-devtools-mcp subprocess. */
|
|
36
|
+
export declare function configToArgs(config: BrowserUseConfig): string[];
|
|
37
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,iEAAiE;AACjE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,CAAC;AAExE,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAEhC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAiBD,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAsBzE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,EAAE,CA+B/D"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const DEFAULT_PROFILE_DIR = join(homedir(), '.pi', 'browser-profile');
|
|
4
|
+
const DEFAULTS = {
|
|
5
|
+
sessionMode: 'persistent',
|
|
6
|
+
categoryPerformance: false,
|
|
7
|
+
categoryNetwork: true,
|
|
8
|
+
categoryEmulation: true,
|
|
9
|
+
categoryExtensions: false,
|
|
10
|
+
experimentalVision: true,
|
|
11
|
+
experimentalScreencast: false,
|
|
12
|
+
experimentalMemory: false,
|
|
13
|
+
usageStatistics: false,
|
|
14
|
+
performanceCrux: false,
|
|
15
|
+
};
|
|
16
|
+
/** Merge user config over sane defaults. */
|
|
17
|
+
export function resolveConfig(config) {
|
|
18
|
+
const resolved = { ...DEFAULTS, ...config };
|
|
19
|
+
switch (resolved.sessionMode) {
|
|
20
|
+
case 'existing':
|
|
21
|
+
if (!resolved.autoConnect && !resolved.browserUrl && !resolved.wsEndpoint) {
|
|
22
|
+
resolved.autoConnect = true;
|
|
23
|
+
}
|
|
24
|
+
break;
|
|
25
|
+
case 'isolated':
|
|
26
|
+
if (!resolved.isolated) {
|
|
27
|
+
resolved.isolated = true;
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
if (!resolved.userDataDir && !resolved.browserUrl && !resolved.wsEndpoint) {
|
|
32
|
+
resolved.userDataDir = DEFAULT_PROFILE_DIR;
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
return resolved;
|
|
37
|
+
}
|
|
38
|
+
/** Convert config into CLI flags for the chrome-devtools-mcp subprocess. */
|
|
39
|
+
export function configToArgs(config) {
|
|
40
|
+
const args = [];
|
|
41
|
+
const resolved = resolveConfig(config);
|
|
42
|
+
if (resolved.headless)
|
|
43
|
+
args.push('--headless');
|
|
44
|
+
if (resolved.channel)
|
|
45
|
+
args.push(`--channel=${resolved.channel}`);
|
|
46
|
+
if (resolved.browserUrl)
|
|
47
|
+
args.push(`--browser-url=${resolved.browserUrl}`);
|
|
48
|
+
if (resolved.wsEndpoint)
|
|
49
|
+
args.push(`--ws-endpoint=${resolved.wsEndpoint}`);
|
|
50
|
+
if (resolved.wsHeaders)
|
|
51
|
+
args.push(`--ws-headers=${resolved.wsHeaders}`);
|
|
52
|
+
if (resolved.executablePath)
|
|
53
|
+
args.push(`--executable-path=${resolved.executablePath}`);
|
|
54
|
+
if (resolved.viewport)
|
|
55
|
+
args.push(`--viewport=${resolved.viewport}`);
|
|
56
|
+
if (resolved.isolated)
|
|
57
|
+
args.push('--isolated');
|
|
58
|
+
if (resolved.userDataDir)
|
|
59
|
+
args.push(`--user-data-dir=${resolved.userDataDir}`);
|
|
60
|
+
if (resolved.autoConnect)
|
|
61
|
+
args.push('--auto-connect');
|
|
62
|
+
if (resolved.slim)
|
|
63
|
+
args.push('--slim');
|
|
64
|
+
if (resolved.categoryPerformance === false)
|
|
65
|
+
args.push('--category-performance=false');
|
|
66
|
+
if (resolved.categoryNetwork === false)
|
|
67
|
+
args.push('--category-network=false');
|
|
68
|
+
if (resolved.categoryEmulation === false)
|
|
69
|
+
args.push('--category-emulation=false');
|
|
70
|
+
if (resolved.categoryExtensions === true)
|
|
71
|
+
args.push('--category-extensions=true');
|
|
72
|
+
if (resolved.experimentalVision)
|
|
73
|
+
args.push('--experimental-vision');
|
|
74
|
+
if (resolved.experimentalScreencast)
|
|
75
|
+
args.push('--experimental-screencast');
|
|
76
|
+
if (resolved.experimentalMemory)
|
|
77
|
+
args.push('--experimental-memory');
|
|
78
|
+
if (resolved.usageStatistics === false)
|
|
79
|
+
args.push('--no-usage-statistics');
|
|
80
|
+
if (resolved.performanceCrux === false)
|
|
81
|
+
args.push('--no-performance-crux');
|
|
82
|
+
if (resolved.extraArgs)
|
|
83
|
+
args.push(...resolved.extraArgs);
|
|
84
|
+
return args;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA0CjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;AAEtE,MAAM,QAAQ,GAA8B;IAC1C,WAAW,EAAE,YAAY;IACzB,mBAAmB,EAAE,KAAK;IAC1B,eAAe,EAAE,IAAI;IACrB,iBAAiB,EAAE,IAAI;IACvB,kBAAkB,EAAE,KAAK;IACzB,kBAAkB,EAAE,IAAI;IACxB,sBAAsB,EAAE,KAAK;IAC7B,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,KAAK;IACtB,eAAe,EAAE,KAAK;CACvB,CAAC;AAEF,4CAA4C;AAC5C,MAAM,UAAU,aAAa,CAAC,MAAyB;IACrD,MAAM,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IAE5C,QAAQ,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC7B,KAAK,UAAU;YACb,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC1E,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;YAC9B,CAAC;YACD,MAAM;QACR,KAAK,UAAU;YACb,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACvB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,MAAM;QACR;YACE,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC1E,QAAQ,CAAC,WAAW,GAAG,mBAAmB,CAAC;YAC7C,CAAC;YACD,MAAM;IACV,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,MAAwB;IACnD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,QAAQ,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,QAAQ,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3E,IAAI,QAAQ,CAAC,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3E,IAAI,QAAQ,CAAC,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IACxE,IAAI,QAAQ,CAAC,cAAc;QAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;IACvF,IAAI,QAAQ,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,cAAc,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpE,IAAI,QAAQ,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,QAAQ,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/E,IAAI,QAAQ,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACtD,IAAI,QAAQ,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEvC,IAAI,QAAQ,CAAC,mBAAmB,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACtF,IAAI,QAAQ,CAAC,eAAe,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC9E,IAAI,QAAQ,CAAC,iBAAiB,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAClF,IAAI,QAAQ,CAAC,kBAAkB,KAAK,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAElF,IAAI,QAAQ,CAAC,kBAAkB;QAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACpE,IAAI,QAAQ,CAAC,sBAAsB;QAAE,IAAI,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,kBAAkB;QAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAEpE,IAAI,QAAQ,CAAC,eAAe,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC3E,IAAI,QAAQ,CAAC,eAAe,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAE3E,IAAI,QAAQ,CAAC,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEzD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { type BrowserSessionMode, type BrowserUseConfig, configToArgs, resolveConfig, type VisionModelConfig } from './config.js';
|
|
4
|
+
export type { BrowserSessionMode, BrowserUseConfig, VisionModelConfig };
|
|
5
|
+
export { configToArgs, resolveConfig };
|
|
6
|
+
/**
|
|
7
|
+
* MCP client that spawns chrome-devtools-mcp as a subprocess and communicates
|
|
8
|
+
* over stdio. Owns the child-process lifecycle: connect() starts it, close() kills it.
|
|
9
|
+
*/
|
|
10
|
+
export declare class DevToolsClient {
|
|
11
|
+
private client;
|
|
12
|
+
private transport;
|
|
13
|
+
private config;
|
|
14
|
+
constructor(config?: BrowserUseConfig);
|
|
15
|
+
connect(): Promise<void>;
|
|
16
|
+
listAllTools(): Promise<Tool[]>;
|
|
17
|
+
callTool(name: string, args: Record<string, unknown>): Promise<{
|
|
18
|
+
content?: Array<{
|
|
19
|
+
type: string;
|
|
20
|
+
text?: string;
|
|
21
|
+
data?: string;
|
|
22
|
+
mimeType?: string;
|
|
23
|
+
}>;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* pi-coding-agent extension entry point.
|
|
30
|
+
*
|
|
31
|
+
* On session_start: spawns chrome-devtools-mcp, discovers upstream tools,
|
|
32
|
+
* and registers each one via pi.registerTool() with a "browser_" prefix.
|
|
33
|
+
* On session_shutdown: tears down the subprocess.
|
|
34
|
+
*
|
|
35
|
+
* Config is loaded from config.json["pi-browser-use"] in the working directory.
|
|
36
|
+
* If visionModel is configured, an additional analyze_screenshot tool is registered.
|
|
37
|
+
*/
|
|
38
|
+
export default function browserUseExtension(pi: ExtensionAPI): void;
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAItF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAO/D,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,YAAY,EACZ,aAAa,EACb,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAOrB,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAsBvC;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,CAAC,EAAE,gBAAgB;IAI/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBxB,YAAY,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAgB/B,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC;QACT,OAAO,CAAC,EAAE,KAAK,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAgBI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B;AA6CD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0JlE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { loadPiSettings } from '@amaster.ai/pi-shared/settings';
|
|
2
|
+
import { complete } from '@earendil-works/pi-ai';
|
|
3
|
+
import { getAgentDir } from '@earendil-works/pi-coding-agent';
|
|
4
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
5
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
6
|
+
import { Type } from 'typebox';
|
|
7
|
+
import { handleAnalyzeScreenshot, VISUAL_SYSTEM_PROMPT, } from './analyze-screenshot.js';
|
|
8
|
+
import { configToArgs, resolveConfig, } from './config.js';
|
|
9
|
+
import { augmentToolDescription, extractTextContent, postProcessToolResult, } from './tool-augment.js';
|
|
10
|
+
export { configToArgs, resolveConfig };
|
|
11
|
+
// All upstream tools are re-exported with this prefix to avoid name collisions with other extensions.
|
|
12
|
+
const TOOL_PREFIX = 'browser_';
|
|
13
|
+
// These upstream tools are noisy or slow; skip them during registration.
|
|
14
|
+
const EXCLUDED_TOOLS = new Set([
|
|
15
|
+
'lighthouse_audit',
|
|
16
|
+
'performance_analyze_insight',
|
|
17
|
+
'performance_start_trace',
|
|
18
|
+
'performance_stop_trace',
|
|
19
|
+
'screencast_start',
|
|
20
|
+
'screencast_stop',
|
|
21
|
+
'install_extension',
|
|
22
|
+
'list_extensions',
|
|
23
|
+
'reload_extension',
|
|
24
|
+
'trigger_extension_action',
|
|
25
|
+
'uninstall_extension',
|
|
26
|
+
]);
|
|
27
|
+
const MCP_TIMEOUT_MS = 60_000;
|
|
28
|
+
/**
|
|
29
|
+
* MCP client that spawns chrome-devtools-mcp as a subprocess and communicates
|
|
30
|
+
* over stdio. Owns the child-process lifecycle: connect() starts it, close() kills it.
|
|
31
|
+
*/
|
|
32
|
+
export class DevToolsClient {
|
|
33
|
+
client = null;
|
|
34
|
+
transport = null;
|
|
35
|
+
config;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.config = resolveConfig(config);
|
|
38
|
+
}
|
|
39
|
+
async connect() {
|
|
40
|
+
const args = configToArgs(this.config);
|
|
41
|
+
this.transport = new StdioClientTransport({
|
|
42
|
+
command: 'npx',
|
|
43
|
+
args: ['-y', 'chrome-devtools-mcp@latest', ...args],
|
|
44
|
+
stderr: 'pipe',
|
|
45
|
+
});
|
|
46
|
+
this.client = new Client({ name: 'pi-browser-use', version: '0.1.0' }, { capabilities: {} });
|
|
47
|
+
this.transport.onerror = (error) => {
|
|
48
|
+
console.error(`[pi-browser-use] chrome-devtools-mcp transport error: ${error.message}`);
|
|
49
|
+
};
|
|
50
|
+
await this.client.connect(this.transport);
|
|
51
|
+
}
|
|
52
|
+
async listAllTools() {
|
|
53
|
+
if (!this.client)
|
|
54
|
+
throw new Error('Client not connected');
|
|
55
|
+
const allTools = [];
|
|
56
|
+
let cursor;
|
|
57
|
+
do {
|
|
58
|
+
const result = await this.client.listTools(cursor ? { cursor } : undefined, {
|
|
59
|
+
timeout: MCP_TIMEOUT_MS,
|
|
60
|
+
});
|
|
61
|
+
allTools.push(...result.tools);
|
|
62
|
+
cursor = result.nextCursor;
|
|
63
|
+
} while (cursor);
|
|
64
|
+
return allTools;
|
|
65
|
+
}
|
|
66
|
+
async callTool(name, args) {
|
|
67
|
+
if (!this.client)
|
|
68
|
+
throw new Error('Client not connected');
|
|
69
|
+
return (await this.client.callTool({ name, arguments: args }, undefined, {
|
|
70
|
+
timeout: MCP_TIMEOUT_MS,
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
async close() {
|
|
74
|
+
if (this.client) {
|
|
75
|
+
await this.client.close();
|
|
76
|
+
this.client = null;
|
|
77
|
+
}
|
|
78
|
+
this.transport = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Read the pi-browser-use section from .pi/settings.json. */
|
|
82
|
+
function loadConfigFromFile(options) {
|
|
83
|
+
return loadPiSettings('pi-browser-use', {
|
|
84
|
+
agentDir: getAgentDir(),
|
|
85
|
+
...options,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** Convert upstream MCP result into pi-agent TextContent[], applying post-processing. */
|
|
89
|
+
function toTextContent(result, originalName) {
|
|
90
|
+
const textContent = extractTextContent(result.content);
|
|
91
|
+
const processed = postProcessToolResult(originalName, textContent);
|
|
92
|
+
const content = [];
|
|
93
|
+
if (processed !== textContent) {
|
|
94
|
+
content.push({ type: 'text', text: processed });
|
|
95
|
+
}
|
|
96
|
+
else if (result.content) {
|
|
97
|
+
for (const item of result.content) {
|
|
98
|
+
if (item.type === 'text' && item.text) {
|
|
99
|
+
content.push({ type: 'text', text: item.text });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (content.length === 0) {
|
|
104
|
+
content.push({ type: 'text', text: '' });
|
|
105
|
+
}
|
|
106
|
+
return result.isError ? { content, isError: true } : { content };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* pi-coding-agent extension entry point.
|
|
110
|
+
*
|
|
111
|
+
* On session_start: spawns chrome-devtools-mcp, discovers upstream tools,
|
|
112
|
+
* and registers each one via pi.registerTool() with a "browser_" prefix.
|
|
113
|
+
* On session_shutdown: tears down the subprocess.
|
|
114
|
+
*
|
|
115
|
+
* Config is loaded from config.json["pi-browser-use"] in the working directory.
|
|
116
|
+
* If visionModel is configured, an additional analyze_screenshot tool is registered.
|
|
117
|
+
*/
|
|
118
|
+
export default function browserUseExtension(pi) {
|
|
119
|
+
let config;
|
|
120
|
+
let client;
|
|
121
|
+
let connected = false;
|
|
122
|
+
async function ensureConnected() {
|
|
123
|
+
if (!client)
|
|
124
|
+
throw new Error('browser-use: session not started');
|
|
125
|
+
if (!connected) {
|
|
126
|
+
await client.connect();
|
|
127
|
+
connected = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function registerUpstreamTools() {
|
|
131
|
+
await ensureConnected();
|
|
132
|
+
const upstreamTools = await client.listAllTools();
|
|
133
|
+
for (const tool of upstreamTools) {
|
|
134
|
+
if (EXCLUDED_TOOLS.has(tool.name))
|
|
135
|
+
continue;
|
|
136
|
+
const prefixedName = `${TOOL_PREFIX}${tool.name}`;
|
|
137
|
+
const originalName = tool.name;
|
|
138
|
+
const description = augmentToolDescription(originalName, tool.description ?? '');
|
|
139
|
+
pi.registerTool({
|
|
140
|
+
name: prefixedName,
|
|
141
|
+
label: prefixedName,
|
|
142
|
+
description,
|
|
143
|
+
parameters: Type.Unsafe(tool.inputSchema),
|
|
144
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
145
|
+
await ensureConnected();
|
|
146
|
+
const result = await client.callTool(originalName, params);
|
|
147
|
+
const { content } = toTextContent(result, originalName);
|
|
148
|
+
return { content, details: undefined };
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** Create a VisionCaller that uses pi-ai's complete() with the model registry. */
|
|
154
|
+
function createPiVisionCaller(visionConfig, ctx) {
|
|
155
|
+
return async (instruction, imageBase64, mimeType) => {
|
|
156
|
+
const model = ctx.modelRegistry.find(visionConfig.provider, visionConfig.model);
|
|
157
|
+
if (!model) {
|
|
158
|
+
throw new Error(`Vision model "${visionConfig.provider}/${visionConfig.model}" not found in model registry.`);
|
|
159
|
+
}
|
|
160
|
+
const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
|
|
161
|
+
if (!auth.ok) {
|
|
162
|
+
throw new Error(`Auth failed for vision model: ${auth.error}`);
|
|
163
|
+
}
|
|
164
|
+
const options = {
|
|
165
|
+
temperature: 0,
|
|
166
|
+
maxTokens: 2048,
|
|
167
|
+
};
|
|
168
|
+
if (auth.apiKey)
|
|
169
|
+
options.apiKey = auth.apiKey;
|
|
170
|
+
if (auth.headers)
|
|
171
|
+
options.headers = auth.headers;
|
|
172
|
+
const result = await complete(model, {
|
|
173
|
+
systemPrompt: VISUAL_SYSTEM_PROMPT,
|
|
174
|
+
messages: [
|
|
175
|
+
{
|
|
176
|
+
role: 'user',
|
|
177
|
+
content: [
|
|
178
|
+
{
|
|
179
|
+
type: 'text',
|
|
180
|
+
text: `Analyze this screenshot and respond to the following instruction:\n\n${instruction}`,
|
|
181
|
+
},
|
|
182
|
+
{ type: 'image', data: imageBase64, mimeType },
|
|
183
|
+
],
|
|
184
|
+
timestamp: Date.now(),
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
}, options);
|
|
188
|
+
return result.content
|
|
189
|
+
.filter((c) => c.type === 'text')
|
|
190
|
+
.map((c) => c.text)
|
|
191
|
+
.join('');
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function registerVisionTool(visionConfig) {
|
|
195
|
+
pi.registerTool({
|
|
196
|
+
name: `${TOOL_PREFIX}analyze_screenshot`,
|
|
197
|
+
label: `${TOOL_PREFIX}analyze_screenshot`,
|
|
198
|
+
description: 'Analyze the current page visually using a screenshot. Use when you need to identify elements by visual attributes (color, layout, position) not available in the accessibility tree, or when you need precise pixel coordinates for click_at.',
|
|
199
|
+
parameters: Type.Object({
|
|
200
|
+
instruction: Type.Optional(Type.String({
|
|
201
|
+
description: 'What to identify or analyze visually (e.g., "Find the coordinates of the blue submit button").',
|
|
202
|
+
})),
|
|
203
|
+
}),
|
|
204
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
205
|
+
await ensureConnected();
|
|
206
|
+
const callVision = createPiVisionCaller(visionConfig, ctx);
|
|
207
|
+
const result = await handleAnalyzeScreenshot(client, callVision, params);
|
|
208
|
+
const content = [];
|
|
209
|
+
if (result.content) {
|
|
210
|
+
for (const item of result.content) {
|
|
211
|
+
if (item.type === 'text' && item.text) {
|
|
212
|
+
content.push({ type: 'text', text: item.text });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (content.length === 0) {
|
|
217
|
+
content.push({ type: 'text', text: '' });
|
|
218
|
+
}
|
|
219
|
+
return { content, details: undefined };
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
pi.on('session_start', async (_event, ctx) => {
|
|
224
|
+
config = resolveConfig(loadConfigFromFile({ cwd: ctx.cwd }));
|
|
225
|
+
client = new DevToolsClient(config);
|
|
226
|
+
connected = false;
|
|
227
|
+
await registerUpstreamTools();
|
|
228
|
+
if (config.visionModel) {
|
|
229
|
+
await registerVisionTool(config.visionModel);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
pi.on('session_shutdown', async () => {
|
|
233
|
+
if (connected && client) {
|
|
234
|
+
await client.close();
|
|
235
|
+
connected = false;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Append usage hints to tool descriptions based on tool name keywords. */
|
|
2
|
+
export declare function augmentToolDescription(toolName: string, description: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Post-process tool output before returning to the LLM:
|
|
5
|
+
* - Strip embedded page snapshots (token bloat) from non-snapshot tools
|
|
6
|
+
* - Detect overlay/interactable issues on click actions
|
|
7
|
+
* - Detect stale element references
|
|
8
|
+
*/
|
|
9
|
+
export declare function postProcessToolResult(toolName: string, result: string): string;
|
|
10
|
+
export declare function extractTextContent(content?: Array<{
|
|
11
|
+
type: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
}>): string;
|
|
14
|
+
//# sourceMappingURL=tool-augment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-augment.d.ts","sourceRoot":"","sources":["../src/tool-augment.ts"],"names":[],"mappings":"AAoBA,2EAA2E;AAC3E,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAOpF;AAWD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA4B9E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAM3F"}
|