{
  "schema": "snappy-card/1",
  "skill": "snappy-libretto",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "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.",
  "verbs": [
    {
      "name": "record",
      "args": [
        "url",
        "name"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-libretto/api.ts record <url> \"<name>\""
    },
    {
      "name": "lessons",
      "args": [],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-libretto/api.ts lessons"
    },
    {
      "name": "lesson",
      "args": [
        "name"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-libretto/api.ts lesson \"<name>\""
    },
    {
      "name": "replay",
      "args": [
        "name",
        "args?"
      ],
      "effect": "write",
      "firstCall": "npx tsx ~/.claude/skills/snappy-libretto/api.ts replay \"<name>\""
    },
    {
      "name": "promote",
      "args": [
        "name",
        "skill",
        "verb"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-libretto/api.ts promote \"<name>\" <skill> <verb>"
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [],
  "checks": {
    "pass": 40,
    "fail": 5,
    "defer": 16,
    "line": "40 of 45 checks pass",
    "failing": [
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path"
      },
      {
        "id": 11,
        "rule": "Each task presents one default, not a menu",
        "says": "2 line(s) present three-way alternative menus"
      },
      {
        "id": 20,
        "rule": "Read and write are separate verbs",
        "says": "mode-changing args on: replay"
      },
      {
        "id": 55,
        "rule": "Eval scenarios are multi-call with ground truth",
        "says": "eval manifest missing"
      },
      {
        "id": 57,
        "rule": "Eval manifest contains a disjoint holdout",
        "says": "0 disjoint holdout scenario(s)"
      }
    ]
  },
  "coverage": null,
  "spec": null,
  "evals": null,
  "files": [
    "AGENTS.md",
    "SKILL.md",
    "api.ts",
    "contract.test.ts"
  ],
  "total_size": 65290,
  "checksum": "sha256:4b7af8fd6ab0c5f5c28a1efdc83f87cf8e522b1615054f6dfd4e0428e143416a",
  "built_at": "2026-09-09T22:09:46.601Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-libretto",
      "version": "0.0.0",
      "description": "Record a browser job once in a headed, persistent agent-browser profile, review the typed lesson and learned XHR/fetch endpoints, replay it with plain fetch and captured auth, then promote it into a typed snappy-* verb. Triggers on: libretto, record browser job, teach this Mac, watch me once, browser lesson, learned endpoint, replay recording, promote lesson."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-libretto/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/record": {
        "post": {
          "operationId": "snappy_libretto_record",
          "summary": "snappy-libretto record",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "description": "Page recorded while the person performs the read once",
                      "x-snappy-position": 0
                    },
                    "name": {
                      "type": "string",
                      "description": "Name the recorded lesson is filed under",
                      "x-snappy-position": 1
                    },
                    "json": {
                      "x-snappy-flag": "--json"
                    }
                  },
                  "required": [
                    "url",
                    "name"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/lessons": {
        "get": {
          "operationId": "snappy_libretto_lessons",
          "summary": "snappy-libretto lessons",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "json",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--json"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/lesson": {
        "get": {
          "operationId": "snappy_libretto_lesson",
          "summary": "snappy-libretto lesson",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "name",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Lesson whose steps are returned",
                "x-snappy-position": 0
              }
            },
            {
              "name": "json",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--json"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/replay": {
        "post": {
          "operationId": "snappy_libretto_replay",
          "summary": "snappy-libretto replay",
          "x-snappy-effect": "write",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Lesson to replay",
                      "x-snappy-position": 0
                    },
                    "args": {
                      "type": "string",
                      "description": "JSON object of values substituted into the lesson's requests",
                      "x-snappy-position": 1
                    },
                    "json": {
                      "x-snappy-flag": "--json"
                    },
                    "now": {
                      "x-snappy-flag": "--now"
                    }
                  },
                  "required": [
                    "name"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/promote": {
        "post": {
          "operationId": "snappy_libretto_promote",
          "summary": "snappy-libretto promote",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Lesson promoted into a hand",
                      "x-snappy-position": 0
                    },
                    "skill": {
                      "type": "string",
                      "description": "Skill that gains the verb",
                      "x-snappy-position": 1
                    },
                    "verb": {
                      "type": "string",
                      "description": "Verb name the lesson is published as",
                      "x-snappy-position": 2
                    },
                    "json": {
                      "x-snappy-flag": "--json"
                    }
                  },
                  "required": [
                    "name",
                    "skill",
                    "verb"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      }
    },
    "components": {
      "schemas": {
        "SnappyRefusal": {
          "type": "object",
          "required": [
            "outcome",
            "code",
            "message"
          ],
          "properties": {
            "outcome": {
              "type": "string",
              "const": "refused"
            },
            "code": {
              "type": "string",
              "description": "A row of the closed refusal table."
            },
            "message": {
              "type": "string"
            },
            "fix": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}