Cadeno
Registratore di flussi browser · Chrome MV3

L'hai mostrato una volta.
Perché lo stai ancora facendo?

Skill Recorder è un'estensione Chrome che ti guarda eseguire un compito nel browser una volta — poi scrive un SKILL.md, una specifica in markdown puro che Claude Code (o qualsiasi agente sulla CLI browse) riproduce senza selettori, glue code o supervisione.

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}}
↑ un flusso di ordine d'acquisto di cinque minuti,
registrato una volta e riprodotto per sempre.
Anatomia

Tre fasi, a un clic di distanza.

Quello che spediamo è una piccola estensione Chrome MV3 e una pipeline di distillazione da 4 KB. Il registratore aggancia chrome.debugger per fedeltà a livello DOM; la distillazione gira interamente nel service worker; la riproduzione legge il SKILL.md risultante tramite la CLI browse. Nessun server. Nessun glue code.

i.

Cattura

Pannello laterale
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

Una porta per frame nel content script inoltra ogni evento DOM al service worker. Shadow DOM e iframe della stessa origine vengono attraversati in modo trasparente.

  • Risolutore di selettori a 6 livelli (testid → id → aria → text → css → xpath)
  • tabPorts: Map<tabId, Map<frameId, Port>>
  • Buffer di input consapevole dell'IME · paste · drag
23 eventi →
ii.

Distilla

Service worker · 30 s
✓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

Sei piccole passate trasformano un log rumoroso di eventi in una specifica deterministica. L'auto-parametrizzazione si attiva solo sopra 0,7 di confidenza; sotto, il registratore chiede invece di indovinare.

  • paramConfidence(step) — scala euristica
  • rilevamento auth-boundary — token opaco + cookie
  • UUID · ID numerico · email · data ISO · valuta
SKILL.md →
iii.

Riproduci

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

La CLI browse legge SKILL.md come markdown puro — nessuno schema, nessun runtime, nessuna scappatoia. Ogni passo è verificabile.

  • ri-esecuzioni idempotenti · pausa + ripresa auth
  • log strutturati ↦ cronologia JSONL
  • funziona con Claude Code, Cline, shell semplice
Specifica

Cosa sopravvive a una registrazione? Tredici casi duri, end-to-end.

Il browser è pieno di trappole per i registratori — classi hashate, modali pigre, Shadow DOM, flussi multi-tab, composizione IME, drag-and-drop. Ogni riga sotto è una fixture reale nel playground; clicca su una qualunque per registrare tu stesso.

punto verde = spedito · blu = automatico
CategoriaTecnicaCosa facciamo al riguardoFixture
Selettori
Rotazione hash di classe e ID

Le classi stile Tailwind come btn__primary--ab3f9c ruotano ad ogni deploy; il resolver attraversa 6 livelli (testid → id → aria → text → css → xpath), così un pulsante ri-hashato colpisce comunque.

A2 →
Selettori
Righe fratelle identiche

Sei righe con pulsanti "Pick" letteralmente identici — solo la posizione distingue. Ancoriamo ogni clic con fingerprintIndex, così viene cliccata la riga giusta anche dopo il riordino.

A3 →
Selettori
Identificatori stabili al locale

"Continue" / "继续" / "Weiter" mappano tutti sullo stesso data-i18n-key="action.continue". Il registratore preferisce attributi indipendenti dal locale, così uno skill registrato in inglese viene riprodotto in cinese.

A4 →
Async
Transizioni di rotta SPA

Le transizioni pushState e hashchange sono tracciate senza reload; la riproduzione attende il mount del nuovo contenuto invece di sondare un contenitore vuoto.

B1 →
Async
Modali montate tardi

Il pulsante Confirm non esiste quando viene cliccato il trigger. elementVisible interroga finché il target compare prima di inviare il passo successivo — niente timeout fragili.

B3 →
Superfici
iframe stessa origine

all_frames: true inietta per frame; le azioni sono etichettate con la frameId di origine, poi ri-risolte per URL tra rerendering, così una frameId stantia non blocca mai la riproduzione.

C1 →
Superfici
Mascheramento campi sensibili

Gli input password / phone / carta / SSN vengono rilevati da type + autocomplete + name e sostituiti con *** prima di toccare lo storage. I byte non lasciano mai la pagina.

C2 →
Superfici
Perforazione Shadow DOM

Un tipo di selettore shadow personalizzato codifica il percorso come segmenti { host, inner }; il resolver cammina shadowRoot.querySelector ad ogni confine, così i Web Components sono cittadini di prima classe.

