{
  "$schema": "https://bestaiskill.com/schemas/agent-install/2.json",
  "skill": "download-gemini-images",
  "built": "2026-10-26",
  "control_level": 4,
  "control_level_label": "L4 高权限",
  "capabilities": [
    "execute_command",
    "network",
    "write_file"
  ],
  "required_controls": {
    "agent": [
      "sandbox_recommended",
      "graded_authorization"
    ],
    "admin": [
      "approval_process",
      "rollback_support",
      "full_audit"
    ]
  },
  "evidence": [
    {
      "file": "scripts/",
      "summary": "Local script or command execution: download-gemini-images/scripts/download_gemini_images.mjs (in host node_repl J"
    },
    {
      "file": "网络端点",
      "summary": "Declared external network access: gemini.google.com (drives user browser to visit/remain on this site; script only performs URL matching, actual requests are dispatched by user browser)"
    },
    {
      "file": "本地工作目录",
      "summary": "File I/O and artifact output: Chrome downloads directory (default ~/Downloads): intermediate files <uuid>.jpg/.png/.webp written by browser itself (script reads only, does not delete)"
    }
  ],
  "verification": {
    "method": "第二遍独立重读 + 反查（不沿用第一遍结论）：① glob 全量文件清单（SKILL.md + scripts×2 + agents/openai.yaml，共 4 个文件，无隐藏脚本、无二进制）；② 对全目录做 token 扫描（https?://、curl、wget、fetch(、API_KEY、TOKEN、SECRET、.env、cookie、keychain、credential、process.env、os.environ、subprocess、child_process、exec(、spawn），唯一命中是 SKILL.md:64 的『Do not inspect browser cookies, local storage, passwords, or session stores.』——即禁止条款本身，坐实「无凭证读取、无外部 API 调用」；③ 逐行重读 mjs 确认网络面只在 browser.user.openTabs/claimTab 与 pageAssets 两处宿主能力上，脚本本身不发起 fetch/XHR；④ 域名复核：gemini.google.com 出现于 mjs:117 与 SKILL.md:29，lh3.googleusercontent.com 出现于 SKILL.md:56，无第三个域名；⑤ 功能声明 vs 实际能力：description 宣称『logged-in Chrome/Gemini state + lightbox + rename in order + ZIP』四项，分别由 claimGeminiTab / waitForSelectedImage / image_NN 命名 / package_images.sh 一一兑现，无夸大；⑥ 安全反例检索：查有无被漏掉的下载外发或删除动作——package_images.sh 唯一的 rm 是 rm -f \"$zip_path\"（删除待写入的同名 ZIP），mjs 无 unlink/rm。",
    "second_pass": [
      {
        "item": "外部依赖：宿主 browser 能力真实存在（不是推测）",
        "status": "ok",
        "detail": "mjs:124 return await browser.user.claimTab(matches[0]); 与 mjs:118 await browser.user.openTabs() 是真实调用点；SKILL.md 第 3 步要求 import 后在 node_repl 里跑，两处对得上。"
      },
      {
        "item": "外部依赖：zip / zipinfo / find / wc 调用点",
        "status": "ok",
        "detail": "package_images.sh 内 zip -qr、zip -T、zipinfo -1、find ... -iname 'image_*.jpg'、wc -l 均实读命中，脚本是真的会跑这些二进制，不是文档口号。"
      },
      {
        "item": "网络端点数量：只有 Google 两个域名",
        "status": "ok",
        "detail": "全目录域名级检索仅 gemini.google.com 与 lh3.googleusercontent.com；无第三方 API、无 webhook、无 telemetry。注意 mjs 中出现的 blob: 是页面内对象 URL，不是网络端点。"
      },
      {
        "item": "凭证面：是否真的不碰 cookie（找反例）",
        "status": "discrepancy",
        "detail": "〔第二遍标注：措辞需精确〕反例检索结果：源码中确实没有任何 document.cookie / chrome.cookies / localStorage 访问，SKILL.md 也明文禁止。但『不读凭证』不等于『不使用凭证态』——claimTab 借用的正是用户已登录会话。第一遍若把此条简单写成「无凭证接触」会掩盖真实权限面，故在 credential_reads 中改写为『无凭证文件读取，但运行于凭证态上下文』。"
      },
      {
        "item": "『绝不自开新浏览器』是否成立",
        "status": "ok",
        "detail": "claimGeminiTab 在 matches.length === 0 时抛错（No open Gemini tab matched），downloadGeminiImagesFromChrome 中 options.tab 与 claimGeminiTab 二选一，无 puppeteer.launch 之类的建窗代码，与 SKILL.md『claim the already-open Gemini tab』一致。"
      },
      {
        "item": "输出完整性校验是否真做了（非文档承诺）",
        "status": "ok",
        "detail": "package_images.sh: zip -T 有实调用，且 image_count 与 zip_count 不等时 exit 1；mjs 侧有 initialCount 校验、按钮数不变量、selectedCount !== 1 抛错——三道都是代码而非描述。"
      },
      {
        "item": "expectedCount 语义是否被夸大",
        "status": "ok",
        "detail": "description 未提 expectedCount；SKILL.md 只说『Set `expectedCount` only when the user gave a specific count』，代码里 initialCount !== expectedCount 时抛错，与文档一致，无越界承诺。"
      },
      {
        "item": "元数据（license/stars/last_push）",
        "status": "ok",
        "detail": "取自同 repo 同 commit 的池内既有值（与 auto-repo-setup.json / bilibili-source.json 一致：MIT、1385★、2026-09-09T12:33:29Z）；本次未联网复核 gh。"
      }
    ],
    "level": 1,
    "level_label": "V1 已固定",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247",
    "sha256": "2c75fce87072dc44632b05f7c87b7a3426689651315db2d4b865bcbbd2b00137",
    "reviewed_by": null,
    "reviewed_at": null
  },
  "assessed_at": "2026-10-25",
  "method_version": "2.0",
  "mirror": {
    "archive": "https://skillpub.pages.dev/r2/v/2026-09-15/download-gemini-images.tar.gz",
    "sha256": "2c75fce87072dc44632b05f7c87b7a3426689651315db2d4b865bcbbd2b00137",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247"
  },
  "original": {
    "github": "https://github.com/daymade/claude-code-skills/tree/main/download-gemini-images",
    "path": "download-gemini-images",
    "commit": "d5c4678cb5d4fd6acc9c922690df035dbd33d247"
  }
}