← All Skills

snappy-libretto

v1.0.0
4 files, 63.8 KB ~3,414 words · 14 min read Updated 2026-09-09

snappy-libretto skill

40 of 45 checks pass
What it can do
record url namewrite-reversible
lessonsread
lesson nameread
replay name args?write
promote name skill verbwrite-reversible
What does not pass yet
$ npx snappy-skills install snappy-libretto
zip ↓
Documents
AGENTS.md

snappy-libretto -- Agent Loader#

Libretto is the person in the browser. It records one headed browser job, turns structural actions plus network calls into a local lesson, then makes that lesson callable with plain fetch.

Decision#

Keep and import snappy-api-sniffer. It already owns request normalization and authenticated fetch replay. Libretto adds the long-running recorder, typed lesson, stale-session refusal, and promotion lifecycle. Do not copy sniffer or browse code.

Flow#

textperson -> record -> ~/snappy/libretto/lessons/<name>/
                  -> lesson review
                  -> replay by plain fetch
                  -> promote into a dedicated snappy-* hand

Verb map#

CLI verb Typed export Effect Result
record <url> <name> recordLesson(url, name, opts?) local write Headed site profile, raw capture, auth state, typed lesson
lessons lessons() read Safe summaries and counts
lesson <name> lesson(name) read Structural steps and endpoint metadata, no secrets or bodies
replay <name> [args] replayLesson(name, args?, opts?) governed write Plain-fetch responses; CLI prints counts only
promote <name> <skill> <verb> promote(name, skill, verb) local write Generated typed hand delegating to Libretto

All verbs support --json. Failures exit non-zero. replay requires --now when any endpoint method is not GET, HEAD, or OPTIONS.

Use#

bashAPI=~/.claude/skills/snappy-libretto/api.ts
npx tsx "$API" record "https://app.example.com/work" review-work
npx tsx "$API" lessons --json
npx tsx "$API" lesson review-work --json
npx tsx "$API" replay review-work '{"field_name":"new value"}' --json
npx tsx "$API" promote review-work snappy-example-work read-work --json
npx tsx "$API" contract

Rules#

  • Runtime artifacts live under ~/snappy/libretto, never in git.
  • Record through snappy-browse; normalize and replay through snappy-api-sniffer; scaffold targets through snappy-skill.
  • Keep structural selectors. Never store or promote [ref=eN] snapshot refs.
  • Password events become fill_secret; never keep their values.
  • Never print auth state, cookies, headers, request bodies, response bodies, or recorded field values. Use lesson for review.
  • Stale auth is a named session_stale refusal. Never add an automatic login or browser fallback.
  • The replay hand contract is write because recordings can contain write methods. The same verb runs after approval with --now.
  • Promotion derives read versus write from captured HTTP methods.
  • Promotion refuses a hand-written target API. Use a dedicated skill instead of splicing two owners together.
  • A recording with no steps and no XHR/fetch calls is refused rather than filed as an empty lesson.

Storage#

text~/snappy/libretto/profiles/<site>/
~/snappy/libretto/lessons/<name>/lesson.json
~/snappy/libretto/lessons/<name>/raw-capture.json
~/snappy/libretto/lessons/<name>/auth-state.json

Directories are 0700; lesson artifacts are 0600. lesson omits sensitive fields. loadLesson is for trusted local code only.

Failure routing#

  • Missing/expired auth or 401/403/login redirect: report session_stale, sign in, record again.
  • No endpoints: browser-only lesson; record the data-producing action or keep the job in snappy-browse.
  • Non-read endpoint without --now: stage through the governed hand and wait for approval.
  • Existing hand-written target: choose a dedicated snappy-* skill.
  • agent-browser permission failure: repair/reinstall the installed binary; do not fork the automation.

Read SKILL.md for selector priority, parameter rewriting, recording limits, privacy boundaries, promotion output, and measured 2026-09-08 product facts.


THE DERIVATION LAW — the installed artifact is the spec (Robert 2026-08-05, LAW)#

For any SDK, dependency, or API: enumerate its REAL surface from the installed package (node_modules/<pkg> — dist, CLI commands, shipped docs) and fetch its llms.txt/llms-full.txt BEFORE writing a line of integration. Import the package's own types; never redeclare a type a dependency exports; never write an integration from memory; never describe a surface you haven't listed. A hand-written parallel of a generated, vendored, or documented definition is a defect (DRY, original sense: one authoritative representation of every piece of knowledge). Writing from training memory instead of the installed source produces hallucinated APIs — the named killer of OpenAI's plugin ecosystem. Printing Press (spec→generated connector) is this law's special case; it applies to EVERYTHING.

