{
  "schema": "snappy-card/1",
  "skill": "snappy-deploy",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "You are deploying a Snappy project. This loader tells you the platform, commands, and verification for each.",
  "verbs": [
    {
      "name": "status",
      "args": [
        "url?"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-deploy/api.ts status"
    },
    {
      "name": "vercel",
      "args": [
        "project-name"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-deploy/api.ts vercel <project-name>"
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [
    "snappy-telegram"
  ],
  "checks": {
    "pass": 44,
    "fail": 8,
    "defer": 9,
    "line": "44 of 52 checks pass",
    "failing": [
      {
        "id": 4,
        "rule": "Near-neighbour descriptions cross-reference each other",
        "says": "near neighbours not named: snappy-client-feisst, snappy-runner, snappy-specwatch"
      },
      {
        "id": 5,
        "rule": "Description is valid, third-person, and says what plus when",
        "says": "1158 chars"
      },
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path"
      },
      {
        "id": 39,
        "rule": "Verb sets consolidate intent rather than mirror endpoints",
        "says": "2 verbs, 3 literal endpoint(s); one-to-one heuristic=true"
      },
      {
        "id": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~290 tokens; body ~4848 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",
    "contract.test.ts",
    "faces/family.tsx",
    "faces/fixtures/deploy-receipt.json",
    "receipt.test.ts",
    "workflows.md"
  ],
  "total_size": 49319,
  "checksum": "sha256:62a49b555774f50f268cdbc006998b35a1c45243ec861ad7ee160d926048e686",
  "built_at": "2026-09-09T22:08:44.800Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-deploy",
      "version": "0.0.0",
      "description": "Meta-deployment skill that orchestrates ALL Snappy project deployments across the four supported platforms: Vercel (Next.js frontends -- Total CRM, snappy.ai), Fly.io (Total CRM hp-base backend prod + dev), Cloudflare Workers (snappy-mcp + snappy-skills gateway Worker code), and Supabase (Total CRM database migrations). Owns the project registry, pre-deploy checks, post-deploy verification commands, rollback workflow, and notification pipeline. Meta-skill: does NOT invent deploy mechanics, orchestrates existing platform CLIs (vercel, fly, wrangler, supabase). Does NOT cover snappy-box (Box self-deploys via POST /_deploy on its own server) or skill content publishing (snappy-gateway publish-skill.js). Triggers on: deploy, deployment, ship, push to prod, deploy frontend, deploy backend, fly deploy, vercel deploy, wrangler deploy, rollback, deploy total, deploy total crm, deploy mcp, deploy website, deploy snappy.ai, deploy worker, deploy migration, supabase migration, pre-deploy check, post-deploy verification, ship to production, multi-project deploy, deployment order, deployment registry, fly.io rollback, vercel rollback, wrangler rollback."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-deploy/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/status": {
        "get": {
          "operationId": "snappy_deploy_status",
          "summary": "snappy-deploy status",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "url",
              "in": "query",
              "required": false,
              "schema": {
                "type": "string",
                "description": "Deployment URL to check; omit for the project's current production URL",
                "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`."
            }
          }
        }
      },
      "/vercel": {
        "get": {
          "operationId": "snappy_deploy_vercel",
          "summary": "snappy-deploy vercel",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "project-name",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Vercel project whose latest deployments are read",
                "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"
            }
          }
        }
      }
    },
    "x-snappy-requires": [
      "VERCEL_TOKEN"
    ]
  }
}