pageqa 0.5.1 → 0.7.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.
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { basename, dirname, extname, join } from "node:path";
3
4
  import { fileURLToPath } from "node:url";
4
5
  import { runAgent, runSuite } from "./agent.js";
5
6
  import { ensureConfigDir, CONFIG_PATH, loadConfig } from "./config.js";
6
- import { expandVars, VAR_HELP } from "./vars.js";
7
+ import { buildReplayScript, loadReplayScript, runReplayScript, sourceDriftNotice, writeReplayScript, } from "./replay.js";
8
+ import { captureRunVars, expandVars, VAR_HELP } from "./vars.js";
7
9
  import { info, setDebug } from "./log.js";
8
10
  function parseArgs(argv) {
9
11
  const args = {
@@ -12,6 +14,9 @@ function parseArgs(argv) {
12
14
  initConfig: false,
13
15
  help: false,
14
16
  debug: false,
17
+ emitScript: false,
18
+ semantic: false,
19
+ failFast: false,
15
20
  };
16
21
  for (let i = 0; i < argv.length; i++) {
17
22
  const a = argv[i];
@@ -20,9 +25,15 @@ function parseArgs(argv) {
20
25
  case "--help":
21
26
  args.help = true;
22
27
  break;
23
- case "--session":
24
- args.session = argv[++i];
28
+ case "--session": {
29
+ const v = argv[++i];
30
+ if (v === undefined) {
31
+ args.error = "--session 需要一个 session id 参数";
32
+ return args;
33
+ }
34
+ args.session = v;
25
35
  break;
36
+ }
26
37
  case "--json":
27
38
  args.json = true;
28
39
  break;
@@ -32,19 +43,78 @@ function parseArgs(argv) {
32
43
  case "--init-config":
33
44
  args.initConfig = true;
34
45
  break;
35
- case "--out":
36
- args.out = argv[++i];
46
+ case "--out": {
47
+ const v = argv[++i];
48
+ if (v === undefined) {
49
+ args.error = "--out 需要一个文件路径参数";
50
+ return args;
51
+ }
52
+ args.out = v;
37
53
  break;
54
+ }
38
55
  case "--debug":
39
56
  args.debug = true;
40
57
  break;
58
+ case "--replay": {
59
+ const v = argv[++i];
60
+ if (v === undefined) {
61
+ args.error = "--replay 需要一个回放脚本路径";
62
+ return args;
63
+ }
64
+ args.replay = v;
65
+ break;
66
+ }
67
+ case "--emit-script": {
68
+ args.emitScript = true;
69
+ // 路径可选:只有「看起来像路径」的后一个 token 才被当作输出路径消费,
70
+ // 否则(如 `pageqa --emit-script examples/smoke.md`)留给用例输入位。
71
+ const next = argv[i + 1];
72
+ if (next && looksLikeScriptPath(next)) {
73
+ args.emitScriptPath = next;
74
+ i++;
75
+ }
76
+ break;
77
+ }
78
+ case "--semantic":
79
+ args.semantic = true;
80
+ break;
81
+ case "--fail-fast":
82
+ args.failFast = true;
83
+ break;
41
84
  default:
42
- if (!a.startsWith("-"))
85
+ if (!a.startsWith("-")) {
86
+ // 只接受一个用例输入。此前是「后者覆盖前者」,`--emit-script ./replay`
87
+ // 这类写法一旦没被识别成输出路径,就会静默把用例换成 `./replay` 去跑,
88
+ // 看起来像正常启动、实际测的是完全无关的文本。这里改为直接报错。
89
+ if (args.input !== undefined) {
90
+ args.error =
91
+ `多余的位置参数:${a}(只接受一个用例输入` +
92
+ `;路径含空格请用引号包裹,输出路径请放在 --emit-script 之后)`;
93
+ return args;
94
+ }
43
95
  args.input = a;
96
+ }
44
97
  }
45
98
  }
46
99
  return args;
47
100
  }
101
+ /**
102
+ * 判断 `--emit-script` 后面的 token 是否应被当作输出路径。
103
+ *
104
+ * 判据是「像不像一个路径」而不是「是不是 .json 结尾」:用户完全可能想写成
105
+ * `--emit-script ./replay`(不带扩展名)。因此:
106
+ * - 以 `-` 开头 → 是下一个选项,不是路径;
107
+ * - 以 .md/.txt 结尾 → 是用例文件,留给输入位(支持 `--emit-script 用例.md` 的写法);
108
+ * - 含空白或中文 → 是内联用例文本,留给输入位;
109
+ * - 其余(`./replay`、`out.json`、`reports/run1`)→ 当作输出路径。
110
+ */
111
+ function looksLikeScriptPath(token) {
112
+ if (token.startsWith("-"))
113
+ return false;
114
+ if (/\.(md|txt)$/i.test(token))
115
+ return false;
116
+ return /^[A-Za-z0-9_./\\-]+$/.test(token);
117
+ }
48
118
  const HELP = `pageqa - 自然语言驱动的页面测试工具(pi-agent-core + browserskill)
49
119
 
50
120
  用法:
@@ -52,6 +122,7 @@ const HELP = `pageqa - 自然语言驱动的页面测试工具(pi-agent-core +
52
122
 
53
123
  <input> 自然语言脚本文件(.md/.txt,路径含空格请用引号包裹),
54
124
  或用引号包裹的内联文本
125
+ 只接受一个用例输入;多给一个会直接报错
55
126
  脚本中可用『## 场景名』分隔多个测试场景,自动批量运行
56
127
  路径中粘贴带来的不可见字符(Bidi/零宽)会被自动清理;
57
128
  若路径以 .md/.txt 结尾但文件不存在,会直接报错而非当作内联文本
@@ -62,11 +133,30 @@ const HELP = `pageqa - 自然语言驱动的页面测试工具(pi-agent-core +
62
133
  并关掉它对应的浏览器窗口(Agent Window)
63
134
  --json 输出 JSON 报告
64
135
  --suite 强制按多场景套件运行(即使只有一个场景)
136
+ --emit-script [path]
137
+ 运行结束后把本次成功的操作序列固化成回放脚本(Replay Script)
138
+ 不给 path 时写到源用例同目录 <用例名>.replay.json
139
+ (内联文本写 ./pageqa.replay.json)
140
+ path 建议写成路径形式(如 ./replay、reports/run1.json),
141
+ 含空白请用引号包裹;紧跟其后的若是 .md/.txt 或含空白的文本,
142
+ 会被当作用例输入而不是输出路径
143
+ 无论 PASS/FAIL 都会生成,便于排查与续写
144
+ --replay <file> 零模型回放已有的回放脚本(详见下方「回放脚本」)
145
+ --semantic 回放时断言改用 Jev 语义判断(默认字符串包含)
65
146
  --init-config 在用户目录创建/重置配置文件
66
147
  --out <file> 将报告写入文件
67
148
  --debug 显示调试日志(bsk 命令、快照体积、上下文裁剪、Jev 请求详情)
68
149
  -h, --help 显示帮助
69
150
 
151
+ 回放脚本(零模型重跑同一用例):
152
+ pageqa --replay <file.replay.json> [--session <id>] [--json] [--semantic] [--fail-fast]
153
+ 按脚本逐步驱动浏览器,**不调用任何大模型**,断言默认走字符串包含
154
+ --semantic 可改用 Jev 语义判断(需已在配置里启用 Jev)
155
+ 元素定位用录制时的语义定位符在当次快照里重新解析,
156
+ 因此页面小幅调整后脚本仍可命中;源用例变更会在 stderr 提示
157
+ --fail-fast 任一失败即停止该场景;默认会跑完剩余步骤,
158
+ 以便一次拿到整条用例的完整健康报告(失败仍会让退出码非零)
159
+
70
160
  进度日志:
71
161
  - 运行进度会带时间戳实时输出到 stderr(bsk daemon 启动、session、每一步工具调用、
72
162
  续跑与最终结论等),stdout 只输出最终报告,两者互不干扰;长流程可据此判断进行到哪一步。
@@ -124,8 +214,60 @@ function cleanInput(raw) {
124
214
  function looksLikeScriptFile(input) {
125
215
  return !/[\r\n]/.test(input) && /\.(md|txt)$/i.test(input);
126
216
  }
217
+ /**
218
+ * 默认的回放脚本落盘位置:贴着源用例(同名 + `.replay.json`),便于和用例一起进 git 评审。
219
+ * 内联文本没有源文件,落到当前工作目录。
220
+ */
221
+ function defaultScriptPath(rawInput, isFile) {
222
+ if (!isFile)
223
+ return "pageqa.replay.json";
224
+ return join(dirname(rawInput), basename(rawInput, extname(rawInput)) + ".replay.json");
225
+ }
226
+ /**
227
+ * 回放模式入口:加载脚本、提示源用例漂移,然后零模型逐步执行。
228
+ * 退出码语义与自然语言模式一致(全部断言通过 0,否则 1),可直接接 CI。
229
+ */
230
+ async function replayMode(args) {
231
+ const path = args.replay;
232
+ let script;
233
+ try {
234
+ script = loadReplayScript(path);
235
+ }
236
+ catch (err) {
237
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
238
+ return 1;
239
+ }
240
+ info("[pageqa] ===== 回放启动 =====");
241
+ const drift = sourceDriftNotice(script);
242
+ if (drift)
243
+ info(`[pageqa] 警告:${drift}`);
244
+ try {
245
+ const result = await runReplayScript(script, {
246
+ session: args.session,
247
+ semantic: args.semantic,
248
+ debug: args.debug,
249
+ scriptPath: path,
250
+ now: new Date(),
251
+ failFast: args.failFast,
252
+ });
253
+ const out = args.json ? result.json : result.text;
254
+ if (args.out)
255
+ writeFileSync(args.out, out + "\n");
256
+ process.stdout.write(out + "\n");
257
+ return result.report.status === "pass" ? 0 : 1;
258
+ }
259
+ catch (err) {
260
+ process.stderr.write(`回放失败: ${err instanceof Error ? err.stack : String(err)}\n`);
261
+ return 1;
262
+ }
263
+ }
127
264
  async function main() {
128
265
  const args = parseArgs(process.argv.slice(2));
266
+ if (args.error) {
267
+ process.stderr.write(`参数错误:${args.error}\n\n`);
268
+ process.stdout.write(HELP + "\n");
269
+ return 1;
270
+ }
129
271
  if (args.help) {
130
272
  process.stdout.write(HELP + "\n");
131
273
  return 0;
@@ -137,6 +279,19 @@ async function main() {
137
279
  process.stdout.write(`当前生效配置:${JSON.stringify(loadConfig(), null, 2)}\n`);
138
280
  return 0;
139
281
  }
282
+ // ── 回放模式:零模型执行已有脚本(与用例输入互斥)──
283
+ if (args.replay) {
284
+ if (args.input) {
285
+ process.stderr.write("参数错误:--replay 不能与用例输入同时使用\n\n");
286
+ return 1;
287
+ }
288
+ if (args.emitScript) {
289
+ process.stderr.write("参数错误:--emit-script 用于生成回放脚本,不能与 --replay 同时使用\n\n");
290
+ return 1;
291
+ }
292
+ setDebug(args.debug);
293
+ return await replayMode(args);
294
+ }
140
295
  if (!args.input) {
141
296
  process.stdout.write(HELP + "\n");
142
297
  return 1;
@@ -152,23 +307,52 @@ async function main() {
152
307
  ` - 若只想跑内联文本,请不要让文本以 .md/.txt 结尾\n`);
153
308
  return 1;
154
309
  }
155
- const input = isFile
156
- ? expandVars(readFileSync(rawInput, "utf8"))
157
- : expandVars(rawInput);
310
+ const sourceText = isFile ? readFileSync(rawInput, "utf8") : rawInput;
311
+ // 展开占位符与「反查占位符」必须共用同一时刻:
312
+ // 生成回放脚本时才能把模型看到的具体值(202609191146)还原成 ${timestamp}。
313
+ const now = new Date();
314
+ const input = expandVars(sourceText, now);
315
+ const vars = captureRunVars(now);
158
316
  const hasScenarios = /^##\s+/m.test(input);
159
317
  const suiteMode = hasScenarios || args.suite;
318
+ const scriptPath = args.emitScript
319
+ ? (args.emitScriptPath ?? defaultScriptPath(rawInput, isFile))
320
+ : undefined;
160
321
  info("[pageqa] ===== 启动 =====");
161
322
  info(`[pageqa] 已读取${isFile ? `脚本文件 ${rawInput}` : "内联用例"}(${input.length} 字符)`);
162
323
  info(`[pageqa] 运行模式:${suiteMode ? "多场景套件" : "单场景"}` +
163
324
  `${args.session ? `,session=${args.session}` : ""}` +
164
325
  `${args.debug ? ",debug=on(stderr 含调试明细)" : ""}`);
326
+ if (scriptPath) {
327
+ info(`[pageqa] 运行结束将生成回放脚本:${scriptPath}`);
328
+ }
165
329
  try {
166
330
  const result = suiteMode
167
- ? await runSuite(input, { session: args.session, debug: args.debug })
168
- : await runAgent(input, { session: args.session, debug: args.debug });
331
+ ? await runSuite(input, {
332
+ session: args.session,
333
+ debug: args.debug,
334
+ vars,
335
+ scriptPath,
336
+ })
337
+ : await runAgent(input, {
338
+ session: args.session,
339
+ debug: args.debug,
340
+ vars,
341
+ scriptPath,
342
+ });
343
+ if (scriptPath) {
344
+ const script = buildReplayScript(result.recordings, {
345
+ sourcePath: isFile ? rawInput : null,
346
+ sourceText,
347
+ });
348
+ writeReplayScript(scriptPath, script);
349
+ const steps = script.scenarios.reduce((n, s) => n + s.steps.length, 0);
350
+ info(`[pageqa] 回放脚本已生成:${scriptPath}` +
351
+ `(${script.scenarios.length} 个场景,共 ${steps} 步)`);
352
+ info(`[pageqa] 下次可零模型回放:pageqa --replay ${scriptPath}`);
353
+ }
169
354
  const out = args.json ? result.json : result.text;
170
355
  if (args.out) {
171
- const { writeFileSync } = await import("node:fs");
172
356
  writeFileSync(args.out, out + "\n");
173
357
  }
174
358
  process.stdout.write(out + "\n");
@@ -185,4 +369,15 @@ main()
185
369
  process.stderr.write(`执行失败: ${err instanceof Error ? err.stack : String(err)}\n`);
186
370
  process.exit(1);
187
371
  });
372
+ // 兜底:main() 的 catch 只能捕获其 Promise 链内的错误。
373
+ // 工具执行、事件订阅回调等异步路径上抛出的异常不会被它捕获,
374
+ // 若不处理会直接静默崩溃(进程退出码非 0 但无任何报错信息)。
375
+ process.on("uncaughtException", (err) => {
376
+ process.stderr.write(`执行失败(未捕获异常): ${err instanceof Error ? err.stack : String(err)}\n`);
377
+ process.exit(1);
378
+ });
379
+ process.on("unhandledRejection", (reason) => {
380
+ process.stderr.write(`执行失败(未处理的 Promise rejection): ${reason instanceof Error ? reason.stack : String(reason)}\n`);
381
+ process.exit(1);
382
+ });
188
383
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAwB1C,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,IAAI,GAAY;QACpB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,KAAK;KAChB,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC;YACV,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,KAAK,GAAG,8BAA8B,CAAC;oBAC5C,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;YACD,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,KAAK,SAAS;gBACZ,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;gBAClB,MAAM;YACR,KAAK,eAAe;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,KAAK,GAAG,kBAAkB,CAAC;oBAChC,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;gBACb,MAAM;YACR,CAAC;YACD,KAAK,SAAS;gBACZ,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;gBAClB,MAAM;YACR,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,KAAK,GAAG,qBAAqB,CAAC;oBACnC,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;gBAChB,MAAM;YACR,CAAC;YACD,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,wCAAwC;gBACxC,yDAAyD;gBACzD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACzB,IAAI,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;oBAC3B,CAAC,EAAE,CAAC;gBACN,CAAC;gBACD,MAAM;YACR,CAAC;YACD,KAAK,YAAY;gBACf,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,MAAM;YACR,KAAK,aAAa;gBAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,MAAM;YACR;gBACE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvB,iDAAiD;oBACjD,2CAA2C;oBAC3C,kCAAkC;oBAClC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;wBAC7B,IAAI,CAAC,KAAK;4BACR,WAAW,CAAC,YAAY;gCACxB,wCAAwC,CAAC;wBAC3C,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;gBACjB,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDX,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;CAwBT,CAAC;AAEF;;;;GAIG;AACH,MAAM,eAAe,GAAG,kDAAkD,CAAC;AAE3E,wDAAwD;AACxD,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC9C,IAAI,MAAM;QAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,4BAA4B;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,iDAAiD;AACjD,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,QAAgB,EAAE,MAAe;IAC1D,IAAI,CAAC,MAAM;QAAE,OAAO,oBAAoB,CAAC;IACzC,OAAO,IAAI,CACT,OAAO,CAAC,QAAQ,CAAC,EACjB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,cAAc,CACvD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,UAAU,CAAC,IAAa;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAgB,CAAC;IACnC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CACxD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,KAAK;QAAE,IAAI,CAAC,eAAe,KAAK,EAAE,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE;YAC3C,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI;YAChB,GAAG,EAAE,IAAI,IAAI,EAAE;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;QAClD,IAAI,IAAI,CAAC,GAAG;YAAE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC5D,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;QAC9B,UAAU,EAAE,CAAC,CAAC,WAAW;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,WAAW,QAAQ,GAAG,IAAI,CAAC,CAAC;QAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACpD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,+BAA+B;IAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACtD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mDAAmD,CACpD,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,CAAC,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,uCAAuC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,WAAW,QAAQ,IAAI;YACrB,oBAAoB;YACpB,8CAA8C;YAC9C,oCAAoC,CACvC,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACtE,yBAAyB;IACzB,oDAAoD;IACpD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;QAChC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9D,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAChC,IAAI,CACF,eAAe,MAAM,CAAC,CAAC,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,MAAM,CAC1E,CAAC;IACF,IAAI,CACF,iBAAiB,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE;QAC5C,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACnD,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC;IACF,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS;YACtB,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE;gBACpB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI;gBACJ,UAAU;aACX,CAAC;YACJ,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE;gBACpB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI;gBACJ,UAAU;aACX,CAAC,CAAC;QACP,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,UAAU,EAAE;gBAClD,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;gBACpC,UAAU;aACX,CAAC,CAAC;YACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACvE,IAAI,CACF,oBAAoB,UAAU,EAAE;gBAC9B,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,UAAU,KAAK,KAAK,CAClD,CAAC;YACF,IAAI,CAAC,qCAAqC,UAAU,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;QAClD,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC5D,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,IAAI,EAAE;KACH,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAClC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC5D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,yCAAyC;AACzC,gCAAgC;AAChC,kCAAkC;AAClC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gBAAgB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CACnE,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iCACE,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CACxD,IAAI,CACL,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/llm.js CHANGED
@@ -13,6 +13,27 @@ const MODELS = [
13
13
  { id: "hy3", name: "Hy3", contextWindow: 192000, maxOutput: 64000 },
14
14
  { id: "deepseek-v4.1-flash", name: "Deepseek-V4.1-Flash", contextWindow: 1_000_000, maxOutput: 128_000 },
15
15
  ];
16
+ /** 预设之外的模型使用的保守上下文窗口/输出上限(未知模型按最小预设处理,避免超出端点实际限制)。 */
17
+ const FALLBACK_CONTEXT_WINDOW = 32_000;
18
+ const FALLBACK_MAX_OUTPUT = 64_000;
19
+ /**
20
+ * 解析实际要注册的模型清单:预设模型沿用精确的 contextWindow/maxOutput;
21
+ * 用户配置了预设之外的模型时,动态补一条保守条目,使「改配置即用」成立
22
+ * (README 承诺 baseUrl/apiKey/model 均可配置、无需改代码)。
23
+ */
24
+ function resolveModels(modelId) {
25
+ if (MODELS.some((m) => m.id === modelId))
26
+ return MODELS;
27
+ return [
28
+ ...MODELS,
29
+ {
30
+ id: modelId,
31
+ name: modelId,
32
+ contextWindow: FALLBACK_CONTEXT_WINDOW,
33
+ maxOutput: FALLBACK_MAX_OUTPUT,
34
+ },
35
+ ];
36
+ }
16
37
  /** 构造一个静态解析的 ApiKeyAuth(避免交互式 env 探测)。 */
17
38
  function staticApiKeyAuth(apiKey, baseUrl) {
18
39
  return {
@@ -26,11 +47,12 @@ export function createLlmBackend() {
26
47
  const DEFAULT_API_KEY = cfg.apiKey;
27
48
  const DEFAULT_MODEL = cfg.model;
28
49
  const models = createModels();
50
+ const registered = resolveModels(DEFAULT_MODEL);
29
51
  const provider = createProvider({
30
52
  id: PROVIDER_ID,
31
53
  name: "OpenAI Compatible (自定义端点)",
32
54
  auth: { apiKey: staticApiKeyAuth(DEFAULT_API_KEY, DEFAULT_BASE_URL) },
33
- models: MODELS.map((m) => ({
55
+ models: registered.map((m) => ({
34
56
  id: m.id,
35
57
  name: m.name,
36
58
  api: "openai-completions",
package/dist/llm.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAwB,MAAM,uBAAuB,CAAC;AAC3F,OAAO,KAAK,iBAAiB,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;GAKG;AAEH,MAAM,WAAW,GAAG,QAAQ,CAAC;AAS7B,MAAM,MAAM,GAAqB;IAC/B,EAAE,EAAE,EAAE,sBAAsB,EAAE,IAAI,EAAE,sBAAsB,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE;IACpG,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE;IACnE,EAAE,EAAE,EAAE,qBAAqB,EAAE,IAAI,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE;CACzG,CAAC;AAEF,0CAA0C;AAC1C,SAAS,gBAAgB,CAAC,MAAc,EAAE,OAAe;IACvD,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC;AAOD,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAAC;IACrC,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,CAAC;IACnC,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC;IAChC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,cAAc,CAAC;QAC9B,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,2BAA2B;QACjC,IAAI,EAAE,EAAE,MAAM,EAAE,gBAAgB,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAAE;QACrE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,GAAG,EAAE,oBAAoB;YACzB,QAAQ,EAAE,WAAW;YACrB,OAAO,EAAE,gBAAgB;YACzB,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,SAAS,EAAE,KAAK;YAChB,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;YAC1D,MAAM,EAAE;gBACN,aAAa,EAAE,KAAK;gBACpB,qBAAqB,EAAE,KAAK;gBAC5B,uBAAuB,EAAE,KAAK;gBAC9B,cAAc,EAAE,YAAY;gBAC5B,0BAA0B,EAAE,KAAK;aAClC;SACF,CAAC,CAAC;QACH,GAAG,EAAE,iBAAiB;KACvB,CAAC,CAAC;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAE7B,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,SAAS,aAAa,aAAa,WAAW,oDAAoD,CACnG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * 元素定位符(Locator):把「这次点的是哪个元素」表达成跨快照可复用的语义描述。
3
+ *
4
+ * 背景:bsk 的 `@eN` 引用只在**产生它的那次快照**内有效,下一次 snapshot 编号会重排,
5
+ * 因此回放脚本不能直接存 `@eN`。bsk 快照文本是一棵缩进的 aria 树,每个可交互节点形如:
6
+ *
7
+ * @e1 link "Learn more" [→ iana.org]
8
+ *
9
+ * 其中的「角色 + 可访问名」(role + name)才是稳定的语义信息:页面微调后仍能重新命中。
10
+ * 本模块负责在**录制时**把 target 解析成定位符,并在**回放时**用新的快照把它解析回 `@eN`。
11
+ *
12
+ * 定位符不保证唯一:同名元素可能有多个(列表每行都有「操作」按钮、页面级与区域级各有一个
13
+ * 「操作」下拉)。因此还记录两样东西:
14
+ * - `nth`:录制时在所有同名候选中排第几;
15
+ * - `path`:录制时该节点的**祖先路径**(只保留有名字的祖先)。
16
+ * 回放时优先用祖先路径消歧——「同名第几个」在页面里同类元素数量变化后会指错,
17
+ * 而「在哪个区域下」是更强、更抗漂移的信号。
18
+ */
19
+ /** bsk 快照中带有 `@eN` 引用的一行。 */
20
+ export interface SnapshotRef {
21
+ /** 引用本身,形如 `@e1`。 */
22
+ ref: string;
23
+ /** 角色(link / button / textbox …),取不到时为空串。 */
24
+ role: string;
25
+ /** 可访问名(按钮文案、链接文字等),取不到时为空串。 */
26
+ name: string;
27
+ /** 祖先路径(从浅到深,只保留有名字的祖先),如 `tabpanel "结构"`。 */
28
+ path: string[];
29
+ }
30
+ /**
31
+ * 元素定位符:语义定位(role + name + 祖先路径 + 同名序号)+ 录制时的原始 target 作为兜底。
32
+ */
33
+ export interface Locator {
34
+ role: string;
35
+ name: string;
36
+ /** 在所有 role+name 相同的候选中排第几(0 起);无法判定时为 -1。 */
37
+ nth: number;
38
+ /** 录制时的原始 target(`@eN` 或 CSS 选择器)。 */
39
+ target: string;
40
+ /** 录制时的祖先路径,用于同名元素消歧。 */
41
+ path: string[];
42
+ }
43
+ /** 是否为 bsk 快照引用(`@e1` 或 `e1`)。回放时引用必须重新解析,CSS 选择器则可直接用。 */
44
+ export declare function isRef(target: string): boolean;
45
+ /** 归一化引用写法:`e1` -> `@e1`。 */
46
+ export declare function normalizeRef(target: string): string;
47
+ /**
48
+ * 解析 bsk 快照文本里所有带引用的行,得到「引用 -> 角色/可访问名/祖先路径」。
49
+ *
50
+ * 缩进即层级:维护一个缩进栈,遇到更浅或同级的新行就弹出更深/同级的节点,
51
+ * 因此每个引用都能拿到「它在哪个区域(tabpanel / dialog / 某个标题)之下」。
52
+ * `@vom` / `@view` / `@layers` / `L1 page` 等元信息行不参与树。
53
+ */
54
+ export declare function parseSnapshotRefs(snapshotText: string): SnapshotRef[];
55
+ /**
56
+ * 录制时构造定位符:从当时的快照里查出该引用对应的角色/可访问名、同名序号与祖先路径。
57
+ *
58
+ * target 是 CSS 选择器(或快照里查不到的引用)时,定位符退化为「只有 target 兜底」,
59
+ * 回放时直接按原 target 操作。
60
+ */
61
+ export declare function buildLocator(target: string, snapshotText: string): Locator;
62
+ /**
63
+ * 回放时用**新的**快照把定位符解析回 `@eN`。
64
+ *
65
+ * 匹配策略逐级放宽,都不中则返回 null(由调用方决定退回 target 还是报错):
66
+ * 1. role + name 全等(最常见,页面没变时必然命中)
67
+ * 2. role 相同且 name 包含(文案被加了前后缀,如「操作」→「操作 更多」)
68
+ * 3. 只看 name(角色被前端改过,如 button 变 a)
69
+ *
70
+ * 命中多个候选时,先按**祖先路径**消歧(「结构」tab 下的「操作」与产品级的「操作」
71
+ * 名字完全一样,只有所属区域能区分),路径也无法区分时才退回录制的同名序号 `nth`。
72
+ */
73
+ export declare function resolveLocator(locator: Locator, snapshotText: string): string | null;
74
+ /** 定位失败时给出的线索类型。 */
75
+ export interface LocatorHint {
76
+ /** similar-name:有名字相近的同角色元素;role-only:有该角色元素但名字都不同;no-role:该角色元素一个都没有。 */
77
+ kind: "similar-name" | "role-only" | "no-role";
78
+ /** 可读的候选元素(最多若干个)。 */
79
+ items: string[];
80
+ /** 页面上该角色的元素总数。 */
81
+ roleCount: number;
82
+ }
83
+ /**
84
+ * 定位不到时给出「当前页面里有什么」的线索。
85
+ *
86
+ * 「元素未找到」本身是条死路,用户只知道某步挂了。区分三种情况后,报告能直接回答
87
+ * 「是弹窗没打开」「是菜单点错了一个」还是「元素改名了」,用户据此就能判断该改脚本还是改用例。
88
+ */
89
+ export declare function locatorHint(locator: Locator, snapshotText: string, limit?: number): LocatorHint;
90
+ /** 定位符的可读描述,用于报告与日志(说明「当时点的是什么、在哪个区域」)。 */
91
+ export declare function describeLocator(locator: Locator | null): string;