dsh-browser-view 0.1.2 → 0.2.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.
@@ -0,0 +1,13 @@
1
+ export declare function toCsv(rows: Record<string, unknown>[]): string;
2
+ export declare function toJsonl(rows: Record<string, unknown>[]): string;
3
+ export declare function toMarkdownTable(rows: Record<string, unknown>[]): string;
4
+ /** 按格式序列化抽取结果(json 为 pretty JSON 字符串)。 */
5
+ export declare function serializeRows(rows: Record<string, unknown>[], format: string): string;
6
+ /** 由文件扩展名推断序列化格式(显式 format 优先)。 */
7
+ export declare function formatFromFile(file: string): string | null;
8
+ /**
9
+ * 解析 CSV 文本为行对象数组(首行为表头;支持引号包裹、双引号转义、
10
+ * 逗号/换行内嵌)。供 browser_replay 的 dataFile 使用。
11
+ */
12
+ export declare function parseCsv(text: string): Record<string, string>[];
13
+ //# sourceMappingURL=extract.d.ts.map
@@ -1,14 +1,12 @@
1
+ import type { ReplayStep } from "./types.js";
1
2
  /** 录制存储目录($DSH_HOME/.dsh-browser/recordings)。 */
2
3
  export declare function recordingsDir(): string;
3
4
  /** 名字安全化:只保留字母数字 . _ -,连续点压成下划线防路径穿越。 */
4
5
  export declare function safeName(name: string): string;
5
6
  /** 加载目录下所有 .json 录制进内存表;返回加载数量。坏文件静默跳过。 */
6
7
  export declare function loadRecordings(): number;
7
- /** 写一个录制到磁盘(原子替换);返回文件路径。 */
8
- export declare function saveRecordingFile(name: string, steps: {
9
- tool: string;
10
- args: any;
11
- }[]): string;
8
+ /** 写一个录制到磁盘(原子替换);返回文件路径。formatVersion 2 起步骤可带 meta(选择器指纹)与 {{var}} 占位符。 */
9
+ export declare function saveRecordingFile(name: string, steps: ReplayStep[]): string;
12
10
  /** 删除磁盘上的录制文件;返回是否存在并删除。 */
13
11
  export declare function deleteRecordingFile(name: string): boolean;
14
12
  /** 录制列表(面板 / browser_record list 共用)。 */