Self-correcting loader (PID feedback)#

The system spec lives at ~/.claude/skills/snappy-settings/skill-spec.md. It defines the entire Snappy operating system. You enforce it.

Before you finish, do two things:#

1. Fix gaps (P — proportional). If this AGENTS.md didn't cover your case — if you had to read another file, run a command not documented here, work around a wrong selector, or discover a quirk — Edit it in before you log.

  • Default action: edit this AGENTS.md. Surgical. Add the missing line, table row, or code example where it belongs. No restructuring.
  • Every line you add carries its reason. Append an HTML comment recording why it exists and what breaks without it:

<!-- why: agent-browser wrote to CWD until we passed the path positionally (2026-08-05) -->

This is the single highest-value habit in the loop. An instruction whose rationale is legible can be safely deleted later; one whose rationale is lost can only be kept, which is how loaders grow without bound. Unreasoned additions are the defect this rule exists to prevent.

  • Only LOGGED when: the fix needs >10 lines, spans multiple files, or requires a structural rewrite (in which case the drain-skill-regen.sh queue picks it up).
  • NOOP is a first-class, blameless outcome. If you hit no gap — the loader covered your case — record NOOP and move on. Do NOT manufacture a gap to have something to write. A fabricated "learning" is strictly worse than silence: it becomes ground truth for every later agent and cannot be distinguished from a real one afterward. Most runs on a mature loader should be NOOP.
  • Concrete example of a valid P-fix: lesson-2 ship agent discovered agent-browser screenshot <path> takes path positionally, not as --output <path>. That's one line in a table, plus its why: comment. Edit it in.
  • The goal: the next agent never has to leave the loader — and the agent after that can still tell which lines have earned their place.

2. Validate structure. Check this skill against the spec:

  • api.ts exists with typed exports, CLI mode, import { env } from "../snappy-settings/load.ts"
  • api.ts calls APIs directly (no Xano proxy, unless this skill IS a Xano DB skill)
  • AGENTS.md has API module section with import + function table + CLI
  • No bash fallbacks, no hardcoded tokens anywhere
  • Every action row carries a certificate: block (premises / action / trace / evidence / conclusion). Same-session toasts are NOT evidence — must be a fresh independent read. Missing or weak certificates are a gap: P-fix them inline and log to ~/.claude/logs/verification-gaps.log.
  • DRY: before you add a new function or new skill, run ~/.claude/skills/snappy-settings/scripts/dry-check.sh <name-or-keyword>. If it matches an existing skill, extend that one instead. Fragmentation is the enemy.
  • If any check fails → fix it or log it

2b. If you just reported an action as successful, verify your certificate. You may not claim PASS unless the evidence: line is a fresh independent read (reload, new session, server round-trip). If your evidence is a toast, a return value, or a same-session DOM read, downgrade the claim to INCONCLUSIVE and log to verification-gaps.log.

3. Log always.

bashecho "[$(date -u +%FT%TZ)] <skill-name>: <what was missing or fixed> [FIXED|LOGGED|NOOP]" >> ~/.claude/logs/agents-md-feedback.log

FIXED = you patched it inline (with its why: comment). LOGGED = too large for inline fix, queued for drain-skill-regen.sh. NOOP = you checked and the loader covered your case — the correct and expected outcome on a mature loader.

Report what actually happened. Every agent run must leave the system better than it found it — and a run that found nothing to fix has already done that by confirming the loader holds. Accuracy is the contribution; volume is not.

Show produced work with snappy-faces: call draw for image channels or lang for MCP Apps.

<!-- SKILL-INDEX-START -->

[snappy-libretto Index]|root: ~/.claude/skills/snappy-libretto|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md}

<!-- SKILL-INDEX-END -->

Used by#

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->

Contract verbs#

Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.

Verb Contract arguments Effect First call
record url, name write-reversible npx tsx ~/.claude/skills/snappy-libretto/api.ts record <url> "<name>"
lessons read npx tsx ~/.claude/skills/snappy-libretto/api.ts lessons
lesson name read npx tsx ~/.claude/skills/snappy-libretto/api.ts lesson "<name>"
replay name, args? write npx tsx ~/.claude/skills/snappy-libretto/api.ts replay "<name>"
promote name, skill, verb write-reversible npx tsx ~/.claude/skills/snappy-libretto/api.ts promote "<name>" <skill> <verb>

Show the result#

When an answer carries face_hint, show it with one snappy_present(<answer>) call.

See /snappy-faces for face selection. Human-facing images must crop to the

element, render at 2x on Retina, and fill the destination channel instead of

placing a small card in a full-page screenshot.

<!-- SNAPPY-CONTRACT-VERBS-END -->

