dsh-browser-view 0.8.0 → 0.8.2
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/README.md +12 -9
- package/lib/client.js +1 -1
- package/lib/index.js +945 -181
- package/lib/mcp.js +924 -181
- package/lib/types/browser/primitives/dialog.d.ts +21 -4
- package/lib/types/browser/primitives/drag.d.ts +12 -2
- package/lib/types/browser/primitives/index.d.ts +1 -0
- package/lib/types/browser/primitives/ui-library.d.ts +72 -0
- package/lib/types/browser/session/cache.d.ts +12 -0
- package/lib/types/browser/session/collaboration.d.ts +13 -0
- package/lib/types/browser/tools/collaboration.d.ts +16 -13
- package/lib/types/browser/tools/common.d.ts +14 -1
- package/lib/types/browser/tools/interaction.d.ts +17 -2
- package/lib/types/browser/walker.d.ts +10 -0
- package/lib/types/client/api.d.ts +4 -1
- package/lib/types/client/components/LoginWaitCard.d.ts +30 -0
- package/lib/types/client/hooks/useLoginWaitPolling.d.ts +6 -0
- package/lib/types/client/types.d.ts +7 -0
- package/lib/types/lib/prompts.d.ts +2 -2
- package/package.json +2 -1
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import type { Locator, Page } from "playwright-core";
|
|
2
|
+
/** 精确层 = 标准层 + 库精确层(ui-library 注册表单一来源,新增 UI 库 = 追加 spec)。 */
|
|
3
|
+
export declare const DIALOG_PRECISE_SELECTORS: string;
|
|
4
|
+
/** 通用模糊层(未注册库兜底):子串词 + :not() 排除子节点。 */
|
|
5
|
+
export declare const DIALOG_FUZZY_SELECTORS: string;
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
7
|
+
* 历史并集 = 精确层 + 模糊层。semantic.ts 弹窗上下文检测与 getActiveDialog 的
|
|
8
|
+
* domOrder 兜底消费(行为与抽取前的并集等价)。
|
|
5
9
|
*/
|
|
6
10
|
export declare const ACTIVE_DIALOG_SELECTORS: string;
|
|
11
|
+
/** 活动弹窗解析结果:locator + 实际仲裁通道(诊断线索)。 */
|
|
12
|
+
export interface ActiveDialog {
|
|
13
|
+
locator: Locator;
|
|
14
|
+
via: "zIndex" | "domOrder";
|
|
15
|
+
z?: number;
|
|
16
|
+
tier?: "precise" | "fuzzy";
|
|
17
|
+
}
|
|
7
18
|
/**
|
|
8
|
-
*
|
|
19
|
+
* 获取当前页面上处于活动状态的最顶层弹窗容器;无弹窗返回 null。
|
|
20
|
+
* ① 快速通道——并集零命中(绝大多数无弹窗的工具调用)直接返回 null,与旧行为
|
|
21
|
+
* 「空 locator + 下游 count 0」等价,零额外 evaluate 往返;
|
|
22
|
+
* ② 有弹窗时走分层选择器 + 页内 z-index/可见性仲裁(walker pickTopDialog,
|
|
23
|
+
* 页内逻辑单一来源),单次 round-trip;
|
|
24
|
+
* ③ evaluate 失败(极端 CSP/销毁竞态)或复核计数为 0 时回退文档序 last()
|
|
25
|
+
* 旧行为并标 via: "domOrder",不阻断主流程。
|
|
9
26
|
*/
|
|
10
|
-
export declare function getActiveDialog(page: Page):
|
|
27
|
+
export declare function getActiveDialog(page: Page): Promise<ActiveDialog | null>;
|
|
11
28
|
export declare function getActiveDialogSelectors(): string;
|
|
12
29
|
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
import type { Page } from "playwright-core";
|
|
2
|
-
export
|
|
1
|
+
import type { Locator, Page } from "playwright-core";
|
|
2
|
+
export type DragChannel = "dragTo" | "mouse";
|
|
3
|
+
/**
|
|
4
|
+
* 核心:在两个已解析的 Locator 之间执行拖拽。
|
|
5
|
+
* 优先 Playwright dragTo(覆盖 HTML5 DnD 与多数组件库);
|
|
6
|
+
* 失败或调用方指定 preferMouse(如跨 Frame,dragTo 的已知限制)时
|
|
7
|
+
* 降级为物理鼠标序列。返回实际使用的通道。失败抛错(带可定位的诊断信息)。
|
|
8
|
+
*/
|
|
9
|
+
export declare function dragAndDropLocators(page: Page, source: Locator, target: Locator, opts?: {
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
preferMouse?: boolean;
|
|
12
|
+
}): Promise<DragChannel>;
|
|
3
13
|
//# sourceMappingURL=drag.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export declare const GENERIC: {
|
|
2
|
+
readonly dialogWords: readonly ["modal", "drawer", "dialog"];
|
|
3
|
+
readonly dialogExcludedParts: readonly ["mask", "wrap", "root", "header", "footer", "title", "close", "body", "btn"];
|
|
4
|
+
/** 下拉触发器内部件(点它展开) */
|
|
5
|
+
readonly dropdownTriggerParts: "[class*='selector'], [role='combobox']";
|
|
6
|
+
/** 下拉浮层容器的子串词(portal 挂载的面板) */
|
|
7
|
+
readonly dropdownFloatWords: readonly ["select-dropdown", "popper"];
|
|
8
|
+
/** 通用下拉选项行(select 状态机消费;库精确层另补) */
|
|
9
|
+
readonly dropdownOptionRows: "[class*='item-option']:not([class*='empty']), [class*='select-dropdown'] li:not([class*='empty'])";
|
|
10
|
+
/** 可交互「选项」枚举(elements 工具下拉选项清单消费) */
|
|
11
|
+
readonly dropdownOptionEnumeration: string;
|
|
12
|
+
/** 多选标签清除按钮 */
|
|
13
|
+
readonly dropdownClearButtons: "[class*='clear'], [aria-label*='clear']";
|
|
14
|
+
/** 多选标签移除按钮 */
|
|
15
|
+
readonly dropdownRemoveButtons: "[class*='remove'], [class*='close'], [aria-label*='close']";
|
|
16
|
+
/** 空态指示器 */
|
|
17
|
+
readonly emptyStates: "[class*='empty'], [class*='no-data'], [role='status'], [class*='item-empty']";
|
|
18
|
+
/** 表单项容器(宽松:BEM/-item 子串 + group + form 元素;label 反查主用) */
|
|
19
|
+
readonly formItemContainers: "[class*='form-item'], [class*='form__item'], [role='group'], form, .form-group";
|
|
20
|
+
/**
|
|
21
|
+
* 表单项容器(严格:带分隔符前缀,避免 platform-item 之类无关门类误命中;
|
|
22
|
+
* elements 工具页内 labelOf 消费)
|
|
23
|
+
*/
|
|
24
|
+
readonly formItemContainersStrict: "[class*='-form-item'], [class*='__form-item'], form, .form-group";
|
|
25
|
+
/** 表单项宿主判定(目标是否处于表单语境;含 label 本身) */
|
|
26
|
+
readonly formItemHosts: "label, [class*='form-item'], [class*='form__item'], [class*='form-group']";
|
|
27
|
+
/** 表单项 label(dom 原语 label 反查消费) */
|
|
28
|
+
readonly formItemLabels: "[class*='form-item-label'], [class*='form-item__label'], [class*='label'], label";
|
|
29
|
+
/** 表单 label(简化集;elements 工具页内 labelOf 消费) */
|
|
30
|
+
readonly formLabelSimple: "[class*='label'], label";
|
|
31
|
+
};
|
|
32
|
+
export interface UILibrarySpec {
|
|
33
|
+
/** 库标识(诊断与文档)。 */
|
|
34
|
+
name: string;
|
|
35
|
+
/** 模态弹窗容器(参与顶层仲裁的容器级节点)。 */
|
|
36
|
+
modalContainers: string[];
|
|
37
|
+
/** 抽屉容器。 */
|
|
38
|
+
drawerContainers: string[];
|
|
39
|
+
/** 下拉浮层容器(portal 挂载的下拉面板)。 */
|
|
40
|
+
dropdownContainers: string[];
|
|
41
|
+
/** 下拉选项行。 */
|
|
42
|
+
dropdownOptions: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 注册新库(示例:naive-ui):
|
|
46
|
+
* const naiveUi: UILibrarySpec = {
|
|
47
|
+
* name: "naive-ui",
|
|
48
|
+
* modalContainers: [".n-modal-container"],
|
|
49
|
+
* drawerContainers: [".n-drawer-container"],
|
|
50
|
+
* dropdownContainers: [".n-base-select-menu"],
|
|
51
|
+
* dropdownOptions: [".n-base-select-option"],
|
|
52
|
+
* };
|
|
53
|
+
* 追加到 UI_LIBRARIES 即可,弹窗顶层仲裁与下拉浮层发现自动获得该库精确层支持;
|
|
54
|
+
* 未注册的库仍由通用子串层兜底。配套要求:补一个该库真页面的 e2e
|
|
55
|
+
* (playground 模式照抄 test:enterprise),防止想当然的类名污染仲裁。
|
|
56
|
+
*/
|
|
57
|
+
export declare const UI_LIBRARIES: readonly UILibrarySpec[];
|
|
58
|
+
/** 弹窗/抽屉容器(库精确层原料,未加 display:none 预过滤)。 */
|
|
59
|
+
export declare function dialogContainersOf(libs?: readonly UILibrarySpec[]): string[];
|
|
60
|
+
/** 弹窗模糊层选择器串:子串词 + 子节点排除(:not 双命名)+ display:none 预过滤。 */
|
|
61
|
+
export declare function composeDialogFuzzy(words?: readonly string[], excludedParts?: readonly string[]): string;
|
|
62
|
+
/** 下拉浮层容器选择器列表(库精确层 + 通用子串层,均带 display:none 预过滤)。 */
|
|
63
|
+
export declare function dropdownFloatSelectors(libs?: readonly UILibrarySpec[]): string[];
|
|
64
|
+
/** 下拉选项行选择器列表(标准层 role=option 由消费方自带 + 库精确层 + 通用子串层)。 */
|
|
65
|
+
export declare function dropdownOptionRowsOf(libs?: readonly UILibrarySpec[]): string[];
|
|
66
|
+
/** 预组合聚合常量(消费方直接 import)。 */
|
|
67
|
+
export declare const LIBRARY_DIALOG_CONTAINERS: readonly string[];
|
|
68
|
+
export declare const LIBRARY_DROPDOWN_CONTAINERS: readonly string[];
|
|
69
|
+
export declare const LIBRARY_DROPDOWN_OPTIONS: readonly string[];
|
|
70
|
+
/** walker 核心源里应包含的表单词表 token(drift-guard 测试用,见 test/ui-library.test.ts)。 */
|
|
71
|
+
export declare const WALKER_FORM_TOKENS: readonly string[];
|
|
72
|
+
//# sourceMappingURL=ui-library.d.ts.map
|
|
@@ -100,4 +100,16 @@ export declare function pushSnapshotVersion(cache: SnapshotCache | undefined, co
|
|
|
100
100
|
}, capacity: unknown): SnapshotCache;
|
|
101
101
|
/** 按版本号取历史条目;不在环形窗口内(更旧/未知)返回 undefined。 */
|
|
102
102
|
export declare function snapshotVersionEntry(cache: SnapshotCache | undefined, version: number): SnapshotEntry | undefined;
|
|
103
|
+
/** 记录"最近一次成功操作"的导航代际(pageIdentity 打点,零成本)。 */
|
|
104
|
+
export declare function markStableNav(page: Page): void;
|
|
105
|
+
/** 当前代际距最近成功操作代际的差值(≥1 = 期间发生过导航)。 */
|
|
106
|
+
export declare function navSinceStable(page: Page): number;
|
|
107
|
+
export interface ExternalNavNote {
|
|
108
|
+
url: string;
|
|
109
|
+
at: number;
|
|
110
|
+
}
|
|
111
|
+
/** 记录一次疑似外部导航(非工具窗口内发生的 framenavigated)。 */
|
|
112
|
+
export declare function noteExternalNav(page: Page, url: string): void;
|
|
113
|
+
/** 读取并清空疑似外部导航记录,拼装 warning 文案;无记录返回 undefined。 */
|
|
114
|
+
export declare function drainExternalNavWarning(page: Page): string | undefined;
|
|
103
115
|
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -21,6 +21,19 @@ export declare function getPendingConfirm(): PendingConfirm | null;
|
|
|
21
21
|
export declare function clearPendingConfirm(): void;
|
|
22
22
|
/** 面板提交审批决策;id 不匹配(已被新审批取代/超时清理)时返回 false。 */
|
|
23
23
|
export declare function resolveConfirm(id: string, decision: "allowed" | "denied"): boolean;
|
|
24
|
+
/** 一次等待人工登录的请求(browser_wait_for_login 等待期间供面板展示与确认)。 */
|
|
25
|
+
export interface PendingLoginWait {
|
|
26
|
+
id: string;
|
|
27
|
+
instruction: string;
|
|
28
|
+
startedAt: number;
|
|
29
|
+
/** 用户点「我已完成登录」后置 true。 */
|
|
30
|
+
done?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function setPendingLoginWait(entry: PendingLoginWait): void;
|
|
33
|
+
export declare function getPendingLoginWait(): PendingLoginWait | null;
|
|
34
|
+
export declare function clearPendingLoginWait(): void;
|
|
35
|
+
/** 面板提交「用户已完成登录」;id 不匹配(已被新请求取代/超时清理)时返回 false。 */
|
|
36
|
+
export declare function resolveLoginWait(id: string): boolean;
|
|
24
37
|
/** 一次待点选的教学请求(browser_pick_element 等待期间供面板展示与提交)。 */
|
|
25
38
|
export interface PendingPick {
|
|
26
39
|
id: string;
|
|
@@ -5,10 +5,6 @@ import type { BrowserConfig } from "../types.js";
|
|
|
5
5
|
* ~1.5 秒。异步不阻塞(fire-and-forget,任何失败静默),不影响操作时序。
|
|
6
6
|
*/
|
|
7
7
|
export declare function previewHighlight(page: Page | null, selector: string, label: string): void;
|
|
8
|
-
/**
|
|
9
|
-
* 常见认证/登录相关的 URL 特征正则,用于防止跳板页提前误判。
|
|
10
|
-
*/
|
|
11
|
-
export declare const AUTH_URL_PATTERN: RegExp;
|
|
12
8
|
export interface WaitForLoginResult {
|
|
13
9
|
loggedIn: boolean;
|
|
14
10
|
waitedMs: number;
|
|
@@ -17,19 +13,26 @@ export interface WaitForLoginResult {
|
|
|
17
13
|
}
|
|
18
14
|
/**
|
|
19
15
|
* 等待人工登录底层执行(独立导出供测试注入 fake page)。
|
|
20
|
-
*
|
|
21
|
-
* 1.
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
16
|
+
* 完成判定(按优先级):
|
|
17
|
+
* 1. **用户主动告知(主通道)**:pendingLoginWait 单槽状态机,面板常驻登录等待卡
|
|
18
|
+
* 「我已完成登录」按钮 → resolveLoginWait(id),500ms 确认节拍;
|
|
19
|
+
* 2. 显式确定性条件:successSelector(任一存活标签可见)/ successUrl(URL 正则,
|
|
20
|
+
* 任一存活标签命中),pollIntervalMs 节拍多标签扫描,命中即把目标页切为命中页;
|
|
21
|
+
* 3. 超时返回 loggedIn:false(附 waitedMs 与 detail,不抛错)。
|
|
22
|
+
*
|
|
23
|
+
* 登录状态不再自动猜测:URL 认证特征/密码框消除/SPA 签名启发式对「登录表单
|
|
24
|
+
* 隐藏不卸载(keep-alive/微前端)」「登录后 URL 仍含 auth 子串」的 SPA 会永久
|
|
25
|
+
* 漏判(用户已登录仍空转到超时),已整体移除——登录完成由用户说了算。
|
|
26
|
+
* 保留:存活标签感知(原标签关闭自愈迁移、新标签经 onNewPageDetected 注册)。
|
|
26
27
|
*/
|
|
27
28
|
export declare function runWaitForLoginOnPage(initialPage: Page, args: Record<string, any>, onNewPageDetected?: (page: Page) => void): Promise<WaitForLoginResult>;
|
|
28
29
|
/**
|
|
29
30
|
* 等待人工登录完成(配合 headless:false 使用):agent 打开登录页后调用本工具,
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* 用户在浏览器窗口完成登录(输入/扫码/双因素)后,在实时画面面板的**常驻登录
|
|
32
|
+
* 等待卡**上点「我已完成登录」主动告知,工具立即返回(500ms 确认节拍)。
|
|
33
|
+
* 亦支持显式确定性条件 successSelector/successUrl(多标签扫描自动判定)。
|
|
34
|
+
* 不做任何登录状态启发式猜测。超时返回 loggedIn:false(附 waitedMs 与
|
|
35
|
+
* detail,不抛错)。无面板环境(MCP 独立模式)必须显式给条件,否则 fail-fast。
|
|
33
36
|
*/
|
|
34
37
|
export declare function waitForLoginTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
35
38
|
url: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** 组件库下拉框的可见选项枚举(ui-library 注册表单一来源,值与抽取前等价)。 */
|
|
2
2
|
export declare const DROPDOWN_OPTION_SELECTOR: string;
|
|
3
3
|
/** 读取 PNG 文件头(IHDR)中的宽高,不解码像素(导出供测试)。 */
|
|
4
4
|
export declare function pngSize(buf: Buffer): {
|
|
@@ -60,8 +60,21 @@ export declare function unwrapDoubleEncodedScript(script: string): {
|
|
|
60
60
|
};
|
|
61
61
|
/** 工作区内落盘路径解析(拒绝穿越到工作区之外)。 */
|
|
62
62
|
export declare function workspaceFilePath(cwd: string, file: string): string;
|
|
63
|
+
export type EvalWrapMode = "expression" | "statements-auto-return" | "statements";
|
|
64
|
+
export interface EvalWrapResult {
|
|
65
|
+
code: string;
|
|
66
|
+
mode: EvalWrapMode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 把 eval 脚本包装成可直接交给 page.evaluate 的代码串,并标明实际执行形态。
|
|
70
|
+
* 语法非法时在 Node 侧抛出引擎原始错误(消息与页内 V8 同源,提前暴露)。
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildEvalScript(script: string): EvalWrapResult;
|
|
63
73
|
/**
|
|
64
74
|
* 规则化抽取:fields 定义抽取结构,next 选择器驱动翻页(maxPages 上限),
|
|
65
75
|
* 行数超 maxRows 截断;format/file 控制序列化与落盘(json/csv/jsonl/markdown)。
|
|
66
76
|
*/
|
|
77
|
+
export declare function assertExpectedUrl(page: {
|
|
78
|
+
url(): string;
|
|
79
|
+
}, expectUrl: unknown, action: string): Promise<void>;
|
|
67
80
|
//# sourceMappingURL=common.d.ts.map
|
|
@@ -2,12 +2,14 @@ import type { ToolRunContext } from "../../lib/types.js";
|
|
|
2
2
|
import type { BrowserConfig } from "../types.js";
|
|
3
3
|
import { targetLocator, resolveTargetLocator } from "../session.js";
|
|
4
4
|
import { type FormFillResult } from "../primitives/index.js";
|
|
5
|
+
import * as primitives from "../primitives/index.js";
|
|
5
6
|
export { targetLocator, resolveTargetLocator };
|
|
6
7
|
export declare function isBotSensitiveUrl(url: string): boolean;
|
|
7
8
|
export declare function clickTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
|
|
8
9
|
url: string;
|
|
9
10
|
title: string;
|
|
10
11
|
viaBridge?: boolean | undefined;
|
|
12
|
+
warning?: string | undefined;
|
|
11
13
|
effectHint?: string | undefined;
|
|
12
14
|
clicked: string;
|
|
13
15
|
effect: {
|
|
@@ -25,20 +27,24 @@ export declare function clickTool(config: BrowserConfig, args: Record<string, an
|
|
|
25
27
|
url: string;
|
|
26
28
|
title: string;
|
|
27
29
|
viaBridge?: boolean | undefined;
|
|
30
|
+
warning?: string | undefined;
|
|
28
31
|
clicked: string;
|
|
29
32
|
}>;
|
|
30
33
|
export declare function typeTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
31
34
|
url: string;
|
|
32
35
|
title: string;
|
|
33
36
|
typed: boolean;
|
|
34
|
-
|
|
37
|
+
typedVia: "editor";
|
|
35
38
|
selector: string;
|
|
36
39
|
} | {
|
|
37
40
|
url: string;
|
|
38
41
|
title: string;
|
|
39
|
-
typed: boolean;
|
|
40
42
|
selector: string;
|
|
41
43
|
submit: boolean;
|
|
44
|
+
warning?: string | undefined;
|
|
45
|
+
focusedElement?: string | undefined;
|
|
46
|
+
typed: boolean;
|
|
47
|
+
typedVia: "fill" | "clicked" | "focus-kept";
|
|
42
48
|
}>;
|
|
43
49
|
export declare function pressTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
44
50
|
url: string;
|
|
@@ -53,12 +59,14 @@ export declare function pressTool(config: BrowserConfig, args: Record<string, an
|
|
|
53
59
|
export declare function selectTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
54
60
|
url: string;
|
|
55
61
|
title: string;
|
|
62
|
+
warning?: string | undefined;
|
|
56
63
|
selected: string;
|
|
57
64
|
selector: string;
|
|
58
65
|
}>;
|
|
59
66
|
export declare function evalTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
60
67
|
scriptUnwrapped?: boolean | undefined;
|
|
61
68
|
result: unknown;
|
|
69
|
+
mode: import("./common.js").EvalWrapMode;
|
|
62
70
|
}>;
|
|
63
71
|
export declare function downloadTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
|
|
64
72
|
path: string;
|
|
@@ -140,10 +148,17 @@ export declare function transferTool(config: BrowserConfig, args: Record<string,
|
|
|
140
148
|
direction: string;
|
|
141
149
|
items: string[];
|
|
142
150
|
}>;
|
|
151
|
+
/**
|
|
152
|
+
* browser_drag:在页面里把源元素拖到目标元素上。
|
|
153
|
+
* 源/目标各自走统一定位管线(selector / ref / what+scope / mark 四选一前缀),
|
|
154
|
+
* 支持 HTML5 原生拖放(dragTo)与鼠标拖动类控件(物理鼠标序列降级);
|
|
155
|
+
* 跨 Frame 拖拽自动绕过 dragTo 的同 Frame 限制。
|
|
156
|
+
*/
|
|
143
157
|
export declare function dragTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
144
158
|
url: string;
|
|
145
159
|
title: string;
|
|
146
160
|
dragged: boolean;
|
|
161
|
+
via: primitives.DragChannel;
|
|
147
162
|
source: string;
|
|
148
163
|
target: string;
|
|
149
164
|
}>;
|
|
@@ -24,11 +24,21 @@ declare function __walkerCore(): {
|
|
|
24
24
|
};
|
|
25
25
|
/** walker 核心注入后暴露给 entry 的 API(类型层)。 */
|
|
26
26
|
export type WalkerApi = ReturnType<typeof __walkerCore>;
|
|
27
|
+
/** walker 核心序列化源(导出供 drift-guard 测试核对表单词表与注册表一致性)。 */
|
|
28
|
+
export declare const WALKER_CORE_SRC: string;
|
|
27
29
|
/**
|
|
28
30
|
* 把消费方 entry(自包含函数,签名 (payload, w: WalkerApi) => R)拼装成
|
|
29
31
|
* 可被 page.evaluate 序列化的独立函数 (payload: P) => R。
|
|
30
32
|
* 拼装发生在模块加载期(new Function 一次性),调用期零开销。
|
|
31
33
|
*/
|
|
32
34
|
export declare function injectWalker<P, R>(entry: (payload: P, w: WalkerApi) => R): (payload: P) => R;
|
|
35
|
+
export declare const pickTopDialog: (payload: {
|
|
36
|
+
precise: string;
|
|
37
|
+
fuzzy: string;
|
|
38
|
+
}) => {
|
|
39
|
+
selector: string;
|
|
40
|
+
z: number;
|
|
41
|
+
tier: "precise" | "fuzzy";
|
|
42
|
+
} | null;
|
|
33
43
|
export {};
|
|
34
44
|
//# sourceMappingURL=walker.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BrowserOp, BrowserStatus, LatestRun, NavHistoryItem, PendingConfirm, PendingPick, RecordingDetail, RecordingRow } from "./types.js";
|
|
1
|
+
import type { BrowserOp, BrowserStatus, LatestRun, NavHistoryItem, PendingConfirm, PendingLoginWait, PendingPick, RecordingDetail, RecordingRow } from "./types.js";
|
|
2
2
|
/** 获取插件后端 API 基路径 (默认为 /browser) */
|
|
3
3
|
export declare function getBasePath(): Promise<string>;
|
|
4
4
|
export declare function fetchStatus(base: string): Promise<BrowserStatus | null>;
|
|
@@ -11,6 +11,9 @@ export declare function fetchLatestRun(base: string): Promise<{
|
|
|
11
11
|
export declare function fetchPendingConfirm(base: string): Promise<PendingConfirm | null>;
|
|
12
12
|
export declare function submitConfirmDecision(base: string, id: string, decision: "allowed" | "denied"): Promise<boolean>;
|
|
13
13
|
export declare function fetchPendingPick(base: string): Promise<PendingPick | null>;
|
|
14
|
+
export declare function fetchPendingLoginWait(base: string): Promise<PendingLoginWait | null>;
|
|
15
|
+
/** 提交「用户已完成登录」确认。 */
|
|
16
|
+
export declare function submitLoginDone(base: string, id: string): Promise<boolean>;
|
|
14
17
|
/** 提交点选坐标(x/y 为截图位图像素坐标,imgW/imgH 为截图尺寸;服务端换算成视口 CSS 坐标)。 */
|
|
15
18
|
export declare function submitPick(base: string, id: string, x: number, y: number, imgW: number, imgH: number): Promise<boolean>;
|
|
16
19
|
export declare function triggerRerun(base: string, source: string, retryOf?: string): Promise<{
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PendingLoginWait } from "../types.js";
|
|
2
|
+
interface LoginWaitCardProps {
|
|
3
|
+
loginWait: PendingLoginWait;
|
|
4
|
+
onDone: () => void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* browser_wait_for_login 等待期间常驻悬浮于 FAB 上方(面板收起也可见):
|
|
8
|
+
* 用户此时在浏览器窗口里登录,可能不看 DSH 面板,卡片必须始终露出。
|
|
9
|
+
* 「我已完成登录」→ POST /browser/login → 工具立即返回 loggedIn:true。
|
|
10
|
+
*/
|
|
11
|
+
export declare function LoginWaitCard({ loginWait, onDone }: LoginWaitCardProps): import("react").DetailedReactHTMLElement<{
|
|
12
|
+
style: {
|
|
13
|
+
position: "fixed";
|
|
14
|
+
right: string;
|
|
15
|
+
bottom: string;
|
|
16
|
+
width: string;
|
|
17
|
+
padding: string;
|
|
18
|
+
borderRadius: string;
|
|
19
|
+
border: string;
|
|
20
|
+
background: string;
|
|
21
|
+
color: "#15803d";
|
|
22
|
+
fontSize: string;
|
|
23
|
+
lineHeight: string;
|
|
24
|
+
boxShadow: "0 4px 16px rgba(0, 0, 0, 0.18)";
|
|
25
|
+
pointerEvents: "auto";
|
|
26
|
+
};
|
|
27
|
+
title: string;
|
|
28
|
+
}, HTMLElement>;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=LoginWaitCard.d.ts.map
|
|
@@ -56,6 +56,13 @@ export interface PendingPick {
|
|
|
56
56
|
instruction: string;
|
|
57
57
|
startedAt: number;
|
|
58
58
|
}
|
|
59
|
+
/** 等待人工登录请求(browser_wait_for_login 等待期间轮询到,用户点「我已完成登录」)。 */
|
|
60
|
+
export interface PendingLoginWait {
|
|
61
|
+
id: string;
|
|
62
|
+
instruction: string;
|
|
63
|
+
startedAt: number;
|
|
64
|
+
done?: boolean;
|
|
65
|
+
}
|
|
59
66
|
export interface LatestRun {
|
|
60
67
|
runId: string;
|
|
61
68
|
ts: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
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\
|
|
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";
|
|
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\u5728\u6D4F\u89C8\u5668\u7A97\u53E3\u5B8C\u6210\u767B\u5F55\u540E\u70B9\u9762\u677F\u767B\u5F55\u5361\u4E0A\u7684\u300C\u6211\u5DF2\u5B8C\u6210\u767B\u5F55\u300D,\u518D\u8C03\u7528 browser_wait_for_login \u7B49\u5F85(\u7528\u6237\u70B9\u6309\u94AE\u5373\u8FD4\u56DE,\u4E0D\u81EA\u52A8\u731C\u6D4B\u767B\u5F55\u72B6\u6001;\u4E5F\u53EF\u7ED9 successSelector/successUrl \u4F5C\u786E\u5B9A\u6027\u81EA\u52A8\u6761\u4EF6;\u65E0\u9762\u677F\u73AF\u5883\u5FC5\u987B\u7ED9\u5176\u4E00,\u5426\u5219\u8C03\u7528\u4F1A\u62A5\u9519);\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(\u7528\u6237\u5728\u9762\u677F\u70B9\u300C\u6211\u5DF2\u5B8C\u6210\u767B\u5F55\u300D\u5373\u8FD4\u56DE;\u65E0\u9762\u677F\u73AF\u5883\u5FC5\u987B\u7ED9 successSelector/successUrl,\u5426\u5219\u8C03\u7528\u62A5\u9519),\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
4
|
/** 组装完整的工具使用指引文本(DSH systemPrompt 段落与 MCP instructions 共用)。 */
|
|
5
5
|
export declare function browserSystemPrompt(config: Pick<BrowserConfig, "toolset" | "confirmMode">): string;
|
|
6
6
|
export { FULL_TOOL_PROMPT, CORE_TOOL_PROMPT };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-browser-view",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
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",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"test:enterprise": "tsx scripts/test-dev-server-enterprise.ts",
|
|
44
44
|
"test:energy": "tsx scripts/test-dev-server-energy.ts",
|
|
45
45
|
"test:shadow": "tsx scripts/test-dev-server-shadow.ts",
|
|
46
|
+
"test:drag": "tsx scripts/test-dev-server-drag.ts",
|
|
46
47
|
"test:span": "tsx scripts/test-dev-server-clickable-span.ts",
|
|
47
48
|
"test:pick": "tsx scripts/test-panel-pick.ts",
|
|
48
49
|
"test:stream": "tsx scripts/test-panel-stream.ts",
|