@@ -21,10 +19,7 @@ export declare function listRecordings(): Array<{
21
19
  /** 录制详情(面板展开查看步骤)。 */
22
20
  export declare function recordingDetail(name: string): {
23
21
  name: string;
24
- steps: {
25
- tool: string;
26
- args: any;
27
- }[];
22
+ steps: ReplayStep[];
28
23
  } | undefined;
29
24
  /** 删除录制(内存 + 磁盘同步);返回是否存在并删除。 */
30
25
  export declare function deleteRecording(name: string): boolean;
@@ -0,0 +1,42 @@
1
+ /** 一步的执行结果(与 runReplay results 条目同形,外加自愈标记)。 */
2
+ export interface RunStepResult {
3
+ index: number;
4
+ tool: string;
5
+ ok: boolean;
6
+ error?: string;
7
+ healed?: boolean;
8
+ via?: string;
9
+ resolved?: string;
10
+ }
11
+ /** 一次 replay/batch 的运行记录。 */
12
+ export interface RunRecord {
13
+ runId: string;
14
+ ts: number;
15
+ kind: "replay" | "batch";
16
+ source: string;
17
+ total: number;
18
+ passed: number;
19
+ failed: number;
20
+ healedCount: number;
21
+ durationMs: number;
22
+ /** data 数据集模式时的行号(单次运行为 undefined)。 */
23
+ row?: number;
24
+ results: RunStepResult[];
25
+ }
26
+ /** 报告存储目录($DSH_HOME/.dsh-browser/reports)。 */
27
+ export declare function reportsDir(): string;
28
+ /** 生成 runId:YYYYMMDD-HHmmss-随机4位。 */
29
+ export declare function makeRunId(ts: number): string;
30
+ /** 追加一条运行记录;超限时截断旧行(原子替换)。 */
31
+ export declare function appendRun(record: RunRecord): void;
32
+ /** 读取全部运行记录(按时间倒序);坏行静默跳过。 */
33
+ export declare function listRuns(limit?: number): RunRecord[];
34
+ /** 最近一次运行(无记录返回 null)。 */
35
+ export declare function latestRun(): RunRecord | null;
36
+ /** 按 runId 取单条记录。 */
37
+ export declare function getRun(runId: string): RunRecord | null;
38
+ /** 生成 Markdown 回归报告。 */
39
+ export declare function renderMarkdownReport(runs: RunRecord[], source?: string): string;
40
+ /** 生成自包含 HTML 回归报告(内联样式,无外部资源)。 */
41
+ export declare function renderHtmlReport(runs: RunRecord[], source?: string): string;
42
+ //# sourceMappingURL=reports.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import type { Page } from "playwright-core";
2
- import type { BrowserConfig, ProfileState, DownloadEntry, FormField, NavEntry } from "./types.js";
2
+ import type { BrowserConfig, ProfileState, DownloadEntry, FormField, NavEntry, RefEntry, ReplayStep, SelectorHint } from "./types.js";
3
3
  /** 当前活动 profile 名(默认 "default")。 */
4
4
  export declare let currentProfile: string;
5
5
  /** 多配置文件浏览器会话:name → 会话状态。 */
@@ -8,12 +8,15 @@ export declare const profileStates: Map<string, ProfileState>;
8
8
  export declare const savedForms: Map<string, FormField[]>;
9
9
  /** 最近一次 browser_form 填充的字段(供 browser_form_save 无参保存)。 */
10
10
  export declare let lastFormFields: FormField[];
11
+ /** 记录一次 aria 快照分配的 ref(整表替换)。 */
12
+ export declare function setPageRefs(page: Page, refs: Map<string, RefEntry>): void;
13
+ /** 查询某个 ref 的定位信息;未注册返回 undefined。 */
14
+ export declare function pageRef(page: Page, ref: string): RefEntry | undefined;
15
+ /** 清空页面的 ref 表(导航/新快照时调用)。 */
16
+ export declare function clearPageRefs(page: Page): void;
11
17
  /** 已保存的录制脚本:name → 步骤数组。 */
12
18
  export declare const savedRecordings: Map<string, {
13
- steps: {
14
- tool: string;
15
- args: any;
16
- }[];
19
+ steps: ReplayStep[];
17
20
  savedAt: number;
18
21
  }>;
19
22
  /** 一次工具调用的记录(操作轨迹 / 录制 / 回放共用)。 */
@@ -24,12 +27,18 @@ export interface TestCall {
24
27
  ms: number;
25
28
  ts: number;
26
29
  error?: string;
30
+ /** 录制时采集的选择器指纹(回放自愈用;register 包装层异步补齐)。 */
31
+ meta?: {
32
+ hint?: SelectorHint;
33
+ };
27
34
  }
28
35
  export declare function isRecording(): boolean;
29
36
  export declare function startRecording(): void;
30
37
  export declare function stopRecording(): TestCall[];
31
- /** 操作轨迹追加(同时写入录制 buffer,排除 record/replay 自身)。 */
32
- export declare function recordCall(call: TestCall): void;
38
+ /** 最近一次完整录制(start→stop)的 buffer;从未录制过返回 null。 */
39
+ export declare function lastRecordingOf(): TestCall[] | null;
40
+ /** 操作轨迹追加(同时写入录制 buffer,排除 record/replay 自身)。返回存入的调用对象(供调用方补 meta)。 */
41
+ export declare function recordCall(call: TestCall): TestCall;
33
42
  /** 操作轨迹(按时间倒序,最新在前)。 */
34
43
  export declare function testLogOf(): TestCall[];
35
44
  export declare function clearTestLog(): void;
@@ -1,12 +1,49 @@
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, 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
  }>;
