Cadeno
브라우저 플로우 레코더 · Chrome MV3

한 번 시연했잖아요.
왜 아직도 직접 하고 있나요?

Skill Recorder는 브라우저 작업을 한 번 따라가는 모습을 보고 SKILL.md를 써주는 Chrome 확장입니다. 이는 셀렉터, 글루 코드, 감시 없이 Claude Code(또는 browse CLI 위의 모든 에이전트)가 재실행할 수 있는 일반 마크다운 명세입니다.

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}}
↑ 5분짜리 발주서 플로우를
한 번 녹화하면 영원히 재생됩니다.
해부

세 단계, 클릭 한 번 거리.

저희가 출하하는 것은 작은 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

콘텐츠 스크립트의 프레임별 포트가 모든 DOM 이벤트를 service worker로 전달합니다. Shadow DOM과 동일 출처 iframe은 투명하게 관통됩니다.

  • 6단계 셀렉터 해석(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 감지 — 불투명 토큰 + 쿠키
  • 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를 일반 마크다운으로 읽습니다 — 스키마도, 런타임도, 탈출구도 없습니다. 모든 단계가 감사 가능합니다.

  • 멱등 재실행 · 인증 일시정지 + 재개
  • 구조화 로그 ↦ JSONL 재생 이력
  • Claude Code, Cline, 일반 셸과 동작
명세

녹화는 무엇을 견뎌낼까요? 13개의 난제, 엔드 투 엔드.

브라우저는 레코더의 함정으로 가득합니다 — 해시 클래스, 지연 모달, Shadow DOM, 멀티 탭 플로우, IME 합성, 드래그 앤 드롭. 아래 각 행은 플레이그라운드의 실제 픽스처입니다. 클릭하면 직접 녹화해 볼 수 있습니다.

녹색 점 = 출시됨 · 파란색 = 자동
카테고리기술우리의 대처픽스처
셀렉터
해시 클래스 & ID 회전

btn__primary--ab3f9c 같은 Tailwind 스타일 클래스는 배포마다 돌아갑니다. 리졸버는 6단계(testid → id → aria → text → css → xpath)를 거치므로 재해시된 버튼도 명중합니다.

A2
셀렉터
동일한 형제 행

글자 그대로 동일한 "Pick" 버튼이 여섯 행 — 위치로만 구분됩니다. fingerprintIndex로 각 클릭을 고정하므로, 리스트가 재정렬돼도 올바른 행을 클릭합니다.

A3
셀렉터
로케일 무관 식별자

"Continue" / "계속" / "Weiter"는 모두 같은 data-i18n-key="action.continue"에 매핑됩니다. 레코더는 로케일 무관 속성을 우선하므로 영어로 녹화한 스킬이 한국어 페이지에서 재생됩니다.

A4
비동기
SPA 라우트 전환

pushState와 hashchange 전환은 reload 없이 추적됩니다. 재생은 빈 컨테이너를 prob하는 대신 새 콘텐츠가 마운트되기를 기다립니다.

B1
비동기
지연 마운트 모달

트리거가 클릭되는 순간 Confirm 버튼은 존재하지 않습니다. elementVisible은 타겟이 나타날 때까지 폴링한 뒤 다음 단계를 디스패치합니다 — 불안정한 timeout 없음.

B3
표면
동일 출처 iframe

all_frames: true로 프레임별 주입. 액션에는 발생한 frameId가 태그되고, 재렌더링 시 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
입력
네이티브 드래그 & 드롭

공유 DataTransfer가 있는 dragstart → dragover → drop 체인이 한 개의 drag 단계로 합쳐집니다(소스 + 타겟 + 관찰된 타입). 취약한 픽셀 좌표 없음.

D1
입력
수정자 키 콤보

단독 "k"는 텍스트 입력 잡음입니다. metaKey: true가 붙으면 Cmd-K 단축키입니다. 레코더는 콤보를 남기고 잡음은 버리며, 재생을 위해 수정자 상태를 유지합니다.

D3
입력
contenteditable 블록

contenteditable에서 change 이벤트는 결코 발생하지 않습니다. input + compositionend를 후크하고 300 ms로 디바운스해 최종 innerText로 단일 change 단계를 방출합니다 — 텍스트 입력과 같은 모양.

D4
입력
ARIA combobox & 타입어헤드

각 클릭 단계는 comboboxContext(옵션 텍스트, 루트 셀렉터)로 강화됩니다. 재생 시 직접 클릭이 실패하면 텍스트 입력 → aria-activedescendant 일치까지 ArrowDown → Enter로 폴백합니다.

D6

16개 중 13개. 추가로 네 개의 복합 픽스처 — Notion, Linear, Jira, Salesforce — 가 이 기법들 중 12~15개를 하나의 일관된 플로우로 묶습니다. 플레이그라운드 보기 →

사례 연구

5분짜리 브라우저 의식, 30초로 정제.

현장 노트녹화 2026-02-19, 16:42 UTC개입 없이 50회 재생

매주 월요일 아침, 소규모 공급업체의 운영 엔지니어는 같은 포털을 열고 새 발주서를 클릭한 뒤 CSV에서 SKU를 붙여넣고 수량을 타이핑하고 제출을 클릭합니다. 그리고 다시 합니다. 또 다시. 주당 200행, 매주, 14개월째. 스프레드시트가 끝날 때까지 반복되는 5분의 의식입니다.

이것이야말로 레코더가 권유받는 종류의 작업이며, 동시에 대부분의 레코더가 실패하는 종류의 작업입니다. 공급업체 포털은 배포마다 Tailwind 해시 클래스를 회전시킵니다. 제출 버튼은 저장 후 매번 재렌더링되는 동적 표 행 안에 있습니다. 인증 쿠키는 정오에 만료됩니다. 이 페이지를 대상으로 작성한 Selenium 스크립트는 평균 2주를 버틴 뒤 조용히 깨지기 시작합니다.

녹화

엔지니어는 확장을 툴바에 고정하고 포털을 열어 녹화 시작을 클릭한 뒤 작업을 정확히 한 번 수행합니다. 클릭 여덟 번, 입력값 둘, 제출 하나. 사이드 패널이 이벤트 라이브 피드를 보여줍니다 — 잡음 포함: 스크롤, 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이 됩니다 — 재생마다 같은 모양.

인계

엔지니어는 생성된 마크다운을 ~/.claude/skills/create-purchase-order/SKILL.md에 넣고 Claude Code에 한 문장을 입력합니다. 에이전트는 이름으로 스킬을 찾고 전제 조건을 해결하고(저장된 쿠키가 정오까지 유효), CSV의 50행을 반복 처리한 뒤 보고합니다. 3분 11초 뒤 작업 완료. 아무도 지켜보지 않았습니다.

claude code · stdout3분 11초 · 0 재시도
> 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
한 문장 들어가서 발주서 50건 나옵니다. 에이전트는 질문 하나 하지 않았습니다.
후기
5분짜리 의식의 비용,
1년 단위로 환산하면.
4:18min
수동 중위값
3.8sec
에이전트 중위값
~187hrs/yr
이 작업만으로 회수
더 어려운 픽스처에서 보고 싶으세요? 플레이그라운드 시도 →
레코더 받기

main.cta.title

오픈 베타 동안 무료. 계정도, 업로드도, 텔레메트리도 없습니다. 전체 번들 4.5 MB. 녹화는 사용자가 내보내기를 선택할 때까지 사용자의 기기에 머뭅니다.

SKILL.md — 사람과 에이전트 사이의 일반 마크다운 계약.v0.4.1 · Updated 2026-02-19