{
  "schema": "snappy-card/1",
  "skill": "snappy-gateway",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "You manage the skills.snappy.ai Cloudflare Worker -- a KV-backed gateway that distributes Claude Code skills with tiered access control. This file is the operational contract. Everything load-bearing lives here.",
  "verbs": [
    {
      "name": "get",
      "args": [
        "name"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gateway/api.ts get \"<name>\""
    },
    {
      "name": "list",
      "args": [],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gateway/api.ts list"
    },
    {
      "name": "card",
      "args": [
        "name"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gateway/api.ts card \"<name>\""
    },
    {
      "name": "publish",
      "args": [
        "name?",
        "tier?"
      ],
      "effect": "post",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gateway/api.ts publish"
    },
    {
      "name": "pull",
      "args": [
        "name"
      ],
      "effect": "write-reversible",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gateway/api.ts pull \"<name>\""
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [
    "snappy-skill"
  ],
  "checks": {
    "pass": 42,
    "fail": 5,
    "defer": 14,
    "line": "42 of 47 checks pass",
    "failing": [
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path"
      },
      {
        "id": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~201 tokens; body ~4580 tokens"
      },
      {
        "id": 54,
        "rule": "At least three eval scenarios precede ready status",
        "says": "0 eval scenario(s); ready=true"
      },
      {
        "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",
    "card.test.ts",
    "card.ts",
    "contract.test.ts",
    "infrastructure.md",
    "key-management.md",
    "publish.ts",
    "publishing.md"
  ],
  "total_size": 107992,
  "checksum": "sha256:88075e3cfbd507689b288f2f45293e7d7618a5944ad7e505b26eaa4d2fbb81a3",
  "built_at": "2026-09-09T22:09:20.428Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-gateway",
      "version": "0.0.0",
      "description": "Snappy Skills Gateway -- publish, gate, and distribute Claude Code skills via skills.snappy.ai (Cloudflare Worker + KV). Manage API keys, access tiers (public/ client/subscriber/personal), publish skill bundles with a parsed card a stranger can evaluate, pull a published skill into a skills root, version via .snappy-meta.json checksums, revoke access, view catalog, deploy Worker updates. Implements the Cloudflare Agent Skills Discovery RFC at /.well-known/skills/. Triggers on: snappy skills, skills gateway, publish skill, skill card, skill keys, manage skills, skills.snappy.ai, skill marketplace, create skill key, revoke key, distribute skills, skill access, skill tiers, gated skills, .snappy-meta.json, skill checksum, skill version, kv namespace, wrangler deploy gateway, well-known skills."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-gateway/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/get": {
        "get": {
          "operationId": "snappy_gateway_get",
          "summary": "snappy-gateway get",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "name",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Gateway entry to read",
                "x-snappy-position": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/list": {
        "get": {
          "operationId": "snappy_gateway_list",
          "summary": "snappy-gateway list",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "How many gateway entries to return. The count is the FLAG --limit, never a positional word; default 20, ceiling 200",
                "default": 20,
                "minimum": 1,
                "maximum": 200,
                "x-snappy-flag": "--limit"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/card": {
        "get": {
          "operationId": "snappy_gateway_card",
          "summary": "snappy-gateway card",
          "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": "Local skill whose listing card is built and printed",
                "x-snappy-position": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/publish": {
        "post": {
          "operationId": "snappy_gateway_publish",
          "summary": "snappy-gateway publish",
          "x-snappy-effect": "post",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": true,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": false,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Gateway entry published; omit with --base-set",
                      "x-snappy-position": 0
                    },
                    "tier": {
                      "type": "string",
                      "description": "Audience tier the entry is published to",
                      "x-snappy-position": 1
                    },
                    "base-set": {
                      "x-snappy-flag": "--base-set"
                    },
                    "dry-run": {
                      "x-snappy-flag": "--dry-run"
                    },
                    "force": {
                      "x-snappy-flag": "--force"
                    },
                    "new-catalog": {
                      "x-snappy-flag": "--new-catalog"
                    }
                  }
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/pull": {
        "post": {
          "operationId": "snappy_gateway_pull",
          "summary": "snappy-gateway pull",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": true,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Published skill installed into the person's skills root",
                      "x-snappy-position": 0
                    },
                    "root": {
                      "type": "string",
                      "description": "Directory the skill is written into; defaults to the runner's recorded skills root",
                      "x-snappy-flag": "--root"
                    }
                  },
                  "required": [
                    "name"
                  ]
                }
              }
            }
          },
          "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"
            }
          }
        }
      }
    }
  }
}