dsh-browser-view 0.7.5 → 0.8.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.
@@ -1,3 +1,6 @@
1
+ /** 标记当前宿主环境是否挂载了交互面板(DSH 插件=true;独立 MCP 模式=false)。 */
2
+ export declare function setInteractivePanelPresent(present: boolean): void;
3
+ export declare function isInteractivePanelPresent(): boolean;
1
4
  export declare function setPauseInstruction(instruction: string): void;
2
5
  export declare function clearPauseInstruction(): void;
3
6
  export declare function currentPause(): {
@@ -0,0 +1,7 @@
1
+ import type { BrowserConfig } from "../browser/types.js";
2
+ declare const FULL_TOOL_PROMPT = "\u6D4F\u89C8\u5668\u5DE5\u5177\u64CD\u4F5C\u4E00\u4E2A\u5171\u4EAB\u6D4F\u89C8\u5668\u4F1A\u8BDD,\u652F\u6301\u591A\u6807\u7B7E\u9875\u4E0E\u591A\u914D\u7F6E\u6587\u4EF6\u3002\u5B9A\u4F4D\u64CD\u4F5C\u5143\u7D20\u6700\u7701\u4E8B\u7684\u65B9\u5F0F\u662F\u610F\u56FE\u8BED\u4E49\u5B9A\u4F4D:browser_click/browser_type/browser_select \u76F4\u63A5\u4F20 what(\u5143\u7D20\u540D\u79F0/label,\u5982 what:'\u767B\u5F55'),\u9875\u5185\u6253\u5206\u5339\u914D\u5E76\u81EA\u52A8\u6CE8\u518C ref,\u4E00\u6B21\u8C03\u7528\u66FF\u4EE3 \u5FEB\u7167\u2192\u67E5\u627E\u2192\u70B9\u51FB \u4E09\u8F6E;\u96F6\u547D\u4E2D\u62A5\u9519\u4F1A\u9644\u6700\u76F8\u8FD1\u5019\u9009\u3002\u9700\u8981\u7CBE\u786E\u63A7\u5236\u65F6\u518D\u7528 selector(CSS)/ref(aria \u5FEB\u7167)\u3002\u6253\u5F00\u9875\u9762\u540E\u53EF\u5148 browser_snapshot \u8BFB\u6587\u672C\u4E0E\u94FE\u63A5\u3001browser_elements \u8BFB\u8868\u5355\u7ED3\u6784(\u542B\u5173\u8054 label \u4E0E\u5C55\u5F00\u7684\u4E0B\u62C9\u9009\u9879);browser_find(query \u4F20\u540D\u79F0,\u53EA\u8FD4\u56DE\u547D\u4E2D ref+\u533A\u57DF\u4E0A\u4E0B\u6587,\u5927\u9875\u9762\u6700\u7701 token;\u96F6\u547D\u4E2D\u4F1A\u7ED9\u76F8\u8FD1\u5019\u9009)\u9002\u5408\u591A\u76EE\u6807\u6392\u67E5,\u9700\u8981\u5168\u9875\u7ED3\u6784\u65F6\u518D\u7528 browser_snapshot { mode: \"aria\" }(\u53EF\u4EA4\u4E92\u5143\u7D20\u5E26 ref=eN,click/type/select/press \u76F4\u63A5\u4F20 ref \u4EE3\u66FF CSS \u9009\u62E9\u5668);\u4E0B\u62C9\u9009\u62E9(\u539F\u751F select \u4E0E antd/element \u7EC4\u4EF6\u5E93)\u7528 browser_select \u4F20 selector/ref/what + option \u6587\u672C\u4E00\u6B65\u5B8C\u6210;\u56FA\u5B9A\u5C0F\u5E8F\u5217(\u70B9\u51FB\u2192\u7B49\u5F85\u2192\u8F93\u5165\u2192\u63D0\u4EA4)\u7528 browser_batch \u4E00\u6B21\u6267\u884C\u51CF\u5C11\u5F80\u8FD4;\u6807\u7B7E\u7BA1\u7406\u7528 browser_tabs;\u4E0B\u8F7D\u7528 browser_download(wait=true \u53EF\u7B49\u65B0\u4E0B\u8F7D);\u767B\u5F55\u6001\u7528 browser_cookies\u3002\u505A\u81EA\u52A8\u5316\u6D4B\u8BD5\u65F6:\u7528 browser_wait_for \u663E\u5F0F\u7B49\u5F85\u9875\u9762\u7A33\u5B9A/\u5143\u7D20\u51FA\u73B0,\u7528 browser_assert \u65AD\u8A00(\u5931\u8D25\u81EA\u52A8\u622A\u56FE;visual={baseline} \u53EF\u505A\u89C6\u89C9\u56DE\u5F52,\u5148\u7528 browser_screenshot { baseline } \u5EFA\u57FA\u7EBF),\u7528 browser_network \u68C0\u67E5\u63A5\u53E3\u8C03\u7528\u4E0E 4xx/5xx,\u8DD1\u5B8C\u4E00\u8F6E\u53EF\u7528 browser_record save \u4FDD\u5B58\u64CD\u4F5C\u5E8F\u5217\u3001browser_replay \u56DE\u653E\u505A\u56DE\u5F52(\u9009\u62E9\u5668\u5931\u6548\u81EA\u52A8\u6309\u6307\u7EB9\u81EA\u6108;vars/data \u652F\u6301\u53C2\u6570\u5316\u4E0E\u6570\u636E\u9A71\u52A8)\u3002\u6BCF\u6B21 replay/batch \u90FD\u8BB0\u5165\u8FD0\u884C\u5386\u53F2,browser_report list/export \u53EF\u67E5\u770B\u4E0E\u5BFC\u51FA\u56DE\u5F52\u62A5\u544A\u3002\u6293\u53D6\u7ED3\u6784\u5316\u6570\u636E\u7528 browser_extract(fields \u5B9A\u4E49 CSS \u5B57\u6BB5,\u53EF\u7FFB\u9875,\u53EF\u5BFC\u51FA CSV/JSONL)\u3002\u9047\u5230\u9700\u8981\u767B\u5F55\u7684\u7F51\u7AD9:\u5148 browser_open \u6253\u5F00\u767B\u5F55\u9875,\u544A\u77E5\u7528\u6237\u8BF7\u5728\u6D4F\u89C8\u5668\u7A97\u53E3\u4E2D\u5B8C\u6210\u767B\u5F55,\u518D\u8C03\u7528 browser_wait_for_login \u7B49\u5F85(\u53EF\u7ED9 successSelector/successUrl);\u9A8C\u8BC1\u7801/\u4E8C\u6B21\u786E\u8BA4\u7B49\u66F4\u5E7F\u7684\u300C\u4EBA\u8865\u4E00\u6B65\u300D\u573A\u666F\u7528 browser_pause_for_human(\u63D0\u793A\u8BED\u4F1A\u663E\u793A\u5728\u5B9E\u65F6\u753B\u9762\u9762\u677F);\u914D\u7F6E userDataDir \u65F6\u767B\u5F55\u6001\u4F1A\u6301\u4E45\u5316\u3002\u7528\u6237\u53EF\u901A\u8FC7\u754C\u9762\u53F3\u4E0B\u89D2\u9762\u677F\u7684\u5B9E\u65F6\u753B\u9762\u67E5\u770B\u6D4F\u89C8\u5668\u3002";
3
+ declare const CORE_TOOL_PROMPT = "\u6D4F\u89C8\u5668\u5DE5\u5177\u64CD\u4F5C\u4E00\u4E2A\u5171\u4EAB\u6D4F\u89C8\u5668\u4F1A\u8BDD(toolset=core:\u5DF2\u7CBE\u7B80\u5DE5\u5177\u96C6)\u3002\u5B9A\u4F4D\u64CD\u4F5C\u5143\u7D20\u6700\u7701\u4E8B\u7684\u65B9\u5F0F\u662F\u610F\u56FE\u8BED\u4E49\u5B9A\u4F4D:browser_click/browser_type/browser_select \u76F4\u63A5\u4F20 what(\u5143\u7D20\u540D\u79F0/label,\u5982 what:'\u767B\u5F55'),\u4E00\u6B21\u8C03\u7528\u66FF\u4EE3\u5FEB\u7167\u2192\u67E5\u627E\u2192\u70B9\u51FB;\u96F6\u547D\u4E2D\u62A5\u9519\u9644\u6700\u76F8\u8FD1\u5019\u9009\u3002\u9700\u8981\u7CBE\u786E\u63A7\u5236\u65F6\u518D\u7528 selector/ref:\u6253\u5F00\u9875\u9762\u540E\u7528 browser_snapshot \u8BFB\u5185\u5BB9(scope \u9650\u5B9A\u533A\u57DF\u3001since \u589E\u91CF\u91CD\u8BFB\u7701 token),browser_find(query \u4F20\u540D\u79F0,\u8FD4\u56DE ref),\u70B9\u51FB/\u8F93\u5165/\u6309\u952E/\u4E0B\u62C9\u7528 browser_click/browser_type/browser_press/browser_select(selector \u6216 ref);\u56FA\u5B9A\u5C0F\u5E8F\u5217\u7528 browser_batch;\u7B49\u5F85\u7528 browser_wait/browser_wait_for,\u65AD\u8A00\u7528 browser_assert;\u63A5\u53E3\u68C0\u67E5\u7528 browser_network;\u6807\u7B7E browser_tabs;\u4E0B\u8F7D/\u4E0A\u4F20 browser_download/browser_upload\u3002\u9700\u8981\u4EBA\u5DE5:\u767B\u5F55\u7528 browser_wait_for_login,\u9A8C\u8BC1\u7801/\u4E8C\u6B21\u786E\u8BA4\u7528 browser_pause_for_human,\u654F\u611F\u52A8\u4F5C(\u63D0\u4EA4/\u5220\u9664/\u652F\u4ED8)\u524D\u7528 browser_confirm\u3002\u73AF\u5883\u5F02\u5E38\u5148\u8DD1 browser_doctor \u8BCA\u65AD\u3002\u5F55\u5236/\u56DE\u653E/\u62A5\u544A/\u62BD\u53D6/profile/\u9694\u79BB context \u7B49\u5DE5\u5177\u5F53\u524D\u672A\u6CE8\u518C(toolset=core),\u9700\u8981\u65F6\u628A\u914D\u7F6E\u6539\u4E3A toolset: all \u5E76\u91CD\u542F DSH\u3002\u7528\u6237\u53EF\u901A\u8FC7\u754C\u9762\u53F3\u4E0B\u89D2\u9762\u677F\u7684\u5B9E\u65F6\u753B\u9762\u67E5\u770B\u6D4F\u89C8\u5668\u3002";
4
+ /** 组装完整的工具使用指引文本(DSH systemPrompt 段落与 MCP instructions 共用)。 */
5
+ export declare function browserSystemPrompt(config: Pick<BrowserConfig, "toolset" | "confirmMode">): string;
6
+ export { FULL_TOOL_PROMPT, CORE_TOOL_PROMPT };
7
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1,34 @@
1
+ import type { ConfigSchema } from "./config.js";
2
+ export declare const BROWSER_CONFIG_SCHEMA: ConfigSchema;
3
+ export declare const BROWSER_DEFAULT_CONFIG: {
4
+ channel: string;
5
+ executablePath: string;
6
+ headless: boolean;
7
+ userDataDir: string;
8
+ profiles: {};
9
+ screenshotDir: string;
10
+ downloadDir: string;
11
+ workspaceDir: string;
12
+ screenshotMaxAgeDays: number;
13
+ screenshotMaxCount: number;
14
+ basePath: string;
15
+ recordBodies: boolean;
16
+ maxTextChars: number;
17
+ maxLinks: number;
18
+ timeoutMs: number;
19
+ baselineDir: string;
20
+ selectorHealing: boolean;
21
+ healTimeoutMs: number;
22
+ maxRefs: number;
23
+ maxRows: number;
24
+ snapshotHistory: number;
25
+ confirmMode: string;
26
+ confirmTimeoutMs: number;
27
+ sensitivePatterns: string[];
28
+ sensitiveTools: string[];
29
+ confirmInReplay: boolean;
30
+ somFallback: boolean;
31
+ refReanchor: boolean;
32
+ toolset: string;
33
+ };
34
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1,29 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import type { PlainToolDefinition } from "./lib/types.js";
3
+ import type { BrowserConfig } from "./browser/types.js";
4
+ /**
5
+ * 环境变量 → raw config(DSH_BROWSER_TIMEOUT_MS → timeoutMs)。
6
+ * 值按目标键的 SCHEMA 类型解析:boolean/number 直转,string[] 逗号分隔,
7
+ * any/object 尝试 JSON.parse(失败回退原字符串),其余原样。
8
+ * 嵌套键(profiles/confirmPolicies/humanize)不支持 env,走 JSON 键时可用。
9
+ */
10
+ export declare function configFromEnv(env: NodeJS.ProcessEnv): Record<string, any>;
11
+ /** 收集 registerTools 注册的工具定义(包装层已生效:审批闸/打点/录制)。 */
12
+ export declare function collectToolDefinitions(config: BrowserConfig): Map<string, PlainToolDefinition>;
13
+ /**
14
+ * 根据工具特性映射 MCP 2025 Tool Annotations(只读/破坏性/幂等/开放世界特征提示)。
15
+ */
16
+ export declare function resolveToolAnnotations(name: string): {
17
+ readOnlyHint?: boolean;
18
+ destructiveHint?: boolean;
19
+ idempotentHint?: boolean;
20
+ openWorldHint?: boolean;
21
+ };
22
+ /**
23
+ * 组装 MCP server(不绑定传输,便于 InMemoryTransport 单测)。
24
+ * instructions 与 DSH systemPrompt 同源;inputSchema/outputSchema 直传
25
+ * PlainToolDefinition 的 JSON Schema,不做 zod 转换。
26
+ */
27
+ export declare function createBrowserMcpServer(config: BrowserConfig): Server;
28
+ export declare function main(): Promise<void>;
29
+ //# sourceMappingURL=mcp.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-browser-view",
3
- "version": "0.7.5",
4
- "description": "DSH 插件:共享 Playwright 浏览器自动化(38 个 browser_* 工具,含 what 意图语义定位(一次调用替代快照→查找→点击)、SoM 标徽看图点击与零命中截图兜底、SPA ref 软失效重锚定、open Shadow DOM 组合树穿透、跨 Frame/IFrame 定位、视口感知动态快照、批量表单智能填充、点击效果验证与定位失败遥测、Playwright 规范代码导出、批处理、视觉回归、选择器自愈、增量快照)+ 人机协作(面板点选教学 browser_pick_element、人工接管等待、敏感操作审批硬拦截、人机混合录制、面板一键重跑)+ CDP 流式推流、拟人化轨迹与高斯击键、全景时光机、企业富控件矩阵。仅依赖 playwright-core。",
3
+ "version": "0.8.0",
4
+ "description": "DSH 插件:共享 Playwright 浏览器自动化(38 个 browser_* 工具,含 what 意图语义定位(一次调用替代快照→查找→点击)、SoM 标徽看图点击与零命中截图兜底、SPA ref 软失效重锚定、open Shadow DOM 组合树穿透、跨 Frame/IFrame 定位、视口感知动态快照、批量表单智能填充、点击效果验证与定位失败遥测、Playwright 规范代码导出、批处理、视觉回归、选择器自愈、增量快照)+ 人机协作(面板点选教学 browser_pick_element、人工接管等待、敏感操作审批硬拦截、人机混合录制、面板一键重跑)+ CDP 流式推流、拟人化轨迹与高斯击键、全景时光机、企业富控件矩阵。另附独立 MCP server 入口(bin dsh-browser-mcp,stdio),任意 MCP 客户端可直接调用全部工具。运行时依赖 playwright-core 与 @modelcontextprotocol/sdk(仅 MCP 入口,不进 DSH 插件加载链)。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/types/index.d.ts",
@@ -14,11 +14,20 @@
14
14
  "types": "./lib/types/client/index.d.ts",
15
15
  "default": "./lib/client.js"
16
16
  },
