@qing3a/flow-rpa-engine 0.1.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.
Files changed (55) hide show
  1. package/dist/atomic.d.ts +9 -0
  2. package/dist/atomic.js +32 -0
  3. package/dist/atomic.js.map +1 -0
  4. package/dist/bench.d.ts +57 -0
  5. package/dist/bench.js +112 -0
  6. package/dist/bench.js.map +1 -0
  7. package/dist/cdp/client.d.ts +70 -0
  8. package/dist/cdp/client.js +272 -0
  9. package/dist/cdp/client.js.map +1 -0
  10. package/dist/cdp/page.d.ts +93 -0
  11. package/dist/cdp/page.js +411 -0
  12. package/dist/cdp/page.js.map +1 -0
  13. package/dist/executor.d.ts +122 -0
  14. package/dist/executor.js +399 -0
  15. package/dist/executor.js.map +1 -0
  16. package/dist/export.d.ts +128 -0
  17. package/dist/export.js +234 -0
  18. package/dist/export.js.map +1 -0
  19. package/dist/gate.d.ts +56 -0
  20. package/dist/gate.js +144 -0
  21. package/dist/gate.js.map +1 -0
  22. package/dist/hello.d.ts +5 -0
  23. package/dist/hello.js +13 -0
  24. package/dist/hello.js.map +1 -0
  25. package/dist/human.d.ts +162 -0
  26. package/dist/human.js +506 -0
  27. package/dist/human.js.map +1 -0
  28. package/dist/index.d.ts +20 -0
  29. package/dist/index.js +16 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/learning.d.ts +82 -0
  32. package/dist/learning.js +240 -0
  33. package/dist/learning.js.map +1 -0
  34. package/dist/mask.d.ts +32 -0
  35. package/dist/mask.js +70 -0
  36. package/dist/mask.js.map +1 -0
  37. package/dist/platform.d.ts +66 -0
  38. package/dist/platform.js +215 -0
  39. package/dist/platform.js.map +1 -0
  40. package/dist/record.d.ts +48 -0
  41. package/dist/record.js +42 -0
  42. package/dist/record.js.map +1 -0
  43. package/dist/schema.d.ts +130 -0
  44. package/dist/schema.js +93 -0
  45. package/dist/schema.js.map +1 -0
  46. package/dist/simprofile.d.ts +94 -0
  47. package/dist/simprofile.js +247 -0
  48. package/dist/simprofile.js.map +1 -0
  49. package/dist/storage.d.ts +63 -0
  50. package/dist/storage.js +138 -0
  51. package/dist/storage.js.map +1 -0
  52. package/dist/validate.d.ts +37 -0
  53. package/dist/validate.js +108 -0
  54. package/dist/validate.js.map +1 -0
  55. package/package.json +32 -0