27
+ /**
28
+ * 快照文本压缩(导出供测试):
29
+ * - 去掉首尾空白行;
30
+ * - 连续空白行折叠为 1 行;
31
+ * - 连续重复的非空行(表格空单元格/占位行产生的噪音)折叠为「首行 + …(重复 N 行)」。
32
+ * 只折叠完全相同的相邻行,不重排、不删改非重复内容。
33
+ */
34
+ export declare function compressText(text: string): string;
9
35
  export declare function snapshotTool(config: BrowserConfig, args: Record<string, any>): Promise<{
36
+ url: string;
37
+ title: string;
38
+ tree: string;
39
+ truncated: boolean;
40
+ refs: number;
41
+ text?: undefined;
42
+ links?: undefined;
43
+ inputs?: undefined;
44
+ } | {
45
+ url: string;
46
+ title: string;
10
47
  text: string;
11
48
  truncated: boolean;
12
49
  links: {
@@ -14,9 +51,15 @@ export declare function snapshotTool(config: BrowserConfig, args: Record<string,
14
51
  href: string;
15
52
  }[];
16
53
  inputs: number;
17
- url: string;
18
- title: string;
54
+ tree?: undefined;
55
+ refs?: undefined;
19
56
  }>;
57
+ /**
58
+ * 解析点击/输入目标为 Locator:selector 直译;ref 走注册表——
59
+ * 先试快照时的 CSS 路径并校验 role/name 仍一致(防 ref 漂移误点),
60
+ * 不一致则降级 getByRole(role, {name}),均失败报「ref 已失效」。
61
+ */
62
+ export declare function targetLocator(page: Page, args: Record<string, any>): Promise<Locator>;
20
63
  export declare function clickTool(config: BrowserConfig, args: Record<string, any>): Promise<{
21
64
  url: string;
22
65
  title: string;
@@ -34,6 +77,17 @@ export declare function pressTool(config: BrowserConfig, args: Record<string, an
34
77
  title: string;
35
78
  pressed: string;
36
79
  }>;
80
+ /**
81
+ * 下拉选择原语:原生 <select> 走 selectOption;组件库下拉(antd/element/listbox)
82
+ * 走「点击触发框 → 等待可见选项 → 按文本点击」。找不到选项时抛出错误并附当前可见
83
+ * 选项清单,agent 可直接据此修正,无需再手写 eval 探查。
84
+ */
85
+ export declare function selectTool(config: BrowserConfig, args: Record<string, any>): Promise<{
86
+ url: string;
87
+ title: string;
88
+ selected: string;
89
+ selector: string;
90
+ }>;
37
91
  export declare function evalTool(config: BrowserConfig, args: Record<string, any>): Promise<{
38
92
  result: unknown;
39
93
  }>;
@@ -42,6 +96,13 @@ export declare function screenshotTool(config: BrowserConfig, args: Record<strin
42
96
  bytes: number;
43
97
  width: number;
44
98
  height: number;
99
+ baseline: string;
100
+ } | {
101
+ path: string;
102
+ bytes: number;
103
+ width: number;
104
+ height: number;
105
+ baseline?: undefined;
45
106
  }>;
46
107
  export declare function waitTool(config: BrowserConfig, args: Record<string, any>): Promise<{
47
108
  url: string;
@@ -189,6 +250,7 @@ export declare function profileTool(config: BrowserConfig, args: Record<string,
189
250
  export declare function elementsTool(config: BrowserConfig, args: Record<string, any>): Promise<{
190
251
  count: number;
191
252
  elements: Record<string, unknown>[];
253
+ dropdownOptions: string[];
192
254
  }>;
193
255
  export declare function closeTool(): Promise<{
194
256
  closed: boolean;
@@ -231,24 +293,48 @@ export declare function waitForLoginTool(config: BrowserConfig, args: Record<str
231
293
  title: string;
232
294
  loggedIn: boolean;
233
295
  }>;
234
- /** 断言:条件在 timeoutMs 内成立则通过,否则失败并自动截图存证据。 */
296
+ /** 断言:条件在 timeoutMs 内成立则通过,否则失败并自动截图存证据。visual 断言走像素比对。 */
235
297
  export declare function assertTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
236
298
  url: string;
237
299
  title: string;
238
300
  passed: boolean;
301
+ visual: {
302
+ baseline: string;
303
+ diffRatio: number;
304
+ diffPixels: number;
305
+ };
306
+ } | {
307
+ url: string;
308
+ title: string;
309
+ passed: boolean;
239
310
  }>;
240
311
  /** 网络记录查询:list / failed / wait / clear。 */
241
312
  export declare function networkTool(args: Record<string, any>): Promise<{
242
313
  cleared: boolean;
243
- entries: number;
314
+ entries: never[];
244
315
  matched?: undefined;
245
316
  waitMs?: undefined;
317
+ stats?: undefined;
246
318
  failed?: undefined;
247
319
  } | {
248
320
  matched: import("./session.js").NetworkEntry;
249
321
  waitMs: number;
250
322
  cleared?: undefined;
251
323
  entries?: undefined;
324
+ stats?: undefined;
325
+ failed?: undefined;
326
+ } | {
327
+ stats: {
328
+ host: string;
329
+ total: number;
330
+ failed: number;
331
+ avgMs: number | null;
332
+ byStatus: Record<string, number>;
333
+ }[];
334
+ cleared?: undefined;
335
+ entries?: undefined;
336
+ matched?: undefined;
337
+ waitMs?: undefined;
252
338
  failed?: undefined;
253
339
  } | {
254
340
  failed: import("./session.js").NetworkEntry[];
@@ -256,20 +342,32 @@ export declare function networkTool(args: Record<string, any>): Promise<{
256
342
  entries?: undefined;
257
343
  matched?: undefined;
258
344
  waitMs?: undefined;
345
+ stats?: undefined;
259
346
  } | {
260
347
  entries: import("./session.js").NetworkEntry[];
261
348
  cleared?: undefined;
262
349
  matched?: undefined;
263
350
  waitMs?: undefined;
351
+ stats?: undefined;
264
352
  failed?: undefined;
265
353
  }>;
354
+ /** 使用 args.selector 定位的工具集合(自愈与录制指纹的作用范围)。 */
355
+ export declare const SELECTOR_STEP_TOOLS: Set<string>;
356
+ /**
357
+ * 采集选择器指向元素的指纹(页内 evaluate;找不到元素返回 null)。
358
+ * 指纹是回放自愈的降级候选来源:testid / role+name / text / id / tag+text。
359
+ */
360
+ export declare function captureSelectorHint(page: Page, selector: string): Promise<SelectorHint | null>;
361
+ /** 由指纹生成自愈降级候选(按优先级排序;导出供测试)。 */
362
+ export declare function healCandidates(hint: SelectorHint): {
363
+ via: string;
364
+ selector: string;
365
+ }[];
266
366
  /** 录制管理:start / stop / save / list / delete。 */
267
367
  export declare function recordTool(args: Record<string, any>): Promise<{
268
368
  recording: boolean;
269
369
  hint: string;
270
370
  steps?: undefined;
271
- saved?: undefined;
272
- file?: undefined;
273
371
  recordings?: undefined;
274
372
  deleted?: undefined;
275
373
  name?: undefined;
@@ -277,16 +375,18 @@ export declare function recordTool(args: Record<string, any>): Promise<{
277
375
  recording: boolean;
278
376
  steps: number;
279
377
  hint?: undefined;
280
- saved?: undefined;
281
- file?: undefined;
282
378
  recordings?: undefined;
283
379
  deleted?: undefined;
284
380
  name?: undefined;
285
381
  } | {
382
+ hint: string;
383
+ warnings?: string[] | undefined;
384
+ varsApplied?: number | undefined;
385
+ stripped?: number | undefined;
286
386
  saved: string;
287
387
  steps: number;
388
+ source: string;
288
389
  file: string;
289
- hint: string;
290
390
  recording?: undefined;
291
391
  recordings?: undefined;
292
392
  deleted?: undefined;
@@ -301,8 +401,6 @@ export declare function recordTool(args: Record<string, any>): Promise<{
301
401
  recording?: undefined;
302
402
  hint?: undefined;
303
403
  steps?: undefined;
304
- saved?: undefined;
305
- file?: undefined;
306
404
  deleted?: undefined;
307
405
  name?: undefined;
308
406
  } | {
@@ -311,29 +409,129 @@ export declare function recordTool(args: Record<string, any>): Promise<{
311
409
  recording?: undefined;
312
410
  hint?: undefined;
313
411
  steps?: undefined;
314
- saved?: undefined;
315
- file?: undefined;
316
412
  recordings?: undefined;
317
413
  }>;
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<{
414
+ /** 回放选项(自愈开关与单次尝试超时,来自 config)。 */
415
+ export interface ReplayOptions {
416
+ healing?: boolean;
417
+ healTimeoutMs?: number;
418
+ }
419
+ /** 回放执行器(步骤 → 工具调用),由 register.ts 注入实现 map。支持选择器自愈。 */
420
+ export declare function runReplay(steps: ReplayStep[], impls: Record<string, (args: any) => Promise<unknown>>, failFast: boolean, opts?: ReplayOptions): Promise<{
323
421
  total: number;
324
422
  passed: number;
325
423
  failed: number;
326
- stoppedAt: number | null;
424
+ healedCount: number;
425
+ stoppedAt?: number;
327
426
  results: any[];
328
427
  }>;
329
- /** 回放入口:name(已保存录制)或 steps(数组)二选一。 */
330
- export declare function replayTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>): Promise<{
428
+ export interface ExtractField {
429
+ name: string;
430
+ selector: string;
431
+ attr?: string;
432
+ multiple?: boolean;
433
+ fields?: ExtractField[];
434
+ }
435
+ /**
436
+ * 把单页抽取结果规整为行数组:恰好一个顶层 multiple 字段时,其数组即行
437
+ * (行内嵌套对象为行,标量包装成 { [name]: value });否则整页算一行。
438
+ */
439
+ export declare function rowsOfExtract(result: Record<string, any>, fields: ExtractField[]): Record<string, any>[];
440
+ /** 工作区内落盘路径解析(拒绝穿越到工作区之外)。 */
441
+ export declare function workspaceFilePath(cwd: string, file: string): string;
442
+ /**
443
+ * 规则化抽取:fields 定义抽取结构,next 选择器驱动翻页(maxPages 上限),
444
+ * 行数超 maxRows 截断;format/file 控制序列化与落盘(json/csv/jsonl/markdown)。
445
+ */
446
+ export declare function extractTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
447
+ url: string;
448
+ title: string;
449
+ file?: string | undefined;
450
+ bytes?: number | undefined;
451
+ truncated: boolean;
452
+ rows: Record<string, any>[];
453
+ count: number;
454
+ pages: number;
455
+ format: string;
456
+ }>;
457
+ /**
458
+ * 回归报告:list 列出最近运行,show 看单条详情,
459
+ * export 聚合生成 Markdown/HTML 报告落盘工作区。
460
+ */
461
+ export declare function reportTool(config: BrowserConfig, args: Record<string, any>, exec?: ToolRunContext): Promise<{
462
+ runs: {
463
+ row?: number | undefined;
464
+ runId: string;
465
+ ts: number;
466
+ kind: "replay" | "batch";
467
+ source: string;
468
+ total: number;
469
+ passed: number;
470
+ failed: number;
471
+ healedCount: number;
472
+ durationMs: number;
473
+ }[];
474
+ run?: undefined;
475
+ file?: undefined;
476
+ bytes?: undefined;
477
+ format?: undefined;
478
+ } | {
479
+ run: RunRecord;
480
+ runs?: undefined;
481
+ file?: undefined;
482
+ bytes?: undefined;
483
+ format?: undefined;
484
+ } | {
485
+ file: string;
486
+ bytes: number;
487
+ runs: number;
488
+ format: string;
489
+ run?: undefined;
490
+ }>;
491
+ /**
492
+ * 动作批处理:一次调用顺序执行多个浏览器步骤(内核复用 runReplay),
493
+ * 减少「点击→等待→输入」类固定小序列的工具往返。步骤内禁止嵌套
494
+ * batch/replay/record;批整体在操作轨迹里记为一条 browser_batch。
495
+ */
496
+ export declare function batchTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>, config?: BrowserConfig): Promise<{
497
+ summary: string;
498
+ total: number;
499
+ passed: number;
500
+ failed: number;
501
+ healedCount: number;
502
+ stoppedAt?: number;
503
+ results: any[];
504
+ }>;
505
+ /** 收集步骤中所有 {{var}} 占位符名(导出供测试)。 */
506
+ export declare function findPlaceholders(steps: ReplayStep[]): string[];
507
+ /**
508
+ * 深拷贝步骤并替换字符串叶子里的 {{var}} 占位符(导出供测试)。
509
+ * vars 缺失的占位符保留原样(由调用方先 findPlaceholders 校验)。
510
+ */
511
+ export declare function substituteVars(steps: ReplayStep[], vars: Record<string, unknown>): ReplayStep[];
512
+ /**
513
+ * 回放入口:name(已保存录制)或 steps(数组)二选一。
514
+ * vars 注入 {{占位符}};data/dataFile 数据集模式逐行运行并聚合。
515
+ */
516
+ export declare function replayTool(args: Record<string, any>, impls: Record<string, (args: any) => Promise<unknown>>, config?: BrowserConfig, exec?: ToolRunContext): Promise<{
517
+ source: string;
518
+ rows: number;
519
+ passedRows: number;
520
+ failedRows: number;
521
+ runs: any[];
522
+ summary: string;
523
+ } | {
331
524
  summary: string;
332
525
  total: number;
333
526
  passed: number;
334
527
  failed: number;
335
- stoppedAt: number | null;
528
+ healedCount: number;
529
+ stoppedAt?: number;
336
530
  results: any[];
337
531
  source: string;
532
+ rows?: undefined;
533
+ passedRows?: undefined;
534
+ failedRows?: undefined;
535
+ runs?: undefined;
338
536
  }>;
339
537
  //# 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,16 @@ 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;
22
34
  }
23
35
  /** 一个命名 profile 的会话状态。 */
24
36
  export interface ProfileState {
@@ -52,4 +64,28 @@ export interface FormField {
52
64
  label?: string;
53
65
  value?: string;
54
66
  }
67
+ /** ARIA 快照分配的 ref 注册项(ref → 定位信息)。 */
68
+ export interface RefEntry {
69
+ role: string;
70
+ name: string;
71
+ /** 生成快照时计算的稳定 CSS 路径(优先 #id / [data-testid] / nth-of-type 链)。 */
72
+ selector: string;
73
+ }
74
+ /** 录制时采集的选择器指纹(回放自愈的降级候选来源)。 */
75
+ export interface SelectorHint {
76
+ testid?: string;
77
+ role?: string;
78
+ name?: string;
79
+ id?: string;
80
+ text?: string;
81
+ tag?: string;
82
+ }
83
+ /** 录制/回放的一步(formatVersion 2 起支持 meta.hint 选择器指纹)。 */
84
+ export interface ReplayStep {
85
+ tool: string;
86
+ args: any;
87
+ meta?: {
88
+ hint?: SelectorHint;
89
+ };
90
+ }
55
91
  //# 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.2.0",
4
+ "description": "DSH 插件:共享 Playwright 浏览器自动化(31 个 browser_* 工具,含 ARIA ref 交互、批处理、视觉回归、选择器自愈、参数化回放、结构化抽取与回归报告)+ 原生界面实时画面面板 + 官方设置弹窗内的浏览器录制管理。仅依赖 playwright-core,不依赖任何 @deepseek-ai 运行时包。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/types/index.d.ts",