17
+ "./mcp": {
18
+ "types": "./lib/types/mcp.d.ts",
19
+ "default": "./lib/mcp.js"
20
+ },
17
21
  "./package.json": "./package.json"
18
22
  },
23
+ "bin": {
24
+ "dsh-browser-view": "./lib/mcp.js",
25
+ "dsh-browser-mcp": "./lib/mcp.js"
26
+ },
19
27
  "files": [
20
28
  "lib/index.js",
21
29
  "lib/client.js",
30
+ "lib/mcp.js",
22
31
  "lib/types/**/*.d.ts",
23
32
  "cordis.patch.yml",
24
33
  "README.md",
@@ -37,6 +46,7 @@
37
46
  "test:span": "tsx scripts/test-dev-server-clickable-span.ts",
38
47
  "test:pick": "tsx scripts/test-panel-pick.ts",
39
48
  "test:stream": "tsx scripts/test-panel-stream.ts",
49
+ "test:mcp": "tsx scripts/test-mcp-e2e.ts",
40
50
  "dev:server": "tsx scripts/dev-server.ts",
41
51
  "verify": "npm run typecheck && npm run lint && npm run test && npm run build",
42
52
  "prepublishOnly": "npm run verify"
@@ -53,6 +63,9 @@
53
63
  "dsh",
54
64
  "dsh-plugin",
55
65
  "deepseek-harness",
66
+ "mcp",
67
+ "mcp-server",
68
+ "model-context-protocol",
56
69
  "browser",
57
70
  "playwright",
58
71
  "automation",
@@ -63,6 +76,7 @@
63
76
  "node": ">=22"
64
77
  },
65
78
  "dependencies": {
79
+ "@modelcontextprotocol/sdk": "^1.32.2",
66
80
  "playwright-core": "^1.49.0"
67
81
  },
68
82
  "devDependencies": {