@@ -0,0 +1,399 @@
1
+ import { z } from 'zod';
2
+ import { maskInputValue } from './mask.js';
3
+ import { StepSchema } from './schema.js';
4
+ import { XorShift32 } from './simprofile.js';
5
+ function execErrorMessage(kind, detail, stepId) {
6
+ switch (kind) {
7
+ case 'page':
8
+ return `页面操作失败: ${detail}`;
9
+ case 'step_action':
10
+ return `步骤 ${stepId ?? '?'} 动作失败: ${detail}`;
11
+ case 'verify':
12
+ return `步骤 ${stepId ?? '?'} 验证失败: ${detail}`;
13
+ case 'unknown_step':
14
+ return `未知步骤类型: ${detail}`;
15
+ }
16
+ }
17
+ /**
18
+ * 执行错误。`message` 为完整文案(与 Rust `ExecError::to_string()` 一致,测试断言依赖)。
19
+ * `category` 为失败类别(D-L2 用 `index_out_of_range`;A2 失败类型学 M6 扩展)。
20
+ */
21
+ export class ExecError extends Error {
22
+ kind;
23
+ detail;
24
+ category;
25
+ constructor(kind, detail, opts) {
26
+ super(execErrorMessage(kind, detail, opts?.stepId));
27
+ this.kind = kind;
28
+ this.detail = detail;
29
+ this.name = 'ExecError';
30
+ this.category = opts?.category;
31
+ }
32
+ static page(msg, opts) {
33
+ return new ExecError('page', msg, opts);
34
+ }
35
+ static stepAction(stepId, msg) {
36
+ return new ExecError('step_action', msg, { stepId });
37
+ }
38
+ static verify(stepId, msg, category) {
39
+ return new ExecError('verify', msg, { stepId, category });
40
+ }
41
+ static unknownStep(type) {
42
+ return new ExecError('unknown_step', type);
43
+ }
44
+ }
45
+ // ---- 工具 ----
46
+ /** 变量插值:把 template 里的 `{name}` 替换为 vars 中的值(找不到则原样保留) */
47
+ function interpolate(template, vars) {
48
+ let out = template;
49
+ for (const [k, v] of vars) {
50
+ out = out.split(`{${k}}`).join(v);
51
+ }
52
+ return out;
53
+ }
54
+ function getParam(step, key) {
55
+ const v = step.params[key];
56
+ return typeof v === 'string' ? v : undefined;
57
+ }
58
+ /** 读取选择器参数(A3 D-S1):string = 单元素链(向后兼容);string[] = 链 */
59
+ function getSelectors(step, key, vars) {
60
+ const v = step.params[key];
61
+ if (typeof v === 'string')
62
+ return [interpolate(v, vars)];
63
+ if (Array.isArray(v)) {
64
+ const sels = v.filter((x) => typeof x === 'string');
65
+ if (sels.length === 0)
66
+ return undefined;
67
+ return sels.map((s) => interpolate(s, vars));
68
+ }
69
+ return undefined;
70
+ }
71
+ /**
72
+ * 选择器链尝试(A3 D-S1):依次调用 op,第一个「命中」的生效;全部不命中 → 失败,
73
+ * 错误文案「选择器未命中」前缀 + 列出全部尝试项。单选择器时直接调用(向后兼容:
74
+ * 失败透传原错误,无链包装)。失败时返回最后尝试项(D-S2:未命中失败记最后尝试项)。
75
+ */
76
+ async function runSelectorChain(selectors, op, isHit) {
77
+ if (selectors.length === 1) {
78
+ const value = await op(selectors[0]);
79
+ return { value, hit: selectors[0] };
80
+ }
81
+ const tried = [];
82
+ for (const sel of selectors) {
83
+ try {
84
+ const value = await op(sel);
85
+ if (isHit(value))
86
+ return { value, hit: sel };
87
+ tried.push(sel);
88
+ }
89
+ catch {
90
+ tried.push(sel);
91
+ }
92
+ }
93
+ const err = ExecError.page(`选择器未命中: ${tried.join(', ')}`);
94
+ err.lastTried = tried[tried.length - 1];
95
+ throw err;
96
+ }
97
+ /** click 的 index 参数:数字直接取;字符串插值后解析(解析失败 → 0,等价 Rust as_u64().unwrap_or(0)) */
98
+ function parseIndex(step, vars) {
99
+ const v = step.params.index;
100
+ if (typeof v === 'number')
101
+ return Math.floor(v) >= 0 ? Math.floor(v) : 0;
102
+ if (typeof v === 'string') {
103
+ const s = interpolate(v, vars);
104
+ const n = Number(s);
105
+ if (Number.isInteger(n) && n >= 0)
106
+ return n;
107
+ }
108
+ return 0;
109
+ }
110
+ /** loop 子步骤解析(结构由 validate 保证;执行时容错) */
111
+ function parseSubSteps(step) {
112
+ const steps = step.params.steps;
113
+ if (!Array.isArray(steps)) {
114
+ throw ExecError.stepAction(step.id, 'loop 缺合法 params.steps');
115
+ }
116
+ try {
117
+ return z.array(StepSchema).parse(steps);
118
+ }
119
+ catch {
120
+ throw ExecError.stepAction(step.id, 'loop 缺合法 params.steps');
121
+ }
122
+ }
123
+ /** maxIterations(D-L3):params.maxIterations number,默认 50 */
124
+ function getMaxIterations(step) {
125
+ const v = step.params.maxIterations;
126
+ if (typeof v === 'number' && Number.isInteger(v) && v > 0)
127
+ return v;
128
+ return 50;
129
+ }
130
+ // 任务内冷却区间(防封铁律;M5 gate.ts 正式落地时移入,避免建半成品模块)
131
+ const COOLDOWN_MIN_SECS = 30;
132
+ const COOLDOWN_MAX_SECS = 60;
133
+ const elapsed = (t0) => Math.round(performance.now() - t0);
134
+ // ---- verify ----
135
+ /**
136
+ * 验证点检查:urlContains / textContains / waitSelector 全部满足才算通过(AND)。
137
+ * 成功返回 VerifyOutcome(含实际检查项 + 耗时);失败抛 ExecError(含失败信息)。
138
+ */
139
+ async function checkVerify(page, stepId, verify, vars) {
140
+ const t0 = performance.now();
141
+ const checked = [];
142
+ if (verify.urlContains !== undefined) {
143
+ const sub = interpolate(verify.urlContains, vars);
144
+ checked.push(['url_contains', sub]);
145
+ if (!(await page.currentUrl()).includes(sub)) {
146
+ throw ExecError.verify(stepId, `URL 不含 ${sub}(实际 ${await page.currentUrl()})`);
147
+ }
148
+ }
149
+ if (verify.textContains !== undefined) {
150
+ const sub = interpolate(verify.textContains, vars);
151
+ checked.push(['text_contains', sub]);
152
+ // 空字符串 textContains 无意义(插值后为空且原文含 {var} → 变量缺失,判失败,防假通过)
153
+ if (sub === '' && sub !== verify.textContains) {
154
+ throw ExecError.verify(stepId, `页面文本变量缺失: ${verify.textContains}`);
155
+ }
156
+ if (!(await page.pageText()).includes(sub)) {
157
+ throw ExecError.verify(stepId, `页面文本不含 ${sub}`);
158
+ }
159
+ }
160
+ if (verify.waitSelector !== undefined) {
161
+ const sel = interpolate(verify.waitSelector, vars);
162
+ checked.push(['wait_selector', sel]);
163
+ try {
164
+ await page.waitSelector(sel, verify.timeoutMs);
165
+ }
166
+ catch {
167
+ throw ExecError.verify(stepId, `等待选择器 ${sel} 超时`);
168
+ }
169
+ }
170
+ // 多条件 AND 全部通过:取首个检查项作为 outcome 摘要
171
+ const first = checked[0];
172
+ return { kind: first?.[0], detail: first?.[1], passed: true, durationMs: elapsed(t0) };
173
+ }
174
+ /** 执行单个步骤(loop 递归执行子步骤)。每步(含失败)push 一条结构化记录。 */
175
+ async function runStep(ctx, step) {
176
+ const { flowId, page, vars, results, opts } = ctx;
177
+ const t0 = performance.now();
178
+ // 掩码前移:input 步骤的输入值在落盘时刻就掩码(明文不落盘)
179
+ let maskedValue;
180
+ let selectorHit;
181
+ let extractInfo;
182
+ let actionError;
183
+ // loop 子步骤失败时子步骤已各自 push failed 记录;loop 本身不重复记。
184
+ // 用该标志跳过 runStep 的失败记录(Rust 语义:loop 无独立失败记录)。
185
+ let loopChildFailed = false;
186
+ let coolKey;
187
+ try {
188
+ switch (step.type) {
189
+ case 'navigate': {
190
+ const url = getParam(step, 'url');
191
+ if (url === undefined)
192
+ throw ExecError.stepAction(step.id, 'navigate 缺 params.url');
193
+ await page.navigate(interpolate(url, vars));
194
+ break;
195
+ }
196
+ case 'click': {
197
+ const selectors = getSelectors(step, 'selector', vars);
198
+ if (!selectors)
199
+ throw ExecError.stepAction(step.id, 'click 缺 params.selector');
200
+ const index = parseIndex(step, vars);
201
+ const { hit } = await runSelectorChain(selectors, (sel) => page.click(sel, index), () => true);
202
+ selectorHit = hit;
203
+ break;
204
+ }
205
+ case 'input': {
206
+ const selectors = getSelectors(step, 'selector', vars);
207
+ if (!selectors)
208
+ throw ExecError.stepAction(step.id, 'input 缺 params.selector');
209
+ const raw = getParam(step, 'value');
210
+ const value = interpolate(raw ?? '', vars);
211
+ // 记录掩码值(供执行记录落盘;明文不落盘)
212
+ maskedValue = maskInputValue(value);
213
+ const { hit } = await runSelectorChain(selectors, (sel) => page.input(sel, value), () => true);
214
+ selectorHit = hit;
215
+ break;
216
+ }
217
+ case 'extract': {
218
+ const selectors = getSelectors(step, 'selector', vars);
219
+ if (!selectors)
220
+ throw ExecError.stepAction(step.id, 'extract 缺 params.selector');
221
+ const field = typeof step.params.field === 'string' ? step.params.field : undefined;
222
+ const save = step.params.save === true;
223
+ const { value, hit } = await runSelectorChain(selectors, (sel) => page.extract(sel), (v) => v.count > 0);
224
+ selectorHit = hit;
225
+ const runId = opts?.runId ?? 'r_local';
226
+ if (save && opts?.sink) {
227
+ opts.sink.saveExtracted(runId, step.id, field, value.content);
228
+ }
229
+ extractInfo = { content: value.content, count: value.count, field, saved: save && !!opts?.sink };
230
+ break;
231
+ }
232
+ case 'next_page': {
233
+ const more = await page.nextPage();
234
+ if (!more)
235
+ throw ExecError.stepAction(step.id, '无下一页');
236
+ break;
237
+ }
238
+ case 'loop': {
239
+ // loop 本身不产生独立失败记录(子步骤各自记录;Rust 语义一致)。
240
+ // 子步骤失败 → 直接上抛(loopChildFailed 置位,跳过本步失败记录)。
241
+ try {
242
+ await runLoop(ctx, step);
243
+ }
244
+ catch (e) {
245
+ loopChildFailed = true;
246
+ throw e;
247
+ }
248
+ break;
249
+ }
250
+ case 'wait': {
251
+ // 任务内冷却(防封铁律):wait 支持固定 ms 或 coolMs 区间随机;coolKey 锚点(D-C1 M5 接通)
252
+ const ms = typeof step.params.ms === 'number' ? step.params.ms : undefined;
253
+ const cool = Array.isArray(step.params.coolMs) ? step.params.coolMs : undefined;
254
+ let coolMs;
255
+ if (ms !== undefined) {
256
+ coolMs = ms;
257
+ }
258
+ else if (cool) {
259
+ const min = typeof cool[0] === 'number' ? cool[0] : COOLDOWN_MIN_SECS * 1000;
260
+ const max = typeof cool[1] === 'number' ? cool[1] : COOLDOWN_MAX_SECS * 1000;
261
+ const [lo, hi] = [Math.min(min, max), Math.max(min, max)];
262
+ coolMs = lo + Math.floor(XorShift32.timeSeeded().next() * (hi - lo + 1));
263
+ }
264
+ else {
265
+ coolMs = 1000;
266
+ }
267
+ await page.waitMs(coolMs);
268
+ // D-C1:coolKey 冷却锚点(记账在 server 层 run 结束后;key=flow#step#coolKey)
269
+ coolKey = getParam(step, 'coolKey');
270
+ break;
271
+ }
272
+ case 'finalize': {
273
+ await page.finalize();
274
+ break;
275
+ }
276
+ default: {
277
+ throw ExecError.unknownStep(step.type);
278
+ }
279
+ }
280
+ }
281
+ catch (e) {
282
+ actionError = e instanceof ExecError ? e : ExecError.page(e instanceof Error ? e.message : String(e));
283
+ // 链失败时记录最后尝试项(D-S2)
284
+ const lastTried = e.lastTried;
285
+ if (lastTried !== undefined)
286
+ selectorHit = lastTried;
287
+ }
288
+ if (actionError) {
289
+ // loop 子步骤失败:子步骤已记录,loop 步骤本身不 push(避免重复失败记录)
290
+ if (!loopChildFailed) {
291
+ results.push({
292
+ stepId: step.id,
293
+ kind: step.type,
294
+ status: 'failed',
295
+ error: actionError.message,
296
+ extracted: extractInfo?.content,
297
+ field: extractInfo?.field,
298
+ saved: extractInfo?.saved,
299
+ count: extractInfo?.count,
300
+ selectorHit,
301
+ verify: undefined,
302
+ durationMs: elapsed(t0),
303
+ inputValueMasked: maskedValue,
304
+ cooldownKey: coolKey,
305
+ });
306
+ }
307
+ throw actionError;
308
+ }
309
+ // 验证点检查(失败也 push 一条 failed 记录)
310
+ let verifyOut;
311
+ if (step.verify) {
312
+ const vt0 = performance.now();
313
+ try {
314
+ verifyOut = await checkVerify(page, step.id, step.verify, vars);
315
+ }
316
+ catch (e) {
317
+ const verr = e instanceof ExecError ? e : ExecError.page(String(e));
318
+ results.push({
319
+ stepId: step.id,
320
+ kind: step.type,
321
+ status: 'failed',
322
+ error: verr.message,
323
+ extracted: extractInfo?.content,
324
+ field: extractInfo?.field,
325
+ saved: extractInfo?.saved,
326
+ count: extractInfo?.count,
327
+ selectorHit,
328
+ verify: { passed: false, durationMs: elapsed(vt0) },
329
+ durationMs: elapsed(t0),
330
+ inputValueMasked: maskedValue,
331
+ cooldownKey: coolKey,
332
+ });
333
+ throw verr;
334
+ }
335
+ }
336
+ results.push({
337
+ stepId: step.id,
338
+ kind: step.type,
339
+ status: 'done',
340
+ error: undefined,
341
+ extracted: extractInfo?.content,
342
+ field: extractInfo?.field,
343
+ saved: extractInfo?.saved,
344
+ count: extractInfo?.count,
345
+ selectorHit,
346
+ verify: verifyOut,
347
+ durationMs: elapsed(t0),
348
+ inputValueMasked: maskedValue,
349
+ cooldownKey: coolKey,
350
+ });
351
+ }
352
+ /**
353
+ * loop 循环(D-L1~D-L4):i 从 0 起注入变量上下文;依次执行全部子步骤;
354
+ * click 索引越界(category=index_out_of_range)→ 列表耗尽,循环正常结束(移除越界
355
+ * failed 子记录,记 loop done);其它失败 → 上抛中止;i 达 maxIterations(默认 50)→ 正常结束。
356
+ */
357
+ async function runLoop(ctx, step) {
358
+ const subs = parseSubSteps(step);
359
+ const maxIters = getMaxIterations(step);
360
+ for (let i = 0; i < maxIters; i++) {
361
+ const loopVars = new Map(ctx.vars);
362
+ loopVars.set('i', String(i));
363
+ for (const sub of subs) {
364
+ try {
365
+ await runStep({ ...ctx, vars: loopVars }, sub);
366
+ }
367
+ catch (e) {
368
+ if (e instanceof ExecError && e.category === 'index_out_of_range') {
369
+ // 索引越界 = 列表耗尽:移除刚 push 的越界 failed 子记录(终止信号非失败),循环正常结束
370
+ ctx.results.pop();
371
+ return;
372
+ }
373
+ throw e;
374
+ }
375
+ }
376
+ }
377
+ }
378
+ // ---- 流程执行 ----
379
+ /**
380
+ * 执行整个流程(失败即中止)。等价 Rust `run_flow`(全 async)。
381
+ * vars 接受 Map 或 Record({keyword} / {i} 等插值来源)。
382
+ */
383
+ export async function runFlow(flow, page, vars, opts) {
384
+ const results = [];
385
+ const varMap = vars instanceof Map ? vars : new Map(Object.entries(vars));
386
+ let err;
387
+ const ctx = { flowId: flow.id, page, vars: varMap, results, opts };
388
+ for (const step of flow.steps) {
389
+ try {
390
+ await runStep(ctx, step);
391
+ }
392
+ catch (e) {
393
+ err = e instanceof Error ? e.message : String(e);
394
+ break;
395
+ }
396
+ }
397
+ return { flowId: flow.id, status: err ? 'failed' : 'done', error: err, steps: results };
398
+ }
399
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ import { maskKeywordInText, maskKeywords, maskInputValue, maskUrl, PLACEHOLDER_COMPANY, PLACEHOLDER_KEYWORD, PLACEHOLDER_PERSON, PLACEHOLDER_JOB } from './mask.js';
2
+ import type { RunRecord } from './record.js';
3
+ import { type LedgerState } from './storage.js';
4
+ /**
5
+ * 脱敏导出 + 观察包 + 本地模拟平台(移植自 Rust `export.rs` + A2 失败类型学 + D-N 编号元素)。
6
+ *
7
+ * 双通道(ARCHITECTURE #6):
8
+ * - **统计通道**(对外默认契约):聚合指标(成功率/选择器命中率/关键词精准率),
9
+ * 绝无单条明细;最小样本门槛(<5 不上传);标识符清洗(<company>/<keyword>/<person>/<job>)。
10
+ * - **观察通道**(开发期默认全开):run.json + DOM 快照 + manifest。
11
+ *
12
+ * A2 失败类型学(EXECUTION-SPEC 第五节):公共失败分类 7 类 ——
13
+ * redirect / verify / selector_miss / timeout / network / parse / unknown。
14
+ * `classifyError` 是统计通道 failure_modes 与 L2 学习信号的公共分类;executor 错误产生处
15
+ * 标注 category(D-F3),本模块的 classifyError 按 D-F2 映射表兜底分类(错误文案级)。
16
+ *
17
+ * D-N 编号元素(EXECUTION-SPEC 第六节):DomSnapshot 含 textSummary + elements(el#N)。
18
+ * 真实浏览器模式 run 后自动 snapshot_dom(D-N1),export_observation 优先用快照(D-N2)。
19
+ */
20
+ export { maskInputValue, maskKeywordInText, maskKeywords, maskUrl, PLACEHOLDER_COMPANY, PLACEHOLDER_KEYWORD, PLACEHOLDER_PERSON, PLACEHOLDER_JOB };
21
+ /** 最小样本门槛:样本 < 此值不上传(与 L2 成熟度门槛 <5 同构) */
22
+ export declare const MIN_SAMPLE_THRESHOLD = 5;
23
+ /** 引擎版本(manifest 用;迁移期标注 TS 版) */
24
+ export declare const ENGINE_VERSION = "0.1.0-ts";
25
+ export type FailureCategory = 'redirect' | 'verify' | 'selector_miss' | 'timeout' | 'network' | 'parse' | 'unknown';
26
+ export declare const FAILURE_CATEGORIES: readonly FailureCategory[];
27
+ /**
28
+ * 失败分类(D-F2 映射表):错误 → 类别。
29
+ * - 错误对象带 category(executor 标注)→ 直接用(优先)
30
+ * - 否则按错误消息关键词映射:
31
+ * 含「超时」/ timeout → timeout
32
+ * 含「选择器未命中」「点击目标不存在」「等待选择器…超时」(选择器层)→ selector_miss
33
+ * 网络/连接/econn → network
34
+ * 解析/parse/json → parse
35
+ * 登录态/重定向/未登录 → redirect
36
+ * 含「验证失败」/ 页面文本不含 → verify
37
+ * 其他 → unknown
38
+ */
39
+ export declare function classifyError(e: unknown): FailureCategory;
40
+ /** 失败模式(统计通道;聚合,无明细/无标识符) */
41
+ export interface FailureMode {
42
+ stepType: string;
43
+ verifyType: string;
44
+ /** 失败类别(A2 公共分类) */
45
+ errorCategory: string;
46
+ count: number;
47
+ }
48
+ /** 统计通道:聚合指标(对外默认契约) */
49
+ export interface StatsBundle {
50
+ /** 统计样本数(< MIN_SAMPLE_THRESHOLD 时不上传) */
51
+ sampleCount: number;
52
+ successRate: number;
53
+ selectorHitRate: number;
54
+ keywordPrecisionRate: number;
55
+ avgDurationMs: number;
56
+ /** 失败模式(步骤类型 + verify 类型 + 失败类别,无标识符) */
57
+ failureModes: FailureMode[];
58
+ }
59
+ /**
60
+ * 聚合执行记录。records 为空返回 undefined(无样本)。
61
+ * 失败类别用 A2 classifyError(替代 Rust 私有 categorize_error;公共分类)。
62
+ */
63
+ export declare function buildStats(records: RunRecord[]): StatsBundle | undefined;
64
+ /** 编号元素(el#N + 类型 + 文本摘要) */
65
+ export interface NumberedElement {
66
+ index: number;
67
+ tag: string;
68
+ text: string;
69
+ }
70
+ /** 观察通道:文本快照摘要 + 编号元素(DOM 信息口径,不存选择器/XPath 全量) */
71
+ export interface DomSnapshot {
72
+ /** 页面文本摘要(截断;长文本取前后若干字符) */
73
+ textSummary: string;
74
+ /** 编号交互元素(el#N + 文本摘要,N 为页面交互元素序号) */
75
+ elements: NumberedElement[];
76
+ /** 生成时间(ISO) */
77
+ capturedAt: string;
78
+ }
79
+ /** 生成文本快照摘要(脱敏:截断) */
80
+ export declare function textSummary(text: string): string;
81
+ /** 生成编号元素(交互元素按文档序编号;文本截断 ≤40 字符) */
82
+ export declare function snapshotFromWeb(text: string, rawElements: Array<[string, string]>): DomSnapshot;
83
+ /** 从纯文本生成快照(无编号元素;mock 页面用) */
84
+ export declare function snapshotFromText(text: string): DomSnapshot;
85
+ /** manifest(观察报告包元信息) */
86
+ export interface Manifest {
87
+ engineVersion: string;
88
+ flowVersion: number;
89
+ sourceHash: string;
90
+ createdAt: string;
91
+ }
92
+ /** 观察报告包(observations/<flow_id>_v<version>_<run_id>/ 下的内容;对齐 md-forge 契约) */
93
+ export interface ExportBundle {
94
+ flowId: string;
95
+ flowVersion: number;
96
+ runId: string;
97
+ /** 统计通道(聚合;样本 < 门槛时为 undefined) */
98
+ stats?: StatsBundle;
99
+ /** 观察通道:DOM 快照摘要(文本 + 编号元素;必选) */
100
+ domSnapshot: DomSnapshot;
101
+ /** 观察通道:run.json 内容 */
102
+ run: RunRecord;
103
+ /** manifest:引擎版本/流程版本/来源哈希/时间 */
104
+ manifest: Manifest;
105
+ }
106
+ /** 极简哈希(FNV-1a 64 位,与 Rust simple_hash 同算法,UTF-8 字节):用于 source_hash */
107
+ export declare function simpleHash(s: string): string;
108
+ /** 从一次执行构建观察报告包(run + 可选 DOM 快照 + 统计通道聚合)。 */
109
+ export declare function buildObservation(rec: RunRecord, allRuns: RunRecord[], domText?: string, domSnapshot?: DomSnapshot): ExportBundle;
110
+ /** 本地模拟平台:把观察报告包落盘到 outbox 目录,并维护上传台账状态机。 */
111
+ export declare class LocalPlatform {
112
+ readonly root: string;
113
+ private readonly store;
114
+ constructor(root: string);
115
+ /** 观察包目录:observations/<flow_id>_v<version>_<run_id>/ */
116
+ obsDir(flowId: string, version: number, runId: string): string;
117
+ /**
118
+ * 组装并「上传」观察包(本地模拟平台):先落盘 run(登记台账 Pending),
119
+ * 再落包 + 标记 Uploaded。allRuns 为流程历史记录(统计通道聚合),
120
+ * domText 为页面文本快照,domSnapshot 为已采集快照(D-N2 优先用)。
121
+ * 返回包目录路径。
122
+ */
123
+ deliver(rec: RunRecord, allRuns: RunRecord[], domText?: string, domSnapshot?: DomSnapshot): string;
124
+ /** 待上传 run_id(台账 Pending/Failed,断网重试入口) */
125
+ pending(): string[];
126
+ /** 台账状态查询(诊断用) */
127
+ ledgerState(runId: string): LedgerState | undefined;
128
+ }