{
  "schema": "snappy-card/1",
  "skill": "snappy-walkthrough",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "Capture step-by-step walkthroughs (Claude Code setup, skill install, MCP",
  "verbs": [
    {
      "name": "annotate",
      "args": [
        "out-dir"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts annotate <out-dir>"
    },
    {
      "name": "capture",
      "args": [
        "recipe"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts capture <recipe>"
    },
    {
      "name": "gates",
      "args": [
        "out-dir"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts gates <out-dir>"
    },
    {
      "name": "lesson",
      "args": [
        "out-dir"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts lesson <out-dir>"
    },
    {
      "name": "run",
      "args": [
        "recipe"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts run <recipe>"
    },
    {
      "name": "status",
      "args": [],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts status"
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [],
  "checks": {
    "pass": 42,
    "fail": 7,
    "defer": 12,
    "line": "42 of 49 checks pass",
    "failing": [
      {
        "id": 5,
        "rule": "Description is valid, third-person, and says what plus when",
        "says": "first/second person"
      },
      {
        "id": 7,
        "rule": "Promised and declared verbs have no set difference",
        "says": "promised-only=[]; loader-missing=[steps]"
      },
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: field/box/element"
      },
      {
        "id": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~172 tokens; body ~2285 tokens"
      },
      {
        "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)"
      },
      {
        "id": 60,
        "rule": "Loader publishes the contract's derived first call, current",
        "says": "generated block is stale against HAND_CONTRACT; run fix-loader"
      }
    ]
  },
  "coverage": null,
  "spec": null,
  "evals": null,
  "files": [
    "AGENTS.md",
    "SKILL.md",
    "api.ts",
    "contract-gates.md",
    "faces/components/walkthrough-faces.css",
    "faces/components/walkthrough-faces.tsx",
    "faces/family.tsx",
    "faces/fixtures/walkthrough-steps.json",
    "out/smoke-test/manual/gates.log",
    "out/smoke-test/manual/lesson.md",
    "out/smoke-test/manual/recipe.json",
    "out/smoke-test/manual/step-01.meta.json",
    "out/smoke-test/manual/step-01.overlay.svg",
    "out/smoke-test/manual/step-01.png",
    "out/smoke-test/manual/step-01.raw.png",
    "out/smoke-test/manual/step-01.svg",
    "recipes/claude-code-first-session.json",
    "refusals.test.ts",
    "steps-face.test.ts"
  ],
  "total_size": 100284,
  "checksum": "sha256:f391db117b118d22f2651e14b289aeb31ca97c048803024f86c12408bbec58c2",
  "built_at": "2026-09-09T22:11:25.100Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-walkthrough",
      "version": "0.0.0",
      "description": "Recipe-driven capture and annotation of step-by-step tutorials. Turns the walkthroughs Robert gives on calls (\"how I set up Claude Code\", \"how I install a skill\", \"how I wire an MCP\") into premium annotated still sequences, ready-to-paste markdown lesson blocks, and (phase 2) animated walkthrough videos. The PID setpoint for \"premium\" lives in contract-gates.md -- every hand-review tightens the rubric. Triggers on: walkthrough, annotated tutorial, step-by-step capture, annotated screenshot, boxes and arrows, click-through tutorial, capture my call, record setup steps, tutorial capture, snappy walkthrough, how-to capture, annotated screen recording, window screenshot annotation."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-walkthrough/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/annotate": {
        "post": {
          "operationId": "snappy_walkthrough_annotate",
          "summary": "snappy-walkthrough annotate",
          "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": {
                    "out-dir": {
                      "type": "string",
                      "description": "Directory the generated files are written to",
                      "x-snappy-position": 0
                    }
                  },
                  "required": [
                    "out-dir"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/capture": {
        "post": {
          "operationId": "snappy_walkthrough_capture",
          "summary": "snappy-walkthrough capture",
          "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": {
                    "recipe": {
                      "type": "string",
                      "description": "Walkthrough recipe name to capture",
                      "x-snappy-position": 0
                    }
                  },
                  "required": [
                    "recipe"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/gates": {
        "get": {
          "operationId": "snappy_walkthrough_gates",
          "summary": "snappy-walkthrough gates",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "out-dir",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Directory the generated files are written to",
                "x-snappy-position": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/lesson": {
        "get": {
          "operationId": "snappy_walkthrough_lesson",
          "summary": "snappy-walkthrough lesson",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "out-dir",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Directory the generated files are written to",
                "x-snappy-position": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/run": {
        "post": {
          "operationId": "snappy_walkthrough_run",
          "summary": "snappy-walkthrough run",
          "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": {
                    "recipe": {
                      "type": "string",
                      "description": "Recipe id from `snappy-ops recipes`",
                      "x-snappy-position": 0
                    }
                  },
                  "required": [
                    "recipe"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/status": {
        "get": {
          "operationId": "snappy_walkthrough_status",
          "summary": "snappy-walkthrough status",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/steps": {
        "get": {
          "operationId": "snappy_walkthrough_steps",
          "summary": "snappy-walkthrough steps",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "out-dir",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Directory a `capture` run wrote its steps into",
                "x-snappy-position": 0
              }
            }
          ],
          "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"
            }
          }
        }
      }
    }
  }
}