Cadeno
浏览器流程录制器 · Chrome MV3

你演示过一次。
为什么还在亲手做?

Skill Recorder 是一个 Chrome 扩展,看你走完一次浏览器流程就够了 — 然后写出一份 SKILL.md,这是一份纯 markdown 规约,Claude Code(或任何接入 browse CLI 的 Agent)都能照着回放,不需要选择器、不需要胶水代码、不需要盯着看。

v0.4.14.5 MB bundleMV3 service worker21 fixtures12 locales
~/Downloads/recordings/2026-03-create-po.jsonrecording
RAW EVENTS23 captured · 4.6s elapsed
01navigate "/orders/new" // 304 → 200
02click "button.tabs__new" // data-tab=create
03focus "#sku"
04type "SKU-1029" // 8 keystrokes, 1.2s
05blur "#sku"
06type "50" // into #qty
07click "button.submit" ⚠ inside dynamic list
… 16 more (scroll · focus · mousemove · blur · resize)
distilled in 30s ↓
SKILL.md4 steps · 2 inputs · 1 precondition
01# create-purchase-order
02
03// precondition: signed in to supplier portal
04
05## inputs
06- {{sku}} // auto-detected · 8 chars · alphanumeric
07- {{quantity}} // auto-detected · int · 1–999
08
09## steps
101. navigate "/orders/new"
112. fill "#sku" with {{sku}}
123. fill "#qty" with {{quantity}}
134. click submit row matching {{sku}}
↑ 一段五分钟的采购单流程,
录一次,永久重放。
结构剖析

三阶段,一点击之间。

我们交付的,是一个小巧的 Chrome MV3 扩展加一段 4 KB 的蒸馏管线。录制器接入 chrome.debugger,做到 DOM 级别的保真;蒸馏完全在 service worker 里跑;回放通过 browse CLI 读取 SKILL.md。没有服务器,也没有胶水代码。

i.

捕获

侧边栏
Skill RecorderREC
00:01click nav.Orders
00:02click btn.New
00:04focus #sku
00:05type "SKU-1029"
00:06blur #sku
00:08type "50" → #qty
00:09click btn.Submit

Content script 里有一个 per-frame 端口,把每个 DOM 事件转发给 service worker。Shadow DOM 和同源 iframe 都被透明穿透。

  • 六级选择器解析(testid → id → aria → text → css → xpath)
  • tabPorts: Map<tabId, Map<frameId, Port>>
  • IME 感知输入缓冲 · paste · drag
23 个事件 →
ii.

蒸馏

Service worker · 30 秒
dedupe consecutive clicks23 → 16
fold keystrokes into type()16 → 11
detect inputs as {{params}}conf 0.94
mark auth boundary+1 precondition
parameterize URL segments2 swapped
flag dynamic-list clicks1 ⚠ note

六次小规模处理把嘈杂的事件流变成确定性规约。自动参数化只在置信度 0.7 以上触发;低于这个值,录制器会先问而不是猜。

  • paramConfidence(step) — 启发式阶梯
  • auth-boundary 检测 — opaque token + cookies
  • UUID · 数字 ID · email · ISO 日期 · 货币
SKILL.md →
iii.

回放

browse CLI
~/work $ claude
> create POs for these 50 rows
Reading ~/.claude/skills/create-purchase-order/SKILL.md Loaded 4 steps · 2 params · 1 precondition ▸ resolving precondition: signed in to supplier portal cookie present, expires 2026-08-04 ▸ running batch [50 rows] 50/50 in 3m 11s 0 retries, 0 manual rescues

browse CLI 把 SKILL.md 当作纯 markdown 来读 — 没有 schema、没有运行时、没有逃生口。每一步都可审计

  • 幂等重跑 · 鉴权暂停 + 恢复
  • 结构化日志 ↦ JSONL 重放历史
  • 支持 Claude Code、Cline、纯 shell
技术规格

一次录制能扛住什么?十三个硬骨头,全链路。

浏览器里到处是录制器陷阱 — 哈希类名、懒加载弹窗、Shadow DOM、多标签流程、IME 输入法合成、拖拽。下表每一行都对应演练场里的一个真实场景,点进去就可以亲自录制。

绿点 = 已发布 · 蓝点 = 自动
分类技术我们的处理方式场景
选择器
哈希类名 & ID 轮换

Tailwind 风格的类名(例如 btn__primary--ab3f9c)每次部署都换;解析器走 6 级回退(testid → id → aria → text → css → xpath),换过哈希的按钮照样命中。

A2
选择器
完全相同的兄弟行

六行里都是一模一样的 "Pick" 按钮 — 只有位置不同。我们用 fingerprintIndex 锚定每次点击,即便列表重排,点击的还是对的那行。

A3
选择器
语言无关的标识

"Continue" / "继续" / "Weiter" 都映射到同一个 data-i18n-key="action.continue"。录制器优先使用语言无关属性,所以英文录的 Skill 能在中文页面下回放。

A4
异步
SPA 路由切换

pushState 和 hashchange 都被跟踪,无需 reload;回放会等待新内容挂载,而不是去探一个空容器。

B1
异步
懒加载弹窗

触发那一刻 Confirm 按钮还不存在。elementVisible 会一直轮询,直到目标出现才下发下一步 — 没有靠 timeout 拼。

B3
界面
同源 iframe

