{
  "schema": "snappy-card/1",
  "skill": "snappy-gemini",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "Wraps the `generativelanguage.googleapis.com` REST API. All Gemini calls in the Snappy system go through this skill so credentials, model IDs, and endpoints live in one place. Auth is automatic via `snappy-settings/load.ts` from `.env.cache`.",
  "verbs": [
    {
      "name": "describe",
      "args": [
        "image",
        "prompt?"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gemini/api.ts describe <image>"
    },
    {
      "name": "generate",
      "args": [
        "prompt"
      ],
      "effect": "draft",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gemini/api.ts generate \"<prompt>\""
    },
    {
      "name": "image",
      "args": [
        "prompt"
      ],
      "effect": "draft",
      "firstCall": "npx tsx ~/.claude/skills/snappy-gemini/api.ts image \"<prompt>\""
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [
    "snappy-course",
    "snappy-image",
    "snappy-openrouter"
  ],
  "checks": {
    "pass": 27,
    "fail": 7,
    "defer": 27,
    "line": "27 of 34 checks pass",
    "failing": [
      {
        "id": 5,
        "rule": "Description is valid, third-person, and says what plus when",
        "says": "1125 chars"
      },
      {
        "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": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~282 tokens; body ~4092 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",
    "examples.md",
    "models.md",
    "prompting.md",
    "scripts/audio.sh",
    "scripts/embed.sh",
    "scripts/image.sh",
    "scripts/lib/auth.sh",
    "scripts/text.sh",
    "scripts/video.sh"
  ],
  "total_size": 93099,
  "checksum": "sha256:bc9f71b8018e0b9a87c4860f1656047073ab5045ea614d08bb8d90a43a104a24",
  "built_at": "2026-09-09T22:09:22.314Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-gemini",
      "version": "0.0.0",
      "description": "Single canonical interface to Google's Gemini family for the Snappy system. Wraps the generativelanguage.googleapis.com REST API as bash scripts: text generation (Gemini 2.5 Pro / 2.5 Flash / 2.5 Flash-Lite / 2.0 Flash / Flash Thinking), image generation (Imagen 3 / Imagen 4 / Nano Banana / Gemini 2.5 Flash Image), video generation (Veo 2 / Veo 3), audio transcription and understanding, embeddings (text-embedding-004 / gemini-embedding-001), structured output via JSON schema, and the Files API for large payloads. Loads credentials from snappy-settings or GEMINI_API_KEY env var. Used by snappy-content, snappy-image, snappy-video, snappy-knowledge, and snappy-testimonials. Triggers on: gemini, google ai, google gemini, gemini api, gemini 2.5, gemini 2.0, gemini pro, gemini flash, gemini flash thinking, imagen, imagen 3, imagen 4, nano banana, veo, veo 2, veo 3, generativelanguage, ai.google.dev, vertex ai, gemini embeddings, text-embedding-004, gemini-embedding-001, structured output, json schema, multimodal, long context, 1m context, gemini files api, gemini transcribe, gemini ocr, gemini audio, gemini video."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-gemini/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/describe": {
        "get": {
          "operationId": "snappy_gemini_describe",
          "summary": "snappy-gemini describe",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "image",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Image file the model looks at",
                "x-snappy-position": 0
              }
            },
            {
              "name": "prompt",
              "in": "query",
              "required": false,
              "schema": {
                "type": "string",
                "description": "What to ask about the image; omit for a plain description",
                "x-snappy-position": 1
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/generate": {
        "post": {
          "operationId": "snappy_gemini_generate",
          "summary": "snappy-gemini generate",
          "x-snappy-effect": "draft",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prompt": {
                      "type": "string",
                      "description": "The text sent to the model",
                      "x-snappy-position": 0
                    },
                    "model": {
                      "x-snappy-flag": "--model"
                    }
                  },
                  "required": [
                    "prompt"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/image": {
        "post": {
          "operationId": "snappy_gemini_image",
          "summary": "snappy-gemini image",
          "x-snappy-effect": "draft",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prompt": {
                      "type": "string",
                      "description": "What the generated image should show",
                      "x-snappy-position": 0
                    },
                    "model": {
                      "x-snappy-flag": "--model"
                    },
                    "out": {
                      "x-snappy-flag": "--out"
                    },
                    "ref": {
                      "x-snappy-flag": "--ref"
                    }
                  },
                  "required": [
                    "prompt"
                  ]
                }
              }
            }
          },
          "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": [
      "GEMINI_API_KEY"
    ]
  }
}