---
name: snappy-libretto
description: Record a browser job once as a typed lesson, replay its learned XHR/fetch calls with captured auth, and promote the replay into a typed snappy-* verb.
---

# snappy-libretto -- Agent Loader

Libretto is the person in the browser. It records one headed browser job, turns structural actions plus network calls into a local lesson, then makes that lesson callable with plain fetch.

## Decision

Keep and import `snappy-api-sniffer`. It already owns request normalization and authenticated fetch replay. Libretto adds the long-running recorder, typed lesson, stale-session refusal, and promotion lifecycle. Do not copy sniffer or browse code.

## Flow

```text
person -> record -> ~/snappy/libretto/lessons/<name>/
                  -> lesson review
                  -> replay by plain fetch
                  -> promote into a dedicated snappy-* hand
```

## Verb map

| CLI verb | Typed export | Effect | Result |
|---|---|---|---|
| `record <url> <name>` | `recordLesson(url, name, opts?)` | local write | Headed site profile, raw capture, auth state, typed lesson |
| `lessons` | `lessons()` | read | Safe summaries and counts |
| `lesson <name>` | `lesson(name)` | read | Structural steps and endpoint metadata, no secrets or bodies |
| `replay <name> [args]` | `replayLesson(name, args?, opts?)` | governed write | Plain-fetch responses; CLI prints counts only |
| `promote <name> <skill> <verb>` | `promote(name, skill, verb)` | local write | Generated typed hand delegating to Libretto |

All verbs support `--json`. Failures exit non-zero. `replay` requires `--now` when any endpoint method is not GET, HEAD, or OPTIONS.

## Use

```bash
API=~/.claude/skills/snappy-libretto/api.ts
npx tsx "$API" record "https://app.example.com/work" review-work
npx tsx "$API" lessons --json
npx tsx "$API" lesson review-work --json
npx tsx "$API" replay review-work '{"field_name":"new value"}' --json
npx tsx "$API" promote review-work snappy-example-work read-work --json
npx tsx "$API" contract
```

## Rules

- Runtime artifacts live under `~/snappy/libretto`, never in git.
- Record through `snappy-browse`; normalize and replay through `snappy-api-sniffer`; scaffold targets through `snappy-skill`.
- Keep structural selectors. Never store or promote `[ref=eN]` snapshot refs.
- Password events become `fill_secret`; never keep their values.
- Never print auth state, cookies, headers, request bodies, response bodies, or recorded field values. Use `lesson` for review.
- Stale auth is a named `session_stale` refusal. Never add an automatic login or browser fallback.
- The `replay` hand contract is `write` because recordings can contain write methods. The same verb runs after approval with `--now`.
- Promotion derives `read` versus `write` from captured HTTP methods.
- Promotion refuses a hand-written target API. Use a dedicated skill instead of splicing two owners together.
- A recording with no steps and no XHR/fetch calls is refused rather than filed as an empty lesson.

## Storage

```text
~/snappy/libretto/profiles/<site>/
~/snappy/libretto/lessons/<name>/lesson.json
~/snappy/libretto/lessons/<name>/raw-capture.json
~/snappy/libretto/lessons/<name>/auth-state.json
```

Directories are `0700`; lesson artifacts are `0600`. `lesson` omits sensitive fields. `loadLesson` is for trusted local code only.

## Failure routing

- Missing/expired auth or 401/403/login redirect: report `session_stale`, sign in, record again.
- No endpoints: browser-only lesson; record the data-producing action or keep the job in `snappy-browse`.
- Non-read endpoint without `--now`: stage through the governed hand and wait for approval.
- Existing hand-written target: choose a dedicated `snappy-*` skill.
- agent-browser permission failure: repair/reinstall the installed binary; do not fork the automation.

Read `SKILL.md` for selector priority, parameter rewriting, recording limits, privacy boundaries, promotion output, and measured 2026-09-08 product facts.

---

## THE DERIVATION LAW — the installed artifact is the spec (Robert 2026-08-05, LAW)

For any SDK, dependency, or API: enumerate its REAL surface from the installed package (`node_modules/<pkg>` — dist, CLI commands, shipped docs) and fetch its `llms.txt`/`llms-full.txt` BEFORE writing a line of integration. Import the package's own types; never redeclare a type a dependency exports; never write an integration from memory; never describe a surface you haven't listed. A hand-written parallel of a generated, vendored, or documented definition is a defect (DRY, original sense: one authoritative representation of every piece of knowledge). Writing from training memory instead of the installed source produces hallucinated APIs — the named killer of OpenAI's plugin ecosystem. Printing Press (spec→generated connector) is this law's special case; it applies to EVERYTHING.