all_frames: true 注入每一帧;动作带上来源 frameId,且会在 URL 重渲染时按 URL 重新解析,过期的 frameId 不会卡住回放。

C1
界面
敏感字段脱敏

password / phone / 信用卡 / SSN 输入被 type + autocomplete + name 检测出来,落入存储前替换成 ***。字节永远不离开页面。

C2
界面
Shadow DOM 穿透

自定义的 shadow 选择器把路径编码成 { host, inner } 段;解析器在每个边界走一遍 shadowRoot.querySelector,所以 Web Components 是一等公民。

C3
界面
跨标签流转

当一段流程打开新标签 — 打印预览、OAuth、报价生成 — 录制通过 chrome.tabs.onCreated 跟上。回放通过 chrome.tabs.create 重新打开新标签。

C4
输入
原生拖拽

dragstart → dragover → drop 三件套带共享 DataTransfer,合并成一个 drag 步骤(源 + 目标 + 观察到的类型)。不依赖脆弱的像素坐标。

D1
输入
修饰键组合

孤立的 "k" 是文本输入噪音;加上 metaKey: true 就成了 Cmd-K 快捷键。录制器留下组合键、丢弃噪音,保留修饰状态供回放。

D3
输入
contenteditable 块

contenteditable 上 change 事件永远不触发。我们勾住 input + compositionend,去抖 300 毫秒,以最终 innerText 合成一个 change 步骤 — 和文本框形状一致。

D4
输入
ARIA combobox & 类型提示

每次点击都附上 comboboxContext(选项文本、根选择器);如果回放时直接点击失败,回退会键入文本、按 ArrowDown 直到 aria-activedescendant 匹配,再按 Enter。

D6

十六中的十三个。另外还有四个综合场景 — Notion、Linear、Jira、Salesforce — 把其中十二到十五个技术串成一段完整流程。看演练场 →

实例走读

一次五分钟的浏览器仪式,蒸馏成三十秒。

现场笔记录于 2026-02-19,16:42 UTC重放 50 次零人工干预

每个周一早上,一家小型供应商的运营工程师都打开同一个门户,点新建采购单,从 CSV 里粘一个 SKU、敲一个数量,再点提交。然后再来一遍。一周两百行,一周接一周,已经持续十四个月。这是一个五分钟仪式,重复到表格结束。

这正是常被推销给录制器的那种任务 — 也正是大多数录制器栽跟头的那种任务。供应商门户每次发布都换 Tailwind 哈希类名。提交按钮藏在每次保存就重渲染的动态表格行里。鉴权 cookie 中午就过期。基于这个页面写的 Selenium 脚本平均能撑两周,然后开始悄悄失败。

录制

工程师把扩展钉到工具栏,打开门户,点开始录制,原原本本做一遍。八次点击、两个填值、一次提交。侧边栏显示事件实时流 — 包括噪音:滚动、focus、blur、不小心划过帮助图标的鼠标。4.6 秒里录到 23 个事件。

raw events · 23用时 4.6 秒
01 navigate "/orders/new" // 304 → 200 02 click "button.tabs__new" // data-tab=create 03 focus "#sku" 04 type "SKU-1029" // 8 keystrokes 05 blur "#sku" 06 focus "#qty" 07 type "50" 08 click "button.submit" inside .row[data-id=r9]16 more (scroll · focus · mousemove · blur · resize)
原始日志保留一切;蒸馏负责决定什么重要。

蒸馏

main.example.p4

before / after23 个事件 → 4 步
— BEFORE (raw)
type "S" → #sku
type "K" → #sku
type "U" → #sku
type "-" → #sku
type "1" → #sku
type "0" → #sku
type "2" → #sku
type "9" → #sku
+ AFTER (distilled)
fill "#sku" with {{sku}}
+ AUTO-DETECTED
// 8 chars · alphanumeric · prefix SKU-
// confidence 0.94
八次按键变成一个带参数的 fill — 每次回放都是同一个形状。

交接

工程师把生成的 markdown 放到 ~/.claude/skills/create-purchase-order/SKILL.md,给 Claude Code 敲了一句话。Agent 按名字找到这个 Skill,解出前置条件(存的 cookie 中午前都还有效),遍历 CSV 里五十行,回头汇报。三分十一秒后,事儿就办完了。没人盯着它跑。

claude code · stdout3 分 11 秒 · 零重试
> create purchase orders for the rows in ~/Desktop/feb-orders.csv Reading ~/.claude/skills/create-purchase-order/SKILL.md 4 steps · 2 params · 1 precondition Resolving precondition: signed in to supplier portal cookie present (expires 2026-02-19 12:00 UTC) Running batch (50 rows) 50/50 submitted 0 retries · 0 manual rescues median 3.8s per row · longest 5.1s
一句话进,五十张采购单出。Agent 一个问题都没问。
后记
一段五分钟仪式的成本,
摊平到一个工作年里。
4:18min
人工平均耗时
3.8sec
Agent 平均耗时
~187hrs/yr
仅此一项每年节省
想看更难的场景?试试演练场 →
拿到录制器

录一次流程。下面的一千次让 Agent 跑。

公开 beta 期间免费。不需要账号、不上传、不发送遥测。整个 bundle 4.5 MB;录制留在你机器上,你要导出才会动。

SKILL.md — 人和 Agent 之间的纯 markdown 契约。v0.4.1 · Updated 2026-02-19