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、沒有 runtime、沒有逃生口。每一步都可稽核

  • 冪等重跑 · 鑑權暫停 + 恢復
  • 結構化日誌 ↦ 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 注入每一個 frame;動作帶上來源 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