dsh-browser-view 0.1.2 → 0.3.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,22 +1,132 @@
1
- import type { Page } from "playwright-core";
1
+ import type { Locator, Page } from "playwright-core";
2
2
  import type { ToolRunContext } from "../lib/types.js";
3
- import type { BrowserConfig } from "./types.js";
3
+ import type { BrowserConfig, RefEntry, ReplayStep, SelectorHint } from "./types.js";
4
+ import { type RunRecord } from "./reports.js";
5
+ /** 读取 PNG 文件头(IHDR)中的宽高,不解码像素(导出供测试)。 */
6
+ export declare function pngSize(buf: Buffer): {
7
+ width: number;
8
+ height: number;
9
+ };
10
+ /** 按缩放比例换算 mask 矩形(导出供测试;与页内比对共用同一套坐标语义)。 */
11
+ export declare function scaleRects(rects: {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ }[], scale: number): {
17
+ x: number;
18
+ y: number;
19
+ width: number;
20
+ height: number;
21
+ }[];
4
22
  export declare function openTool(config: BrowserConfig, args: Record<string, any>): Promise<{
5
23
  url: string;
6
24
  title: string;
7
25
  status: string;
8
26
  }>;
9
- export declare function snapshotTool(config: BrowserConfig, args: Record<string, any>): Promise<{
10
- text: string;
27
+ /**
28
+ * 快照文本压缩(导出供测试):
29
+ * - 去掉首尾空白行;
30
+ * - 连续空白行折叠为 1 行;
31
+ * - 连续重复的非空行(表格空单元格/占位行产生的噪音)折叠为「首行 + …(重复 N 行)」。
32
+ * 只折叠完全相同的相邻行,不重排、不删改非重复内容。
33
+ */
34
+ export declare function compressText(text: string): string;
35
+ /** 最长公共子串长度(小写比较;零依赖,导出供测试)。 */
36
+ export declare function lcsScore(a: string, b: string): number;
37
+ /** 零命中时按相似度挑 top5 候选(导出供测试)。 */
38
+ export declare function topSuggestions(query: string, candidates: {
39
+ role: string;
40
+ name: string;
41
+ }[], count?: number): {
42
+ role: string;
43
+ name: string;
44
+ score: number;
45
+ }[];
46
+ /**
47
+ * 为命中元素增量分配 ref:沿用既有注册表的编号继续(不与上次快照冲突),
48
+ * 合并写回;返回带 ref 的命中列表(上限 maxRefs,超出标 truncated)。
49
+ * 导出供测试(纯逻辑,不依赖浏览器)。
50
+ */
51
+ export declare function assignRefs(existing: Map<string, RefEntry>, matches: {
52
+ role: string;
53
+ name: string;
54
+ selector: string;
55
+ ancestors: string[];
56
+ }[], maxRefs: number): {
57
+ withRefs: {
58
+ ref: string;
59
+ role: string;
60
+ name: string;
61
+ selector: string;
62
+ ancestors: string[];
63
+ }[];
64
+ merged: Map<string, RefEntry>;
11
65
  truncated: boolean;
12
- links: {
13
- text: string;
14
- href: string;
66
+ };
67
+ /**
68
+ * 语义元素定位:按名称(或 id/data-testid)在可交互元素中查找,只返回命中的
69
+ * ref + 区域上下文,不输出全量 aria 树 —— 大页面定位单个目标时 token 开销
70
+ * 远小于 browser_snapshot { mode: "aria" }。返回的 ref 可直接用于
71
+ * click/type/select/press。零命中不抛错,附最相近候选供二次定位。
72
+ */
73
+ export declare function findTool(config: BrowserConfig, args: Record<string, any>): Promise<{
74
+ scanned: number;
75
+ url: string;
76
+ title: string;
77
+ truncated?: true | undefined;
78
+ suggestions?: {
79
+ role: string;
80
+ name: string;
81
+ score: number;
82
+ }[] | undefined;
83
+ found: number;
84
+ matches: {
85
+ ref: string;
86
+ role: string;
87
+ name: string;
88
+ ancestors: string[];
15
89
  }[];
16
- inputs: number;
90
+ }>;
91
+ /**
92
+ * 行级 diff:掐掉公共前缀/后缀,返回变化区。导出供测试。
93
+ * 全等返回 { unchanged: true };否则 changedFrom 为新文本中变化区首行(1 起)。
94
+ */
95
+ export declare function diffLines(oldText: string, newText: string): {
96
+ unchanged: boolean;
97
+ changedFrom?: number;
98
+ lines?: string[];
99
+ removed?: number;
100
+ };
101
+ export declare function snapshotTool(config: BrowserConfig, args: Record<string, any>): Promise<{
17
102
  url: string;
18
103
  title: string;
104
+ scope?: string | undefined;
105
+ unchanged: boolean;
106
+ contentVersion: number;
107
+ } | {
108
+ url: string;
109
+ title: string;
110
+ truncated: boolean;
111
+ scope?: string | undefined;
112
+ diff: boolean;
113
+ contentVersion: number;
114
+ changedFrom: number | undefined;
115
+ removed: number | undefined;
116
+ } | {
117
+ url: string;
118
+ title: string;
119
+ truncated: boolean;
120
+ scope?: string | undefined;
121
+ stale?: boolean | undefined;
122
+ contentVersion: number;
19
123
  }>;
124
+ /**
125
+ * 解析点击/输入目标为 Locator:selector 直译;ref 走注册表——
126
+ * 先试快照时的 CSS 路径并校验 role/name 仍一致(防 ref 漂移误点),
127
+ * 不一致则降级 getByRole(role, {name}),均失败报「ref 已失效」。
128
+ */
129
+ export declare function targetLocator(page: Page, args: Record<string, any>): Promise<Locator>;
20
130
  export declare function clickTool(config: BrowserConfig, args: Record<string, any>): Promise<{
21
131
  url: string;
22
132
  title: string;
@@ -34,6 +144,17 @@ export declare function pressTool(config: BrowserConfig, args: Record<string, an
34
144
  title: string;
35
145
  pressed: string;
36
146
  }>;
147
+ /**
148
+ * 下拉选择原语:原生 <select> 走 selectOption;组件库下拉(antd/element/listbox)
149
+ * 走「点击触发框 → 等待可见选项 → 按文本点击」。找不到选项时抛出错误并附当前可见
150
+ * 选项清单,agent 可直接据此修正,无需再手写 eval 探查。
151
+ */
152
+ export declare function selectTool(config: BrowserConfig, args: Record<string, any>): Promise<{
153
+ url: string;
154
+ title: string;
155
+ selected: string;
156
+ selector: string;
157
+ }>;
37
158
  export declare function evalTool(config: BrowserConfig, args: Record<string, any>): Promise<{
38
159
  result: unknown;
39
160
  }>;
@@ -42,6 +163,13 @@ export declare function screenshotTool(config: BrowserConfig, args: Record<strin
42
163
  bytes: number;
43
164
  width: number;
44
165
  height: number;
166
+ baseline: string;
167
+ } | {
168
+ path: string;
169
+ bytes: number;
170
+ width: number;
171
+ height: number;
172
+ baseline?: undefined;
45
173
  }>;
46
174
  export declare function waitTool(config: BrowserConfig, args: Record<string, any>): Promise<{
47
175
  url: string;
@@ -56,6 +184,95 @@ export declare function reloadTool(config: BrowserConfig): Promise<{
56
184
  url: string;
57
185
  title: string;
58
186
  }>;
187
+ /** 一项诊断结果(ok=false 时附 advice 修复建议)。导出供测试。 */
188
+ export interface DoctorCheck {
189
+ name: string;
190
+ ok: boolean;
191
+ detail: string;
192
+ advice?: string;
193
+ }
194
+ export declare function setDoctorProbe(fn: ((basePath: string) => Promise<{
195
+ ok: boolean;
196
+ detail: string;
197
+ advice?: string;
198
+ }>) | null): void;
199
+ /** 目录可写性检查(mkdir + 写探针文件 + 删除)。导出供测试。 */
200
+ export declare function checkWritableDir(dir: string): {
201
+ ok: boolean;
202
+ detail: string;
203
+ };
204
+ /** 可执行文件存在性检查(executablePath 显式配置用)。导出供测试。 */
205
+ export declare function checkExecutable(path: string): DoctorCheck;
206
+ /**
207
+ * 命名隔离上下文:同一浏览器进程内独立 cookies/storage 的"标签组"。
208
+ * 页注册进 profile 标签表(所有既有工具直接可用),context 只做归属记录:
209
+ * list / new(name?, url?) / switch(激活该组的一页,没有则新开) / close(整组关闭)。
210
+ * 持久模式(userDataDir)浏览器只有单一 context,不支持本工具(用 profiles 替代)。
211
+ */
212
+ export declare function contextTool(config: BrowserConfig, args: Record<string, any>): Promise<{
213
+ contexts: {
214
+ name: string;
215
+ pages: number;
216
+ active: boolean;
217
+ createdAt: number;
218
+ }[];
219
+ profile: string;
220
+ closed?: undefined;
221
+ remainingTabs?: undefined;
222
+ } | {
223
+ url: string;
224
+ title: string;
225
+ navigated?: string | undefined;
226
+ created: string;
227
+ contexts?: undefined;
228
+ profile?: undefined;
229
+ closed?: undefined;
230
+ remainingTabs?: undefined;
231
+ } | {
232
+ url: string;
233
+ title: string;
234
+ switched: string;
235
+ contexts?: undefined;
236
+ profile?: undefined;
237
+ closed?: undefined;
238
+ remainingTabs?: undefined;
239
+ } | {
240
+ url: string;
241
+ title: string;
242
+ switched: string;
243
+ pages: number;
244
+ contexts?: undefined;
245
+ profile?: undefined;
246
+ closed?: undefined;
247
+ remainingTabs?: undefined;
248
+ } | {
249
+ closed: string;
250
+ remainingTabs: number;
251
+ contexts?: undefined;
252
+ profile?: undefined;
253
+ }>;
254
+ /**
255
+ * 页内拾取器(evaluate 注入):一次性 click 捕获 —— 点击任意元素时阻止默认行为,
256
+ * 计算稳定 CSS 路径 + 元素信息存 window.__dshPickResult(面板轮询读取后自清)。
257
+ * 与 aria walker 的 cssPath 同一套语义(#id → [data-testid] → nth-of-type 链)。
258
+ */
259
+ export declare function pickElementInjector(): void;
260
+ /** 读取并清空拾取结果(ui.ts /pick GET 调用;无结果返回 null)。 */
261
+ export declare function takePickResult(page: Page): Promise<Record<string, unknown> | null>;
262
+ /**
263
+ * 操作预告高亮:agent 即将 click/type/select/press 的元素在页面上琥珀色描边
264
+ * ~1.5 秒。异步不阻塞(fire-and-forget,任何失败静默),不影响操作时序。
265
+ */
266
+ export declare function previewHighlight(page: Page | null, selector: string, label: string): void;
267
+ /** 一次性健康诊断:不启动浏览器,只做静态/本地检查。 */
268
+ export declare function doctorTool(config: BrowserConfig, _args: Record<string, any>, exec?: ToolRunContext): Promise<{
269
+ checks: DoctorCheck[];
270
+ summary: {
271
+ ok: boolean;
272
+ passed: number;
273
+ failed: number;
274
+ };
275
+ }>;
59
276
  export declare function statusTool(): Promise<{
60
277
  open: boolean;
61
278
  profile: string;
@@ -189,6 +406,7 @@ export declare function profileTool(config: BrowserConfig, args: Record<string,
189
406
  export declare function elementsTool(config: BrowserConfig, args: Record<string, any>): Promise<{
190
407
  count: number;
191
408
  elements: Record<string, unknown>[];
409
+ dropdownOptions: string[];
192
410
  }>;
193
411
  export declare function closeTool(): Promise<{
194
412
  closed: boolean;
@@ -231,24 +449,84 @@ export declare function waitForLoginTool(config: BrowserConfig, args: Record<str
231
449
  title: string;
232
450
  loggedIn: boolean;
233
451
  }>;
234
- /** 断言:条件在 timeoutMs 内成立则通过,否则失败并自动截图存证据。 */
452
+ /**
453
+ * 人工接管等待(通用版 wait_for_login):agent 把控制权交还给用户(验证码 /
454
+ * 二次确认 / 人工复核等)。instruction 会显示在实时画面面板;完成条件三选一:
455
+ * successSelector(元素出现)/ successUrl(URL 正则)/ 两者都不给则以
456
+ * URL 变化或页面内容签名变化视为完成。轮询间隔 2 秒,超时返回 completed:false
457
+ * (不抛错)。导出 runPauseOnPage 供测试注入 fake page。
458
+ */
459
+ export declare function runPauseOnPage(page: Page, args: Record<string, any>): Promise<{
460
+ completed: boolean;
461
+ waitedMs: number;
462
+ detail: string;
463
+ }>;
464
+ /** 人工接管等待工具入口(缺 instruction 在启动浏览器前即校验,失败更快)。 */
465
+ export declare function pauseForHumanTool(config: BrowserConfig, args: Record<string, any>): Promise<{
466
+ url: string;
467
+ title: string;
468
+ completed: boolean;
469
+ status: "completed" | "timedOut";
470
+ instruction: string;
471
+ detail: string;
472
+ waitedMs: number;
473
+ }>;
474
+ /**
475
+ * 敏感操作审批:agent 在执行提交/删除/支付类动作前调用,把审批请求推到实时
476
+ * 画面面板,挂起等待用户点「允许/拒绝」。超时视为拒绝(fail-closed)。
477
+ * 用户允许时返回 { decision: "allowed", ... };拒绝/超时**抛错**(消息含原因),
478
+ * 使 live 调用与 replay/batch 步骤统一按失败处理,agent 不应继续敏感动作。
479
+ * 决策通过 session.resolveConfirm(面板 POST)写入。
480
+ */
481
+ export declare function confirmTool(config: BrowserConfig, args: Record<string, any>): Promise<{
482
+ decision: "allowed";
483
+ id: string;
484
+ reason: string;
485
+ waitedMs: number;
486
+ detail: string;
487
+ }>;
488
+ /** 断言:条件在 timeoutMs 内成立则通过,否则失败并自动截图存证据。visual 断言走像素比对。 */
235
489
  export declare function assertTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
236
490
  url: string;
237
491
  title: string;
238
492
  passed: boolean;
493
+ visual: {
494
+ baseline: string;
495
+ diffRatio: number;
496
+ diffPixels: number;
497
+ };
498
+ } | {
499
+ url: string;
500
+ title: string;
501
+ passed: boolean;
239
502
  }>;
240
503
  /** 网络记录查询:list / failed / wait / clear。 */
241
504
  export declare function networkTool(args: Record<string, any>): Promise<{
242
505
  cleared: boolean;
243
- entries: number;
506
+ entries: never[];
244
507
  matched?: undefined;
245
508
  waitMs?: undefined;
509
+ stats?: undefined;
246
510
  failed?: undefined;
247
511
  } | {
248
512
  matched: import("./session.js").NetworkEntry;
249
513
  waitMs: number;
250
514
  cleared?: undefined;
251
515
  entries?: undefined;
516
+ stats?: undefined;
517
+ failed?: undefined;
518
+ } | {
519
+ stats: {
520
+ host: string;
521
+ total: number;
522
+ failed: number;
523
+ avgMs: number | null;
524
+ byStatus: Record<string, number>;
525
+ }[];
526
+ cleared?: undefined;
527
+ entries?: undefined;
528
+ matched?: undefined;
529
+ waitMs?: undefined;
252
530
  failed?: undefined;
253
531
  } | {
254
532
  failed: import("./session.js").NetworkEntry[];
@@ -256,20 +534,32 @@ export declare function networkTool(args: Record<string, any>): Promise<{
256
534
  entries?: undefined;
257
535
  matched?: undefined;
258
536
  waitMs?: undefined;
537
+ stats?: undefined;
259
538
  } | {
260
539
  entries: import("./session.js").NetworkEntry[];
261
540
  cleared?: undefined;
262
541
  matched?: undefined;
263
542
  waitMs?: undefined;
543
+ stats?: undefined;
264
544
  failed?: undefined;
265
545
  }>;
546
+ /** 使用 args.selector 定位的工具集合(自愈与录制指纹的作用范围)。 */
547
+ export declare const SELECTOR_STEP_TOOLS: Set<string>;
548
+ /**
549
+ * 采集选择器指向元素的指纹(页内 evaluate;找不到元素返回 null)。
550
+ * 指纹是回放自愈的降级候选来源:testid / role+name / text / id / tag+text。
551
+ */
552
+ export declare function captureSelectorHint(page: Page, selector: string): Promise<SelectorHint | null>;
553
+ /** 由指纹生成自愈降级候选(按优先级排序;导出供测试)。 */
554
+ export declare function healCandidates(hint: SelectorHint): {
555
+ via: string;
556
+ selector: string;
557
+ }[];
266
558
  /** 录制管理:start / stop / save / list / delete。 */
267
559
  export declare function recordTool(args: Record<string, any>): Promise<{
268
560
  recording: boolean;
269
561
  hint: string;
270
562
  steps?: undefined;
271
- saved?: undefined;
272
- file?: undefined;
273
563
  recordings?: undefined;
274
564
  deleted?: undefined;
275
565
  name?: undefined;
@@ -277,16 +567,18 @@ export declare function recordTool(args: Record<string, any>): Promise<{
277
567
  recording: boolean;
278
568
  steps: number;
279
569
  hint?: undefined;
280
- saved?: undefined;
281
- file?: undefined;
282
570
  recordings?: undefined;
283
571
  deleted?: undefined;
284
572
  name?: undefined;
285
573
  } | {
574
+ hint: string;
575
+ warnings?: string[] | undefined;
576
+ varsApplied?: number | undefined;
577
+ stripped?: number | undefined;
286
578
  saved: string;
287
579
  steps: number;
580
+ source: string;
288
581
  file: string;
289
- hint: string;
290
582
  recording?: undefined;
291
583
  recordings?: undefined;
292
584
  deleted?: undefined;
@@ -301,8 +593,6 @@ export declare function recordTool(args: Record<string, any>): Promise<{
301
593
  recording?: undefined;
302
594
  hint?: undefined;
303
595
  steps?: undefined;
304
- saved?: undefined;
305
- file?: undefined;
306
596
  deleted?: undefined;
307
597
  name?: undefined;
308
598
  } | {
@@ -311,29 +601,129 @@ export declare function recordTool(args: Record<string, any>): Promise<{
311
601
  recording?: undefined;
312
602
  hint?: undefined;
313
603
  steps?: undefined;
314
- saved?: undefined;
315
- file?: undefined;
316
604
  recordings?: undefined;
317
605
  }>;
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<{
606
+ /** 回放选项(自愈开关与单次尝试超时,来自 config)。 */
607
+ export interface ReplayOptions {
608
+ healing?: boolean;
609
+ healTimeoutMs?: number;
610
+ }
611
+ /** 回放执行器(步骤 → 工具调用),由 register.ts 注入实现 map。支持选择器自愈。 */
612
+ export declare function runReplay(steps: ReplayStep[], impls: Record<string, (args: any) => Promise<unknown>>, failFast: boolean, opts?: ReplayOptions): Promise<{
323
613
  total: number;
324
614
  passed: number;
325
615
  failed: number;
326
- stoppedAt: number | null;
616
+ healedCount: number;
617
+ stoppedAt?: number;
327
618
  results: any[];
328
619
  }>;
329
- /** 回放入口:name(已保存录制)或 steps(数组)二选一。 */
330
- export declare function replayTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>): Promise<{
620
+ export interface ExtractField {
621
+ name: string;
622
+ selector: string;
623
+ attr?: string;
624
+ multiple?: boolean;
625
+ fields?: ExtractField[];
626
+ }
627
+ /**
628
+ * 把单页抽取结果规整为行数组:恰好一个顶层 multiple 字段时,其数组即行
629
+ * (行内嵌套对象为行,标量包装成 { [name]: value });否则整页算一行。
630
+ */
631
+ export declare function rowsOfExtract(result: Record<string, any>, fields: ExtractField[]): Record<string, any>[];
632
+ /** 工作区内落盘路径解析(拒绝穿越到工作区之外)。 */
633
+ export declare function workspaceFilePath(cwd: string, file: string): string;
634
+ /**
635
+ * 规则化抽取:fields 定义抽取结构,next 选择器驱动翻页(maxPages 上限),
636
+ * 行数超 maxRows 截断;format/file 控制序列化与落盘(json/csv/jsonl/markdown)。
637
+ */
638
+ export declare function extractTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
639
+ url: string;
640
+ title: string;
641
+ file?: string | undefined;
642
+ bytes?: number | undefined;
643
+ truncated: boolean;
644
+ rows: Record<string, any>[];
645
+ count: number;
646
+ pages: number;
647
+ format: string;
648
+ }>;
649
+ /**
650
+ * 回归报告:list 列出最近运行,show 看单条详情,
651
+ * export 聚合生成 Markdown/HTML 报告落盘工作区。
652
+ */
653
+ export declare function reportTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
654
+ runs: {
655
+ row?: number | undefined;
656
+ runId: string;
657
+ ts: number;
658
+ kind: "replay" | "batch";
659
+ source: string;
660
+ total: number;
661
+ passed: number;
662
+ failed: number;
663
+ healedCount: number;
664
+ durationMs: number;
665
+ }[];
666
+ run?: undefined;
667
+ file?: undefined;
668
+ bytes?: undefined;
669
+ format?: undefined;
670
+ } | {
671
+ run: RunRecord;
672
+ runs?: undefined;
673
+ file?: undefined;
674
+ bytes?: undefined;
675
+ format?: undefined;
676
+ } | {
677
+ file: string;
678
+ bytes: number;
679
+ runs: number;
680
+ format: string;
681
+ run?: undefined;
682
+ }>;
683
+ /**
684
+ * 动作批处理:一次调用顺序执行多个浏览器步骤(内核复用 runReplay),
685
+ * 减少「点击→等待→输入」类固定小序列的工具往返。步骤内禁止嵌套
686
+ * batch/replay/record;批整体在操作轨迹里记为一条 browser_batch。
687
+ */
688
+ export declare function batchTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>, config?: BrowserConfig): Promise<{
689
+ summary: string;
690
+ total: number;
691
+ passed: number;
692
+ failed: number;
693
+ healedCount: number;
694
+ stoppedAt?: number;
695
+ results: any[];
696
+ }>;
697
+ /** 收集步骤中所有 {{var}} 占位符名(导出供测试)。 */
698
+ export declare function findPlaceholders(steps: ReplayStep[]): string[];
699
+ /**
700
+ * 深拷贝步骤并替换字符串叶子里的 {{var}} 占位符(导出供测试)。
701
+ * vars 缺失的占位符保留原样(由调用方先 findPlaceholders 校验)。
702
+ */
703
+ export declare function substituteVars(steps: ReplayStep[], vars: Record<string, unknown>): ReplayStep[];
704
+ /**
705
+ * 回放入口:name(已保存录制)或 steps(数组)二选一。
706
+ * vars 注入 {{占位符}};data/dataFile 数据集模式逐行运行并聚合。
707
+ */
708
+ export declare function replayTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>, config?: BrowserConfig, exec?: ToolRunContext): Promise<{
709
+ source: string;
710
+ rows: number;
711
+ passedRows: number;
712
+ failedRows: number;
713
+ runs: any[];
714
+ summary: string;
715
+ } | {
331
716
  summary: string;
332
717
  total: number;
333
718
  passed: number;
334
719
  failed: number;
335
- stoppedAt: number | null;
720
+ healedCount: number;
721
+ stoppedAt?: number;
336
722
  results: any[];
337
723
  source: string;
724
+ rows?: undefined;
725
+ passedRows?: undefined;
726
+ failedRows?: undefined;
727
+ runs?: undefined;
338
728
  }>;
339
729
  //# sourceMappingURL=tools.d.ts.map
@@ -8,6 +8,8 @@ export interface BrowserConfig {
8
8
  profiles?: Record<string, Partial<BrowserConfig>>;
9
9
  screenshotDir?: string;
10
10
  downloadDir?: string;
11
+ /** 截图/下载/上传的落盘基准目录(默认探测会话 cwd;显式指定后优先)。 */
12
+ workspaceDir?: string;
11
13
  /** 截图保留天数(0 = 不按时间清理)。 */
12
14
  screenshotMaxAgeDays?: number;
13
15
  /** 截图保留数量上限(0 = 不按数量清理)。 */
@@ -19,6 +21,28 @@ export interface BrowserConfig {
19
21
  maxTextChars?: number;
20
22
  maxLinks?: number;
21
23
  timeoutMs?: number;
24
+ /** 视觉回归基线截图目录(默认 .dsh-browser/baselines,不受截图清理策略约束)。 */
25
+ baselineDir?: string;
26
+ /** 回放/批处理时的选择器自愈(默认 true;只作用于失败路径,live 工具不受影响)。 */
27
+ selectorHealing?: boolean;
28
+ /** 自愈时单次尝试的超时毫秒(默认 3000,避免等满全局超时)。 */
29
+ healTimeoutMs?: number;
30
+ /** ARIA 快照每次分配的最大 ref 数(默认 200)。 */
31
+ maxRefs?: number;
32
+ /** browser_extract 单次最多聚合的行数(默认 1000)。 */
33
+ maxRows?: number;
34
+ /**
35
+ * 敏感操作审批模式:off(默认,行为与 v0.2 一致,工具仍可手动调用)|
36
+ * manual(systemPrompt 指示 agent 在提交/删除/支付类动作前调用 browser_confirm)。
37
+ */
38
+ confirmMode?: "off" | "manual";
39
+ /** browser_confirm 等待人工决策的默认超时毫秒(默认 60000)。 */
40
+ confirmTimeoutMs?: number;
41
+ /**
42
+ * 工具集:all(默认,全部工具)| core(只注册高频核心集,低频的
43
+ * 录制/回放/报告/抽取/profile 等不注册,降 systemPrompt 常驻 token)。
44
+ */
45
+ toolset?: "core" | "all";
22
46
  }
23
47
  /** 一个命名 profile 的会话状态。 */
24
48
  export interface ProfileState {
@@ -52,4 +76,29 @@ export interface FormField {
52
76
  label?: string;
53
77
  value?: string;
54
78
  }
79
+ /** ARIA 快照分配的 ref 注册项(ref → 定位信息)。 */
80
+ export interface RefEntry {
81
+ role: string;
82
+ name: string;
83
+ /** 生成快照时计算的稳定 CSS 路径(优先 #id / [data-testid] / nth-of-type 链)。 */
84
+ selector: string;
85
+ }
86
+ /** 录制时采集的选择器指纹(回放自愈的降级候选来源)。 */
87
+ export interface SelectorHint {
88
+ testid?: string;
89
+ role?: string;
90
+ name?: string;
91
+ id?: string;
92
+ text?: string;
93
+ tag?: string;
94
+ }
95
+ /** 录制/回放的一步(formatVersion 2 起支持 meta.hint 选择器指纹)。 */
96
+ export interface ReplayStep {
97
+ tool: string;
98
+ args: any;
99
+ meta?: {
100
+ hint?: SelectorHint;
101
+ source?: "human";
102
+ };
103
+ }
55
104
  //# sourceMappingURL=types.d.ts.map
@@ -1,9 +1,20 @@
1
1
  import type { PlainToolDefinition, ToolRunContext } from "./types.js";
2
+ /** 注入日志函数(插件 apply 时调用一次)。 */
3
+ export declare function setToolsLogger(fn: ((message: string) => void) | null): void;
2
4
  /**
3
5
  * Resolve the workspace working directory for one tool execution.
4
6
  * Prefers the calling agent's session cwd; falls back to the host process cwd.
5
7
  */
6
8
  export declare function workspaceCwd(exec: ToolRunContext | undefined): string;
9
+ /**
10
+ * 截图/下载/上传等文件的落盘基准目录:
11
+ * 1. config.workspaceDir 显式指定(相对路径按 process.cwd() 解析)——最高优先;
12
+ * 2. 会话 cwd 探测链(workspaceCwd);
13
+ * 首次解析打一次日志,记录来源,便于诊断「文件落错位置」类问题。
14
+ */
15
+ export declare function workspaceBaseDir(config: {
16
+ workspaceDir?: string;
17
+ }, exec: ToolRunContext | undefined): string;
7
18
  /** definePlainTool 的输入选项。 */
8
19
  export interface PlainToolOptions {
9
20
  name: string;
@@ -29,6 +29,8 @@ export interface ToolRunContext {
29
29
  };
30
30
  };
31
31
  };
32
+ /** 部分宿主直接给执行上下文挂 cwd(次于 session.meta.cwd 的候选)。 */
33
+ cwd?: string;
32
34
  callId?: string;
33
35
  }
34
36
  /** 规范化工具输出契约。 */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-browser-view",
3
- "version": "0.1.2",
4
- "description": "DSH 插件:共享 Playwright 浏览器自动化(27 个 browser_* 工具)+ 原生界面实时画面面板 + 官方设置弹窗内的浏览器录制管理。仅依赖 playwright-core,不依赖任何 @deepseek-ai 运行时包。",
3
+ "version": "0.3.0",
4
+ "description": "DSH 插件:共享 Playwright 浏览器自动化(36 个 browser_* 工具,含语义元素查找、批处理、视觉回归、选择器自愈、参数化回放、结构化抽取、回归报告与隔离 context)+ 人机协作(人工接管等待、敏感操作审批、人机混合录制、面板双向化:点选元素/操作预告高亮/内嵌报告)+ 实时画面面板与录制管理。仅依赖 playwright-core,不依赖任何 @deepseek-ai 运行时包。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/types/index.d.ts",