캡처
사이드 패널콘텐츠 스크립트의 프레임별 포트가 모든 DOM 이벤트를 service worker로 전달합니다. Shadow DOM과 동일 출처 iframe은 투명하게 관통됩니다.
- 6단계 셀렉터 해석(testid → id → aria → text → css → xpath)
- tabPorts: Map<tabId, Map<frameId, Port>>
- IME 인식 입력 버퍼링 · paste · drag
Skill Recorder는 브라우저 작업을 한 번 따라가는 모습을 보고 SKILL.md를 써주는 Chrome 확장입니다. 이는 셀렉터, 글루 코드, 감시 없이 Claude Code(또는 browse CLI 위의 모든 에이전트)가 재실행할 수 있는 일반 마크다운 명세입니다.
저희가 출하하는 것은 작은 Chrome MV3 확장과 4 KB 정제 파이프라인입니다. 레코더는 chrome.debugger에 후크해 DOM 수준의 충실도를 내고, 정제는 service worker 안에서 완결되며, 재생은 browse CLI가 결과 SKILL.md를 읽어들입니다. 서버도, 글루 코드도 없습니다.
콘텐츠 스크립트의 프레임별 포트가 모든 DOM 이벤트를 service worker로 전달합니다. Shadow DOM과 동일 출처 iframe은 투명하게 관통됩니다.
여섯 번의 작은 패스가 잡음 많은 이벤트 로그를 결정적 명세로 바꿉니다. 자동 파라미터화는 신뢰도 0.7 이상에서만 발동되며, 그 아래에서는 추측 대신 묻습니다.
browse CLI는 SKILL.md를 일반 마크다운으로 읽습니다 — 스키마도, 런타임도, 탈출구도 없습니다. 모든 단계가 감사 가능합니다.
브라우저는 레코더의 함정으로 가득합니다 — 해시 클래스, 지연 모달, Shadow DOM, 멀티 탭 플로우, IME 합성, 드래그 앤 드롭. 아래 각 행은 플레이그라운드의 실제 픽스처입니다. 클릭하면 직접 녹화해 볼 수 있습니다.
btn__primary--ab3f9c 같은 Tailwind 스타일 클래스는 배포마다 돌아갑니다. 리졸버는 6단계(testid → id → aria → text → css → xpath)를 거치므로 재해시된 버튼도 명중합니다.
A2 →글자 그대로 동일한 "Pick" 버튼이 여섯 행 — 위치로만 구분됩니다. fingerprintIndex로 각 클릭을 고정하므로, 리스트가 재정렬돼도 올바른 행을 클릭합니다.
A3 →"Continue" / "계속" / "Weiter"는 모두 같은 data-i18n-key="action.continue"에 매핑됩니다. 레코더는 로케일 무관 속성을 우선하므로 영어로 녹화한 스킬이 한국어 페이지에서 재생됩니다.
A4 →pushState와 hashchange 전환은 reload 없이 추적됩니다. 재생은 빈 컨테이너를 prob하는 대신 새 콘텐츠가 마운트되기를 기다립니다.
B1 →트리거가 클릭되는 순간 Confirm 버튼은 존재하지 않습니다. elementVisible은 타겟이 나타날 때까지 폴링한 뒤 다음 단계를 디스패치합니다 — 불안정한 timeout 없음.
B3 →all_frames: true로 프레임별 주입. 액션에는 발생한 frameId가 태그되고, 재렌더링 시 URL로 재해석되므로 오래된 frameId가 재생을 막지 않습니다.
C1 →password / phone / 신용카드 / SSN 입력은 type + autocomplete + name으로 감지되어 저장에 들어가기 전에 ***로 치환됩니다. 바이트는 페이지를 떠나지 않습니다.
C2 →커스텀 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에서 change 이벤트는 결코 발생하지 않습니다. input + compositionend를 후크하고 300 ms로 디바운스해 최종 innerText로 단일 change 단계를 방출합니다 — 텍스트 입력과 같은 모양.
D4 →각 클릭 단계는 comboboxContext(옵션 텍스트, 루트 셀렉터)로 강화됩니다. 재생 시 직접 클릭이 실패하면 텍스트 입력 → aria-activedescendant 일치까지 ArrowDown → Enter로 폴백합니다.
D6 →16개 중 13개. 추가로 네 개의 복합 픽스처 — Notion, Linear, Jira, Salesforce — 가 이 기법들 중 12~15개를 하나의 일관된 플로우로 묶습니다. 플레이그라운드 보기 →
매주 월요일 아침, 소규모 공급업체의 운영 엔지니어는 같은 포털을 열고 새 발주서를 클릭한 뒤 CSV에서 SKU를 붙여넣고 수량을 타이핑하고 제출을 클릭합니다. 그리고 다시 합니다. 또 다시. 주당 200행, 매주, 14개월째. 스프레드시트가 끝날 때까지 반복되는 5분의 의식입니다.
이것이야말로 레코더가 권유받는 종류의 작업이며, 동시에 대부분의 레코더가 실패하는 종류의 작업입니다. 공급업체 포털은 배포마다 Tailwind 해시 클래스를 회전시킵니다. 제출 버튼은 저장 후 매번 재렌더링되는 동적 표 행 안에 있습니다. 인증 쿠키는 정오에 만료됩니다. 이 페이지를 대상으로 작성한 Selenium 스크립트는 평균 2주를 버틴 뒤 조용히 깨지기 시작합니다.
엔지니어는 확장을 툴바에 고정하고 포털을 열어 녹화 시작을 클릭한 뒤 작업을 정확히 한 번 수행합니다. 클릭 여덟 번, 입력값 둘, 제출 하나. 사이드 패널이 이벤트 라이브 피드를 보여줍니다 — 잡음 포함: 스크롤, focus, blur, 도움말 아이콘을 우연히 지나간 마우스무브. 4.6초에 23개 이벤트 캡처.
main.example.p4
엔지니어는 생성된 마크다운을 ~/.claude/skills/create-purchase-order/SKILL.md에 넣고 Claude Code에 한 문장을 입력합니다. 에이전트는 이름으로 스킬을 찾고 전제 조건을 해결하고(저장된 쿠키가 정오까지 유효), CSV의 50행을 반복 처리한 뒤 보고합니다. 3분 11초 뒤 작업 완료. 아무도 지켜보지 않았습니다.
오픈 베타 동안 무료. 계정도, 업로드도, 텔레메트리도 없습니다. 전체 번들 4.5 MB. 녹화는 사용자가 내보내기를 선택할 때까지 사용자의 기기에 머뭅니다.