dsh-browser-view 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +134 -2
- package/cordis.patch.yml +31 -0
- package/lib/client.js +2 -0
- package/lib/index.js +2949 -0
- package/lib/types/browser/recordings.d.ts +31 -0
- package/lib/types/browser/register.d.ts +4 -0
- package/lib/types/browser/session.d.ts +103 -0
- package/lib/types/browser/tools.d.ts +339 -0
- package/lib/types/browser/types.d.ts +55 -0
- package/lib/types/browser/ui.d.ts +4 -0
- package/lib/types/client/index.d.ts +26 -0
- package/lib/types/embed.d.ts +7 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/lib/config.d.ts +17 -0
- package/lib/types/lib/http.d.ts +12 -0
- package/lib/types/lib/tools.d.ts +26 -0
- package/lib/types/lib/types.d.ts +59 -0
- package/package.json +76 -4
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** 录制存储目录($DSH_HOME/.dsh-browser/recordings)。 */
|
|
2
|
+
export declare function recordingsDir(): string;
|
|
3
|
+
/** 名字安全化:只保留字母数字 . _ -,连续点压成下划线防路径穿越。 */
|
|
4
|
+
export declare function safeName(name: string): string;
|
|
5
|
+
/** 加载目录下所有 .json 录制进内存表;返回加载数量。坏文件静默跳过。 */
|
|
6
|
+
export declare function loadRecordings(): number;
|
|
7
|
+
/** 写一个录制到磁盘(原子替换);返回文件路径。 */
|
|
8
|
+
export declare function saveRecordingFile(name: string, steps: {
|
|
9
|
+
tool: string;
|
|
10
|
+
args: any;
|
|
11
|
+
}[]): string;
|
|
12
|
+
/** 删除磁盘上的录制文件;返回是否存在并删除。 */
|
|
13
|
+
export declare function deleteRecordingFile(name: string): boolean;
|
|
14
|
+
/** 录制列表(面板 / browser_record list 共用)。 */
|
|
15
|
+
export declare function listRecordings(): Array<{
|
|
16
|
+
name: string;
|
|
17
|
+
steps: number;
|
|
18
|
+
savedAt: number;
|
|
19
|
+
preview: string;
|
|
20
|
+
}>;
|
|
21
|
+
/** 录制详情(面板展开查看步骤)。 */
|
|
22
|
+
export declare function recordingDetail(name: string): {
|
|
23
|
+
name: string;
|
|
24
|
+
steps: {
|
|
25
|
+
tool: string;
|
|
26
|
+
args: any;
|
|
27
|
+
}[];
|
|
28
|
+
} | undefined;
|
|
29
|
+
/** 删除录制(内存 + 磁盘同步);返回是否存在并删除。 */
|
|
30
|
+
export declare function deleteRecording(name: string): boolean;
|
|
31
|
+
//# sourceMappingURL=recordings.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { Page } from "playwright-core";
|
|
2
|
+
import type { BrowserConfig, ProfileState, DownloadEntry, FormField, NavEntry } from "./types.js";
|
|
3
|
+
/** 当前活动 profile 名(默认 "default")。 */
|
|
4
|
+
export declare let currentProfile: string;
|
|
5
|
+
/** 多配置文件浏览器会话:name → 会话状态。 */
|
|
6
|
+
export declare const profileStates: Map<string, ProfileState>;
|
|
7
|
+
/** 已保存的表单回放:name → fields 数组。 */
|
|
8
|
+
export declare const savedForms: Map<string, FormField[]>;
|
|
9
|
+
/** 最近一次 browser_form 填充的字段(供 browser_form_save 无参保存)。 */
|
|
10
|
+
export declare let lastFormFields: FormField[];
|
|
11
|
+
/** 已保存的录制脚本:name → 步骤数组。 */
|
|
12
|
+
export declare const savedRecordings: Map<string, {
|
|
13
|
+
steps: {
|
|
14
|
+
tool: string;
|
|
15
|
+
args: any;
|
|
16
|
+
}[];
|
|
17
|
+
savedAt: number;
|
|
18
|
+
}>;
|
|
19
|
+
/** 一次工具调用的记录(操作轨迹 / 录制 / 回放共用)。 */
|
|
20
|
+
export interface TestCall {
|
|
21
|
+
tool: string;
|
|
22
|
+
args: Record<string, any>;
|
|
23
|
+
ok: boolean;
|
|
24
|
+
ms: number;
|
|
25
|
+
ts: number;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function isRecording(): boolean;
|
|
29
|
+
export declare function startRecording(): void;
|
|
30
|
+
export declare function stopRecording(): TestCall[];
|
|
31
|
+
/** 操作轨迹追加(同时写入录制 buffer,排除 record/replay 自身)。 */
|
|
32
|
+
export declare function recordCall(call: TestCall): void;
|
|
33
|
+
/** 操作轨迹(按时间倒序,最新在前)。 */
|
|
34
|
+
export declare function testLogOf(): TestCall[];
|
|
35
|
+
export declare function clearTestLog(): void;
|
|
36
|
+
/** 网络请求/响应记录。 */
|
|
37
|
+
export interface NetworkEntry {
|
|
38
|
+
url: string;
|
|
39
|
+
method: string;
|
|
40
|
+
resourceType: string;
|
|
41
|
+
status?: number;
|
|
42
|
+
ok?: boolean;
|
|
43
|
+
failed?: boolean;
|
|
44
|
+
error?: string;
|
|
45
|
+
startedAt: number;
|
|
46
|
+
durationMs?: number;
|
|
47
|
+
/** 请求体(截断,默认记录)。 */
|
|
48
|
+
postData?: string | null;
|
|
49
|
+
/** 响应体(截断,默认记录;SSE 与大响应跳过)。 */
|
|
50
|
+
body?: string | null;
|
|
51
|
+
}
|
|
52
|
+
export declare function networkEntries(name: string): NetworkEntry[];
|
|
53
|
+
export declare function addNetworkEntry(profile: string, entry: NetworkEntry): void;
|
|
54
|
+
export declare function clearNetwork(profile: string): void;
|
|
55
|
+
export declare function profileConfig(config: BrowserConfig, name: string): BrowserConfig;
|
|
56
|
+
export declare function getProfileState(name: string): ProfileState;
|
|
57
|
+
export declare function downloadsOf(name: string): DownloadEntry[];
|
|
58
|
+
/** 某 profile 的访问历史(按时间先后)。 */
|
|
59
|
+
export declare function historyOf(name: string): NavEntry[];
|
|
60
|
+
export declare function attachPage(page: Page, config: BrowserConfig): void;
|
|
61
|
+
export declare function loadPlaywright(): Promise<typeof import("playwright-core")>;
|
|
62
|
+
export declare function launchProfile(name: string, config: BrowserConfig): Promise<void>;
|
|
63
|
+
/** 当前 profile 状态(未启动时创建空状态)。 */
|
|
64
|
+
export declare function stateOf(): ProfileState;
|
|
65
|
+
/** 新建一个页面(当前 profile 会话未启动时先启动)。 */
|
|
66
|
+
export declare function newPage(config: BrowserConfig): Promise<Page>;
|
|
67
|
+
/** 返回当前活动页面(没有则新建),并保证浏览器已启动。 */
|
|
68
|
+
export declare function getPage(config: BrowserConfig): Promise<Page>;
|
|
69
|
+
/** 活动页面(可能为 null,不触发启动)。 */
|
|
70
|
+
export declare function activePage(): Page | null;
|
|
71
|
+
/** 投影当前 profile 的标签列表。 */
|
|
72
|
+
export declare function tabList(): Promise<{
|
|
73
|
+
id: number;
|
|
74
|
+
url: string;
|
|
75
|
+
title: string;
|
|
76
|
+
}[]>;
|
|
77
|
+
export declare function closeBrowser(): Promise<void>;
|
|
78
|
+
/** Best-effort current page identity, safe when nothing is open. */
|
|
79
|
+
export declare function pageIdentity(page: Page): Promise<{
|
|
80
|
+
url: string;
|
|
81
|
+
title: string;
|
|
82
|
+
}>;
|
|
83
|
+
/** 设置最近一次表单填充(供 browser_form_save 无参保存)。 */
|
|
84
|
+
export declare function setLastFormFields(fields: FormField[]): void;
|
|
85
|
+
/** 切换当前 profile。 */
|
|
86
|
+
export declare function setCurrentProfile(name: string): void;
|
|
87
|
+
/** 记录最近一次截图目录(截图工具调用时写入)。 */
|
|
88
|
+
export declare function noteScreenshotDir(dir: string): void;
|
|
89
|
+
/** 定时清扫入口:若已知截图目录则按当前配置清理。 */
|
|
90
|
+
export declare function sweepScreenshotDir(opts: {
|
|
91
|
+
maxAgeDays?: number;
|
|
92
|
+
maxCount?: number;
|
|
93
|
+
}): number;
|
|
94
|
+
/**
|
|
95
|
+
* 清理截图目录里的 .png 文件:按修改时间保留最新的 maxCount 个,
|
|
96
|
+
* 并删除超过 maxAgeDays 天的旧文件。只处理目录直属文件,不递归;
|
|
97
|
+
* 单个文件删除失败(被占用等)静默跳过。返回删除数量。
|
|
98
|
+
*/
|
|
99
|
+
export declare function cleanupScreenshots(dir: string, opts: {
|
|
100
|
+
maxAgeDays?: number;
|
|
101
|
+
maxCount?: number;
|
|
102
|
+
}): number;
|
|
103
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import type { Page } from "playwright-core";
|
|
2
|
+
import type { ToolRunContext } from "../lib/types.js";
|
|
3
|
+
import type { BrowserConfig } from "./types.js";
|
|
4
|
+
export declare function openTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
5
|
+
url: string;
|
|
6
|
+
title: string;
|
|
7
|
+
status: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function snapshotTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
10
|
+
text: string;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
links: {
|
|
13
|
+
text: string;
|
|
14
|
+
href: string;
|
|
15
|
+
}[];
|
|
16
|
+
inputs: number;
|
|
17
|
+
url: string;
|
|
18
|
+
title: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function clickTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
21
|
+
url: string;
|
|
22
|
+
title: string;
|
|
23
|
+
clicked: string;
|
|
24
|
+
}>;
|
|
25
|
+
export declare function typeTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
26
|
+
url: string;
|
|
27
|
+
title: string;
|
|
28
|
+
typed: boolean;
|
|
29
|
+
selector: string;
|
|
30
|
+
submit: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
export declare function pressTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
33
|
+
url: string;
|
|
34
|
+
title: string;
|
|
35
|
+
pressed: string;
|
|
36
|
+
}>;
|
|
37
|
+
export declare function evalTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
38
|
+
result: unknown;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function screenshotTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
|
|
41
|
+
path: string;
|
|
42
|
+
bytes: number;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
}>;
|
|
46
|
+
export declare function waitTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
47
|
+
url: string;
|
|
48
|
+
title: string;
|
|
49
|
+
waitedMs: number;
|
|
50
|
+
}>;
|
|
51
|
+
export declare function backTool(config: BrowserConfig): Promise<{
|
|
52
|
+
url: string;
|
|
53
|
+
title: string;
|
|
54
|
+
}>;
|
|
55
|
+
export declare function reloadTool(config: BrowserConfig): Promise<{
|
|
56
|
+
url: string;
|
|
57
|
+
title: string;
|
|
58
|
+
}>;
|
|
59
|
+
export declare function statusTool(): Promise<{
|
|
60
|
+
open: boolean;
|
|
61
|
+
profile: string;
|
|
62
|
+
channel: string;
|
|
63
|
+
tabs: number;
|
|
64
|
+
profiles: {
|
|
65
|
+
name: string;
|
|
66
|
+
open: boolean;
|
|
67
|
+
tabs: number;
|
|
68
|
+
channel: string;
|
|
69
|
+
persistent: boolean;
|
|
70
|
+
}[];
|
|
71
|
+
} | {
|
|
72
|
+
url: string;
|
|
73
|
+
title: string;
|
|
74
|
+
open: boolean;
|
|
75
|
+
profile: string;
|
|
76
|
+
channel: string;
|
|
77
|
+
tabs: number;
|
|
78
|
+
profiles: {
|
|
79
|
+
name: string;
|
|
80
|
+
open: boolean;
|
|
81
|
+
tabs: number;
|
|
82
|
+
channel: string;
|
|
83
|
+
persistent: boolean;
|
|
84
|
+
}[];
|
|
85
|
+
}>;
|
|
86
|
+
export declare function tabsTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
87
|
+
action: any;
|
|
88
|
+
tabs: {
|
|
89
|
+
id: number;
|
|
90
|
+
url: string;
|
|
91
|
+
title: string;
|
|
92
|
+
}[];
|
|
93
|
+
activeId: number;
|
|
94
|
+
tab?: undefined;
|
|
95
|
+
} | {
|
|
96
|
+
action: any;
|
|
97
|
+
tab: {
|
|
98
|
+
id: number;
|
|
99
|
+
url: string;
|
|
100
|
+
title: string;
|
|
101
|
+
};
|
|
102
|
+
tabs: {
|
|
103
|
+
id: number;
|
|
104
|
+
url: string;
|
|
105
|
+
title: string;
|
|
106
|
+
}[];
|
|
107
|
+
activeId: number;
|
|
108
|
+
}>;
|
|
109
|
+
export declare function resolveTabId(args: Record<string, any>): number;
|
|
110
|
+
export declare function downloadTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
|
|
111
|
+
path: string;
|
|
112
|
+
filename: string;
|
|
113
|
+
url: string;
|
|
114
|
+
bytes: number;
|
|
115
|
+
}>;
|
|
116
|
+
export declare function uploadTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
|
|
117
|
+
url: string;
|
|
118
|
+
title: string;
|
|
119
|
+
uploaded: string;
|
|
120
|
+
bytes: number;
|
|
121
|
+
}>;
|
|
122
|
+
export declare function cookiesTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
123
|
+
cookies: {
|
|
124
|
+
name: string;
|
|
125
|
+
value: string;
|
|
126
|
+
domain: string;
|
|
127
|
+
path: string;
|
|
128
|
+
httpOnly: boolean;
|
|
129
|
+
secure: boolean;
|
|
130
|
+
sameSite: "Strict" | "Lax" | "None";
|
|
131
|
+
expires: number;
|
|
132
|
+
}[];
|
|
133
|
+
set?: undefined;
|
|
134
|
+
name?: undefined;
|
|
135
|
+
url?: undefined;
|
|
136
|
+
cleared?: undefined;
|
|
137
|
+
} | {
|
|
138
|
+
set: boolean;
|
|
139
|
+
name: string;
|
|
140
|
+
url: any;
|
|
141
|
+
cookies?: undefined;
|
|
142
|
+
cleared?: undefined;
|
|
143
|
+
} | {
|
|
144
|
+
cleared: boolean;
|
|
145
|
+
cookies?: undefined;
|
|
146
|
+
set?: undefined;
|
|
147
|
+
name?: undefined;
|
|
148
|
+
url?: undefined;
|
|
149
|
+
}>;
|
|
150
|
+
export declare function formTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
151
|
+
url: string;
|
|
152
|
+
title: string;
|
|
153
|
+
filled: ({
|
|
154
|
+
selector: any;
|
|
155
|
+
label?: undefined;
|
|
156
|
+
} | {
|
|
157
|
+
label: any;
|
|
158
|
+
selector?: undefined;
|
|
159
|
+
})[];
|
|
160
|
+
submit: boolean;
|
|
161
|
+
}>;
|
|
162
|
+
export declare function formSaveTool(args: Record<string, any>): Promise<{
|
|
163
|
+
saved: string;
|
|
164
|
+
fields: number;
|
|
165
|
+
}>;
|
|
166
|
+
export declare function formsTool(args: Record<string, any>): Promise<{
|
|
167
|
+
forms: {
|
|
168
|
+
name: string;
|
|
169
|
+
fields: number;
|
|
170
|
+
preview: string;
|
|
171
|
+
}[];
|
|
172
|
+
deleted?: undefined;
|
|
173
|
+
name?: undefined;
|
|
174
|
+
} | {
|
|
175
|
+
deleted: boolean;
|
|
176
|
+
name: string;
|
|
177
|
+
forms?: undefined;
|
|
178
|
+
}>;
|
|
179
|
+
export declare function profileTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
180
|
+
current: string;
|
|
181
|
+
profiles: {
|
|
182
|
+
name: string;
|
|
183
|
+
open: boolean;
|
|
184
|
+
tabs: number;
|
|
185
|
+
persistent: boolean;
|
|
186
|
+
userDataDir: string;
|
|
187
|
+
}[];
|
|
188
|
+
}>;
|
|
189
|
+
export declare function elementsTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
190
|
+
count: number;
|
|
191
|
+
elements: Record<string, unknown>[];
|
|
192
|
+
}>;
|
|
193
|
+
export declare function closeTool(): Promise<{
|
|
194
|
+
closed: boolean;
|
|
195
|
+
}>;
|
|
196
|
+
/**
|
|
197
|
+
* 条件检查引擎(测试原语共用)。
|
|
198
|
+
*
|
|
199
|
+
* cond 支持四类(每类内部互斥,取第一个存在的字段):
|
|
200
|
+
* { selector: "#btn", state: "visible|hidden|attached|detached" } 元素状态(默认 visible)
|
|
201
|
+
* { url: "正则字符串" } 当前 URL 匹配
|
|
202
|
+
* { text: "子串" } body 可见文本包含
|
|
203
|
+
* { count: { selector, op: "eq|gt|gte|lt|lte", value: n } } 元素数量比较
|
|
204
|
+
* { eval: "JS 表达式" } 表达式求值 truthy
|
|
205
|
+
*/
|
|
206
|
+
export type TestCondition = Record<string, any>;
|
|
207
|
+
/** 单次检查:返回 { ok, detail }。不抛错,失败时 detail 给出原因。 */
|
|
208
|
+
export declare function checkOnce(page: Page, cond: TestCondition): Promise<{
|
|
209
|
+
ok: boolean;
|
|
210
|
+
detail?: string;
|
|
211
|
+
}>;
|
|
212
|
+
/** 轮询等待条件成立(intervalMs 步进),返回最后一次检查结果。 */
|
|
213
|
+
export declare function pollCondition(page: Page, cond: TestCondition, timeoutMs: number, intervalMs?: number): Promise<{
|
|
214
|
+
ok: boolean;
|
|
215
|
+
detail?: string;
|
|
216
|
+
}>;
|
|
217
|
+
/** 通用显式等待:等待条件成立,超时抛错。 */
|
|
218
|
+
export declare function waitForTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
219
|
+
url: string;
|
|
220
|
+
title: string;
|
|
221
|
+
met: boolean;
|
|
222
|
+
}>;
|
|
223
|
+
/**
|
|
224
|
+
* 等待人工登录完成(配合 headless:false 使用):agent 打开登录页后调用本工具,
|
|
225
|
+
* 提示用户在浏览器窗口中完成登录(输入/扫码/双因素)。基于通用条件引擎:
|
|
226
|
+
* successSelector / successUrl 指定完成条件,两者都不给则以 URL 跳转视为完成。
|
|
227
|
+
* 超时返回 loggedIn:false(不抛错)。
|
|
228
|
+
*/
|
|
229
|
+
export declare function waitForLoginTool(config: BrowserConfig, args: Record<string, any>): Promise<{
|
|
230
|
+
url: string;
|
|
231
|
+
title: string;
|
|
232
|
+
loggedIn: boolean;
|
|
233
|
+
}>;
|
|
234
|
+
/** 断言:条件在 timeoutMs 内成立则通过,否则失败并自动截图存证据。 */
|
|
235
|
+
export declare function assertTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
|
|
236
|
+
url: string;
|
|
237
|
+
title: string;
|
|
238
|
+
passed: boolean;
|
|
239
|
+
}>;
|
|
240
|
+
/** 网络记录查询:list / failed / wait / clear。 */
|
|
241
|
+
export declare function networkTool(args: Record<string, any>): Promise<{
|
|
242
|
+
cleared: boolean;
|
|
243
|
+
entries: number;
|
|
244
|
+
matched?: undefined;
|
|
245
|
+
waitMs?: undefined;
|
|
246
|
+
failed?: undefined;
|
|
247
|
+
} | {
|
|
248
|
+
matched: import("./session.js").NetworkEntry;
|
|
249
|
+
waitMs: number;
|
|
250
|
+
cleared?: undefined;
|
|
251
|
+
entries?: undefined;
|
|
252
|
+
failed?: undefined;
|
|
253
|
+
} | {
|
|
254
|
+
failed: import("./session.js").NetworkEntry[];
|
|
255
|
+
cleared?: undefined;
|
|
256
|
+
entries?: undefined;
|
|
257
|
+
matched?: undefined;
|
|
258
|
+
waitMs?: undefined;
|
|
259
|
+
} | {
|
|
260
|
+
entries: import("./session.js").NetworkEntry[];
|
|
261
|
+
cleared?: undefined;
|
|
262
|
+
matched?: undefined;
|
|
263
|
+
waitMs?: undefined;
|
|
264
|
+
failed?: undefined;
|
|
265
|
+
}>;
|
|
266
|
+
/** 录制管理:start / stop / save / list / delete。 */
|
|
267
|
+
export declare function recordTool(args: Record<string, any>): Promise<{
|
|
268
|
+
recording: boolean;
|
|
269
|
+
hint: string;
|
|
270
|
+
steps?: undefined;
|
|
271
|
+
saved?: undefined;
|
|
272
|
+
file?: undefined;
|
|
273
|
+
recordings?: undefined;
|
|
274
|
+
deleted?: undefined;
|
|
275
|
+
name?: undefined;
|
|
276
|
+
} | {
|
|
277
|
+
recording: boolean;
|
|
278
|
+
steps: number;
|
|
279
|
+
hint?: undefined;
|
|
280
|
+
saved?: undefined;
|
|
281
|
+
file?: undefined;
|
|
282
|
+
recordings?: undefined;
|
|
283
|
+
deleted?: undefined;
|
|
284
|
+
name?: undefined;
|
|
285
|
+
} | {
|
|
286
|
+
saved: string;
|
|
287
|
+
steps: number;
|
|
288
|
+
file: string;
|
|
289
|
+
hint: string;
|
|
290
|
+
recording?: undefined;
|
|
291
|
+
recordings?: undefined;
|
|
292
|
+
deleted?: undefined;
|
|
293
|
+
name?: undefined;
|
|
294
|
+
} | {
|
|
295
|
+
recordings: {
|
|
296
|
+
name: string;
|
|
297
|
+
steps: number;
|
|
298
|
+
savedAt: number;
|
|
299
|
+
preview: string;
|
|
300
|
+
}[];
|
|
301
|
+
recording?: undefined;
|
|
302
|
+
hint?: undefined;
|
|
303
|
+
steps?: undefined;
|
|
304
|
+
saved?: undefined;
|
|
305
|
+
file?: undefined;
|
|
306
|
+
deleted?: undefined;
|
|
307
|
+
name?: undefined;
|
|
308
|
+
} | {
|
|
309
|
+
deleted: boolean;
|
|
310
|
+
name: string;
|
|
311
|
+
recording?: undefined;
|
|
312
|
+
hint?: undefined;
|
|
313
|
+
steps?: undefined;
|
|
314
|
+
saved?: undefined;
|
|
315
|
+
file?: undefined;
|
|
316
|
+
recordings?: undefined;
|
|
317
|
+
}>;
|
|
318
|
+
/** 回放执行器(步骤 → 工具调用),由 register.ts 注入实现 map。 */
|
|
319
|
+
export declare function runReplay(steps: {
|
|
320
|
+
tool: string;
|
|
321
|
+
args: any;
|
|
322
|
+
}[], impls: Record<string, (args: any) => Promise<unknown>>, failFast: boolean): Promise<{
|
|
323
|
+
total: number;
|
|
324
|
+
passed: number;
|
|
325
|
+
failed: number;
|
|
326
|
+
stoppedAt: number | null;
|
|
327
|
+
results: any[];
|
|
328
|
+
}>;
|
|
329
|
+
/** 回放入口:name(已保存录制)或 steps(数组)二选一。 */
|
|
330
|
+
export declare function replayTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>): Promise<{
|
|
331
|
+
summary: string;
|
|
332
|
+
total: number;
|
|
333
|
+
passed: number;
|
|
334
|
+
failed: number;
|
|
335
|
+
stoppedAt: number | null;
|
|
336
|
+
results: any[];
|
|
337
|
+
source: string;
|
|
338
|
+
}>;
|
|
339
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Browser, BrowserContext, Page } from "playwright-core";
|
|
2
|
+
export interface BrowserConfig {
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
channel?: string;
|
|
5
|
+
executablePath?: string;
|
|
6
|
+
headless?: boolean;
|
|
7
|
+
userDataDir?: string;
|
|
8
|
+
profiles?: Record<string, Partial<BrowserConfig>>;
|
|
9
|
+
screenshotDir?: string;
|
|
10
|
+
downloadDir?: string;
|
|
11
|
+
/** 截图保留天数(0 = 不按时间清理)。 */
|
|
12
|
+
screenshotMaxAgeDays?: number;
|
|
13
|
+
/** 截图保留数量上限(0 = 不按数量清理)。 */
|
|
14
|
+
screenshotMaxCount?: number;
|
|
15
|
+
/** 面板嵌入 + 实时画面 API 基路径。 */
|
|
16
|
+
basePath?: string;
|
|
17
|
+
/** 网络记录是否保存请求/响应体(默认 true,截断存储)。 */
|
|
18
|
+
recordBodies?: boolean;
|
|
19
|
+
maxTextChars?: number;
|
|
20
|
+
maxLinks?: number;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/** 一个命名 profile 的会话状态。 */
|
|
24
|
+
export interface ProfileState {
|
|
25
|
+
browser: Browser | null;
|
|
26
|
+
context: BrowserContext | null;
|
|
27
|
+
persistent: boolean;
|
|
28
|
+
pages: Map<number, Page>;
|
|
29
|
+
activeId: number | null;
|
|
30
|
+
counter: number;
|
|
31
|
+
channel?: string;
|
|
32
|
+
}
|
|
33
|
+
/** 一次页面下载的记录。 */
|
|
34
|
+
export interface DownloadEntry {
|
|
35
|
+
download: {
|
|
36
|
+
saveAs(path: string): Promise<void>;
|
|
37
|
+
suggestedFilename(): string;
|
|
38
|
+
url(): string;
|
|
39
|
+
};
|
|
40
|
+
suggestedFilename: string;
|
|
41
|
+
at: number;
|
|
42
|
+
}
|
|
43
|
+
/** 一次页面访问(导航)的记录,供实时画面模态框展示访问历史。 */
|
|
44
|
+
export interface NavEntry {
|
|
45
|
+
url: string;
|
|
46
|
+
title: string;
|
|
47
|
+
ts: number;
|
|
48
|
+
}
|
|
49
|
+
/** 表单字段(selector 或 label 二选一)。 */
|
|
50
|
+
export interface FormField {
|
|
51
|
+
selector?: string;
|
|
52
|
+
label?: string;
|
|
53
|
+
value?: string;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-browser-view client half:
|
|
3
|
+
* 1. "settings.section" -> A "🌐 浏览器" page in the official dsh settings
|
|
4
|
+
* dialog managing saved browser recordings with polished header & icon.
|
|
5
|
+
* 2. "shell.overlay" -> Universal floating widget (FAB + live screenshot
|
|
6
|
+
* thumbnail panel + full-size inspection modal) rendered natively in both
|
|
7
|
+
* Electron desktop and web client.
|
|
8
|
+
*/
|
|
9
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
10
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
11
|
+
interface SlotMap {
|
|
12
|
+
'shell.overlay': {
|
|
13
|
+
kind: 'list';
|
|
14
|
+
scope: 'root';
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Required services (cordis fiber inject). */
|
|
19
|
+
export declare const inject: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Register the browser extension components:
|
|
22
|
+
* 1. settings.section -> "🌐 浏览器" page in settings
|
|
23
|
+
* 2. shell.overlay -> Universal floating live screenshot widget (Desktop & Web)
|
|
24
|
+
*/
|
|
25
|
+
export declare function apply(ctx: ClientContext): void;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReefContext, WebRoute } from "./lib/types.js";
|
|
2
|
+
export declare function applyEmbed(ctx: ReefContext, webServer: {
|
|
3
|
+
register(route: WebRoute): () => void;
|
|
4
|
+
tapIndex(transform: (html: string) => string): () => void;
|
|
5
|
+
port?: number;
|
|
6
|
+
}, base: string): () => void;
|
|
7
|
+
//# sourceMappingURL=embed.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface FieldSchema {
|
|
2
|
+
type: "string" | "number" | "boolean" | "array" | "object" | "string[]" | "any";
|
|
3
|
+
optional?: boolean;
|
|
4
|
+
default?: unknown;
|
|
5
|
+
enum?: string[];
|
|
6
|
+
items?: FieldSchema;
|
|
7
|
+
max?: number;
|
|
8
|
+
min?: number;
|
|
9
|
+
}
|
|
10
|
+
export type ConfigSchema = Record<string, FieldSchema>;
|
|
11
|
+
declare const TYPES: string[];
|
|
12
|
+
/** 校验配置;返回错误列表(空 = 通过)。 */
|
|
13
|
+
export declare function validateConfig(schema: ConfigSchema, config: Record<string, any>): string[];
|
|
14
|
+
/** 合并默认值 + 校验;抛错时带模块名前缀。 */
|
|
15
|
+
export declare function resolveConfig(moduleName: string, schema: ConfigSchema, defaults: Record<string, any>, raw: Record<string, any> | undefined): Record<string, any>;
|
|
16
|
+
export { TYPES };
|
|
17
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
/** Parse the request URL pathname (query strings are ignored). */
|
|
3
|
+
export declare function urlPath(req: IncomingMessage): string;
|
|
4
|
+
/** Read the request body as a UTF-8 string (bounded). */
|
|
5
|
+
export declare function readRawBody(req: IncomingMessage, limitBytes?: number): Promise<string>;
|
|
6
|
+
/** Read and parse a JSON request body; `undefined` when the body is empty. */
|
|
7
|
+
export declare function readJsonBody(req: IncomingMessage, limitBytes?: number): Promise<unknown>;
|
|
8
|
+
/** Send a JSON response. */
|
|
9
|
+
export declare function sendJson(res: ServerResponse, status: number, value: unknown, extraHeaders?: Record<string, string>): void;
|
|
10
|
+
/** Send a plain text response. */
|
|
11
|
+
export declare function sendText(res: ServerResponse, status: number, text: string, headers?: Record<string, string>): void;
|
|
12
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PlainToolDefinition, ToolRunContext } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the workspace working directory for one tool execution.
|
|
4
|
+
* Prefers the calling agent's session cwd; falls back to the host process cwd.
|
|
5
|
+
*/
|
|
6
|
+
export declare function workspaceCwd(exec: ToolRunContext | undefined): string;
|
|
7
|
+
/** definePlainTool 的输入选项。 */
|
|
8
|
+
export interface PlainToolOptions {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
parameters: Record<string, unknown>;
|
|
12
|
+
outputSchema?: Record<string, unknown>;
|
|
13
|
+
execute: (args: any, exec: ToolRunContext) => Promise<unknown> | unknown;
|
|
14
|
+
render?: (args: any, value: any) => string;
|
|
15
|
+
presentCall?: (args: any) => unknown;
|
|
16
|
+
concurrencySafe?: boolean;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a plain ToolDefinition for `ctx.tools.register` without depending on
|
|
21
|
+
* any @deepseek-ai package (max version-alignment tolerance).
|
|
22
|
+
*/
|
|
23
|
+
export declare function definePlainTool(options: PlainToolOptions): PlainToolDefinition;
|
|
24
|
+
/** Generic card view used by all dsh-browser tools. */
|
|
25
|
+
export declare function genericCard(kind: string, title: string, rawInput: string): unknown;
|
|
26
|
+
//# sourceMappingURL=tools.d.ts.map
|