C3 →
Superfici
Handoff tra tab

Quando un flusso apre una nuova tab — anteprima di stampa, OAuth, generazione preventivo — la registrazione segue via chrome.tabs.onCreated. La riproduzione ricrea la tab via chrome.tabs.create.

C4 →
Input
Drag & drop nativo

Una catena dragstart → dragover → drop con DataTransfer condiviso si fonde in un passo drag (sorgente + destinazione + tipi osservati). Niente coordinate di pixel fragili.

D1 →
Input
Combinazioni di modificatori

Una "k" da sola è rumore di input testuale; con metaKey: true è una scorciatoia Cmd-K. Il registratore tiene il combo, scarta il rumore, preserva lo stato del modificatore per la riproduzione.

D3 →
Input
Blocchi contenteditable

change non scatta mai su contenteditable. Agganciamo input + compositionend, debounce 300 ms, emettiamo un passo change con l'innerText finale — stessa forma di un campo testo.

D4 →
Input
Combobox ARIA e typeahead

Ogni passo di clic è arricchito con comboboxContext (testo opzione, selettore radice); se il clic diretto fallisce in riproduzione, il fallback digita il testo, ArrowDown finché aria-activedescendant combacia, poi Enter.

D6 →

Tredici su sedici. Più quattro fixture composite — Notion, Linear, Jira, Salesforce — che concatenano da dodici a quindici di queste tecniche in un singolo flusso coerente. Vedi il playground →

Esempio elaborato

Un rituale browser di cinque minuti, distillato in trenta secondi.

Taccuino sul campoRegistrato 2026-02-19, 16:42 UTCRiprodotto 50× senza intervento

Ogni lunedì mattina un'ingegnera operativa di un piccolo fornitore apre lo stesso portale, clicca Nuovo ordine d'acquisto, incolla un SKU da un CSV, digita una quantità e clicca Invia. Poi rifà tutto. E di nuovo. Duecento righe a settimana, ogni settimana, da quattordici mesi. È un rituale di cinque minuti ripetuto finché il foglio non finisce.

È esattamente il tipo di compito a cui viene proposto un registratore — e esattamente il tipo su cui la maggior parte dei registratori inciampa. Il portale ruota gli hash delle classi Tailwind a ogni deploy. Il pulsante Invia vive dentro una riga di tabella dinamica che si rirende dopo ogni salvataggio. Il cookie di auth scade a mezzogiorno. Gli script Selenium contro questa pagina sopravvivono in media due settimane, poi iniziano silenziosamente a rompersi.

La registrazione

L'ingegnera fissa l'estensione alla barra degli strumenti, apre il portale, clicca Avvia registrazione e svolge il compito esattamente una volta. Otto clic, due valori digitati, un invio. Il pannello laterale mostra un feed in diretta degli eventi — rumore incluso: scroll, focus, blur, mousemove accidentali sull'icona di aiuto. Ventitré eventi catturati in 4,6 secondi.

raw events · 23trascorsi 4,6 s
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)
Il log grezzo conserva tutto; la distillazione decide cosa conta.

La distillazione

main.example.p4

before / after23 eventi → 4 passi
— 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
Otto tasti diventano un fill parametrizzato — stessa forma ad ogni riproduzione.

Il passaggio di consegne

L'ingegnera mette il markdown risultante in ~/.claude/skills/create-purchase-order/SKILL.md e scrive una sola frase a Claude Code. L'agente trova lo skill per nome, risolve la precondizione (il cookie salvato è valido fino a mezzogiorno), itera sulle cinquanta righe del CSV e fa rapporto. Tre minuti e undici secondi dopo, il lavoro è fatto. Nessuno l'ha guardato girare.

claude code · stdout3 m 11 s · 0 tentativi
> 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
Una frase entra, cinquanta ordini escono. L'agente non ha fatto nemmeno una domanda.
Poscritto
Il costo di un rituale di cinque minuti,
ammortizzato su un anno di lavoro.
4:18min
mediana manuale
3.8sec
mediana agente
~187hrs/yr
recuperate, solo da questo compito
Vuoi vederlo su fixture più dure? Prova il playground →
Procurati il registratore

main.cta.title

Gratis durante la beta aperta. Nessun account, nessun upload, nessuna telemetria. L'intero bundle è 4,5 MB; le registrazioni vivono sulla tua macchina finché non scegli di esportarle.

SKILL.md — un contratto in markdown puro tra umani e agenti.v0.4.1 · Updated 2026-02-19