## Self-correcting loader (PID feedback)

The system spec lives at `~/.claude/skills/snappy-settings/skill-spec.md`. It defines the entire Snappy operating system. You enforce it.

### Before you finish, do two things:

**1. Fix gaps (P — proportional).** If this AGENTS.md didn't cover your case — if you had to read another file, run a command not documented here, work around a wrong selector, or discover a quirk — `Edit` it in before you log.

- **Default action: edit this AGENTS.md.** Surgical. Add the missing line, table row, or code example where it belongs. No restructuring.
- **Every line you add carries its reason.** Append an HTML comment recording *why* it exists and what breaks without it:
  `<!-- why: agent-browser wrote to CWD until we passed the path positionally (2026-08-05) -->`
  This is the single highest-value habit in the loop. An instruction whose rationale is legible can be safely deleted later; one whose rationale is lost can only be kept, which is how loaders grow without bound. Unreasoned additions are the defect this rule exists to prevent.
- **Only LOGGED when:** the fix needs >10 lines, spans multiple files, or requires a structural rewrite (in which case the drain-skill-regen.sh queue picks it up).
- **NOOP is a first-class, blameless outcome.** If you hit no gap — the loader covered your case — record `NOOP` and move on. Do NOT manufacture a gap to have something to write. A fabricated "learning" is strictly worse than silence: it becomes ground truth for every later agent and cannot be distinguished from a real one afterward. Most runs on a mature loader should be NOOP.
- Concrete example of a valid P-fix: lesson-2 ship agent discovered `agent-browser screenshot <path>` takes path positionally, not as `--output <path>`. That's one line in a table, plus its `why:` comment. Edit it in.
- The goal: the next agent never has to leave the loader — and the agent after that can still tell which lines have earned their place.

**2. Validate structure.** Check this skill against the spec:
- `api.ts` exists with typed exports, CLI mode, `import { env } from "../snappy-settings/load.ts"`
- `api.ts` calls APIs directly (no Xano proxy, unless this skill IS a Xano DB skill)
- `AGENTS.md` has API module section with import + function table + CLI
- No bash fallbacks, no hardcoded tokens anywhere
- **Every action row carries a `certificate:` block** (premises / action / trace / evidence / conclusion). Same-session toasts are NOT evidence — must be a fresh independent read. Missing or weak certificates are a gap: P-fix them inline and log to `~/.claude/logs/verification-gaps.log`.
- **DRY:** before you add a new function or new skill, run `~/.claude/skills/snappy-settings/scripts/dry-check.sh <name-or-keyword>`. If it matches an existing skill, extend that one instead. Fragmentation is the enemy.
- If any check fails → fix it or log it

**2b. If you just reported an action as successful, verify your certificate.** You may not claim PASS unless the `evidence:` line is a fresh independent read (reload, new session, server round-trip). If your evidence is a toast, a return value, or a same-session DOM read, downgrade the claim to INCONCLUSIVE and log to `verification-gaps.log`.

**3. Log always.**
```bash
echo "[$(date -u +%FT%TZ)] <skill-name>: <what was missing or fixed> [FIXED|LOGGED|NOOP]" >> ~/.claude/logs/agents-md-feedback.log
```
`FIXED` = you patched it inline (with its `why:` comment). `LOGGED` = too large for inline fix, queued for drain-skill-regen.sh. `NOOP` = you checked and the loader covered your case — the correct and expected outcome on a mature loader.

**Report what actually happened.** Every agent run must leave the system better than it found it — and a run that found nothing to fix has already done that by confirming the loader holds. Accuracy is the contribution; volume is not.


Show produced work with `snappy-faces`: call `draw` for image channels or `lang` for MCP Apps.

<!-- SKILL-INDEX-START -->
[snappy-libretto Index]|root: ~/.claude/skills/snappy-libretto|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md}
<!-- SKILL-INDEX-END -->

## Used by

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs

Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.

| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
| `record` | `url`, `name` | `write-reversible` | `npx tsx ~/.claude/skills/snappy-libretto/api.ts record <url> "<name>"` |
| `lessons` | — | `read` | `npx tsx ~/.claude/skills/snappy-libretto/api.ts lessons` |
| `lesson` | `name` | `read` | `npx tsx ~/.claude/skills/snappy-libretto/api.ts lesson "<name>"` |
| `replay` | `name`, `args?` | `write` | `npx tsx ~/.claude/skills/snappy-libretto/api.ts replay "<name>"` |
| `promote` | `name`, `skill`, `verb` | `write-reversible` | `npx tsx ~/.claude/skills/snappy-libretto/api.ts promote "<name>" <skill> <verb>` |

## Show the result

When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?