feat(record): capture Trace v3 states after pages settle - #103
Draft
shnpd wants to merge 1 commit into
Draft
Conversation
shnpd
requested review from
Ljy-0827 and
iuyo5678
and
a lite review from Copilot
August 18, 2026 06:50
There was a problem hiding this comment.
Pull request overview
This PR lays down the Trace v3 recording-side observation pipeline in the extension (page settle → capture VOM observation → target geometry matching → v3 reduction → TraceV3 build), while keeping the current default recorder export on Trace v2 by splitting out the v2 reducer.
Changes:
- Add page “settle” detection via an injected
MutationObserverprobe (waitForPageSettled) and centralize recording constants (settle budgets, hashing, id generation, defaults). - Introduce observation/state registry + target matching utilities (
record-observation.ts,match-target.ts,format-observation-file.ts) to capture and dedupe states and attach step annotations. - Split Trace v2 reduction into
trace-reducer-v2.tsand switchrecord.tstobuildTraceV2, while evolving the existingtrace-reducer.tsinto a Trace v3 reducer that emits state-linked steps.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/extension/src/transport/types.ts | Expand draft step payloads with v3 fields (state ids, geometry, captureTarget) and add v3 types. |
| apps/extension/src/tools/vom/capture.ts | Add documentRect and derive viewport localRect from document coordinates for robust matching after scroll. |
| apps/extension/src/tools/vom/tests/capture.test.ts | Update tests to validate documentRect preservation and derived viewport rects. |
| apps/extension/src/tools/record.ts | Keep default recording output on v2 by switching to buildTraceV2. |
| apps/extension/src/lib/trace-reducer.ts | Implement v3 reducer producing states[] + steps[] with state/result references and redirect collapsing semantics. |
| apps/extension/src/lib/trace-reducer-v2.ts | New v2-only reducer extracted to preserve legacy output behavior. |
| apps/extension/src/lib/record-observation.ts | New observation pipeline: throttled capture, state dedupe, settle queueing, redirect coalescing, annotation + TraceV3 builder. |
| apps/extension/src/lib/record-constants.ts | New centralized constants + FNV-1a hash + state id generator + navigation cause mapping defaults. |
| apps/extension/src/lib/page-settled.ts | New “settle” implementation based on DOM quiet probing and readyState polling. |
| apps/extension/src/lib/match-target.ts | New geometry-based matching from content-script capture to VOM refs (viewport vs document coordinates). |
| apps/extension/src/lib/format-observation-file.ts | New observation file serialization (front matter + inline step annotations). |
| apps/extension/src/lib/describe-target.ts | Rename content-script descriptor to CaptureTargetDescriptor (keep deprecated alias). |
| apps/extension/src/lib/tests/trace-reducer.test.ts | Update tests to validate v3 reducer semantics (states, redirects, step id mapping). |
| apps/extension/src/lib/tests/trace-reducer-v2.test.ts | New tests to validate extracted v2 reducer behavior. |
| apps/extension/src/lib/tests/record-observation.test.ts | New tests covering annotation redaction behavior, target matching fallback, redirect coalescing. |
| apps/extension/src/lib/tests/page-settled.test.ts | New tests for settle floor and cancellation behavior. |
| apps/extension/src/lib/tests/match-target.test.ts | New tests for geometry matching and fallback/unmatched rules. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Wait for DOM quiet after actions, match targets to VOM refs, and reduce drafts into deduped state-linked Trace v3 while keeping the v2 reducer. Co-authored-by: Cursor <cursoragent@cursor.com>
shnpd
force-pushed
the
feat/record-settled-states
branch
from
August 18, 2026 07:36
e7a4b48 to
1afd217
Compare
shnpd
marked this pull request as draft
August 18, 2026 08:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
本 PR 基于
feat/trace-v3-protocol(PR #101),落地 Trace v3 录制侧的完整 observation 库,覆盖:refbuildTraceV3CaptureGeometry、documentRect等)尚未把线上
record工具完整切到 Trace v3 产出。record.ts结束录制时仍走buildTraceV2;本改动先搭好管线(settle → observe → 几何匹配 → reduce →buildTraceV3),后续再接线。动机
固定延时既不适合一帧内出现的弹窗,也不适合慢路由。本方案改为:页面 DOM 安静后再拍 observation,并把点击/填写等目标通过 几何信息 对齐到该 observation 中的 VOM ref,使 Trace v3 同时描述「做了什么」和「在哪个控件 / 哪个页面状态上做的」。
Trace v3 形态:
states[]— 去重后的页面观察(s1、s2、…)steps[]— 每步绑定state(操作前)与result.state(操作后),目标优先带 VOMref架构 / 数据流
改动清单(本 PR 全部内容)
1. 页面 settle —
page-settled.ts+record-constants.tsidleMs+readyState150ms,安静250ms,最长2s,轮询60msquiet/timeout/cancelledsNid、导航 cause 映射、fill 默认commit=blur、几何容差2px2. Observation 管线 —
record-observation.tscreateObservationState:state registry、settle 队列、redirect 合并状态、注解表captureAndRegisterObservation:节流捕获、VOM 获取、state 去重注册、更新lastSettledapplyTargetMatching:几何匹配入口;无 settled 观察时保留 capture 语义,不写成空 unmatched;若上一动作仍在 settle 且新控件匹配失败,不绑定陈旧 origin statescheduleDraftSettle/flushPendingSettles/cancelPendingSettles:串行 settle、可被更新动作取消scheduleRedirectLandingFlush/flushPendingRedirectLanding(中间跳只更新 URL + generation)inferMissingPostStates、settleUnsettledDraftsbuildTraceV3:reduce → 只发布被引用的 states → 重编号s1..sN→ 写入带注解的 state body3. 几何匹配(本 PR 核心能力之一)
3.1
match-target.ts用 content script 上报的
CaptureGeometry,在最近一次 settled observation 的CapturedNode[]+RenderedRef[]中定位控件:ownerFrameBackendNodeId必须一致GEOM_MATCH_TOLERANCE_PX = 2documentRect→ 文档坐标(rect + scroll↔documentRect);否则 → 视口坐标(localRect/rect)unmatched{ ref, role?, name?, ctx? }(从 VOM refs 取)fallbackDescriptor:尽量保留 capture 的role/name,并标unmatched: true3.2 Capture 侧几何数据 —
vom/capture.tsCapturedNode新增documentRect(DOMSnapshot 文档坐标)localRect由documentRect - scroll得到,供视口匹配使用3.3 描述符分层 —
describe-target.tsCaptureTargetDescriptor(操作瞬间的 role/name/tag…)TargetDescriptorV3(可带ref/unmatched)分离TargetDescriptor别名,兼容迁移期4. Observation 文件 —
format-observation-file.ts# bsk-observation 1front matter + VOM bodysteps_here与行内注解(如⟵ step 3: fill: "...")5. Trace v3 reducer —
trace-reducer.tsregisterObservation/stateDedupKey(fnv1a64(body):url)StepV3(state/result.state;navigatecause;fillcommit)stepIdByDraftId,供注解 /steps_here重映射resolveTraceStartUrl6. Trace v2 拆分 —
trace-reducer-v2.ts+record.tstrace-reducer-v2.ts(buildTraceV2)record.ts当前仍调用buildTraceV2,默认录制路径不回归buildTraceV37. 协议类型 —
transport/types.ts新增/扩展:
CaptureGeometry(rect / scrollX/Y / position / tag / ownerFrameBackendNodeId)TargetDescriptorV3(ref / role / name / ctx / unmatched)DraftTraceStep增加:captureTarget、geometry、preStateId、postStateId、observation 元数据、navigate transition 元数据、fillcommit等TraceState/StepV3/TraceV3/RecordedTrace等 v3 wire 形状(与协议 PR 对齐、供本库使用)8. 测试
match-target.test.tspage-settled.test.tsrecord-observation.test.tstrace-reducer.test.tstrace-reducer-v2.test.tsvom/capture.test.tsdocumentRect/ 录制复用相关 capture建议命令:
pnpm --filter @browser-skill/extension exec vitest run \ src/lib/__tests__/page-settled.test.ts \ src/lib/__tests__/match-target.test.ts \ src/lib/__tests__/record-observation.test.ts \ src/lib/__tests__/trace-reducer.test.ts \ src/lib/__tests__/trace-reducer-v2.test.ts \ src/tools/vom/__tests__/capture.test.ts pnpm --filter @browser-skill/extension compile兼容性 / 非目标
trace_version=3协商(协议 PR)record.tsReview 关注点
documentRect从 DOMSnapshot 推导是否覆盖 iframe / 变换场景?pre ?? post兜底相对丢步是否可接受?buildTraceV3是否 OK?