canghe-compress-image
Compresses images to WebP (default) or PNG with automatic tool selection. Use when user asks to "compress image", "optimize image", "convert to webp", or reduce image file size.
1How It Works & Mechanism
The core logic is "automatically selecting a compressor based on the target format": webp prioritizes cwebp, then ImageMagick's convert, and finally sharp; non-webp formats use sips on macOS, otherwise convert, falling back to sharp.
if (await commandExists("cwebp")) return "cwebp";
Availability probing relies on which + child_process.spawn, and the compression itself spawns the system CLI and parses the exit code/stderr.
const proc = spawn("which", [cmd], { stdio: "pipe" });
sharp serves as a pure JS fallback and is lazily loaded via dynamic import (incurring loading overhead only when preceding paths miss).
const sharp = (await import("sharp")).default;
Disk writing uses "temporary file + atomic rename": it first writes to output + '.tmp', and renames it to the target name upon success.
renameSync(tempOutput, output);
Defaults to "convert rather than save as copy": same directory, same basename, changed extension; outputs {base}-compressed.{ext} only when --keep is enabled and the extension remains identical.
return join(dir, `${base}-compressed${ext}`);
When --keep is not enabled, the original image is renamed and preserved as {base}_original.{ext}.
renameSync(absInput, `${base}_original${ext}`);
Directory mode recursively collects files based on an extension whitelist, processes them one by one, and aggregates the total size.
const SUPPORTED_EXTS = [".png", ".jpg", ".jpeg", ".webp", ".gif", ".tiff"];
Preferences are only declared at the SKILL.md layer (resolved via EXTEND.md across three lookup levels and applied if matched); the script itself does not read configuration files.
Read, parse, apply settings
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| cli | sips(macOS 系统自带图像工具,非 webp 时的首选) |
| cli | cwebp(libwebp 官方 CLI,webp 首选) |
| cli | ImageMagick convert |
| cli | which(命令可用性探测) |
| package | sharp(动态 import 的纯 JS 兜底;skill 目录无 package.json,依赖运行环境解析) |
4Recommended Governance & Evidence
- scripts/: Executes local scripts or commands: scripts/main.ts (run via bun; spawns which / sips / cwebp / convert, dynamically imports sharp)
- 本地工作目录: File I/O and artifact output: Outputs images (same directory with new extension or path specified via -o), temporary file <output>.tmp, renames original image to {base}_original.{ext} when --keep is disabled
5Second-Pass Verification
- [ok] 自带脚本只有 scripts/main.ts,且仅本地行为 — 扫描“网络请求”0 命中;唯一执行面是 spawn which/sips/cwebp/convert 与动态 import sharp;无 fetch/http 调用。
- [ok] 原图改名副作用 — processFile 中当 !keep 且 absInput !== output 时 renameSync 原图为 *_original.{ext};已在 risks 提示,批量前建议试跑或 -o。
- [ok] sharp 依赖来源(无自带 package.json) — skill 目录确无 package.json;sharp 靠运行环境解析,缺失时仅在前几条 CLI 路径都不命中才会失败。
- [ok] 选项表与脚本参数一致 — SKILL.md 的 7 个 option 与 parseArgs 处理的分支完全对应,默认值 format=webp、quality=80、keep/recursive/json=false。
- [ok] 安全面与档位 — 零网络、零凭证、零配置解析;仅本地文件读写与系统 CLI 调用,判 blue 与前例一致。
- [ok] meta 元数据 — commit dd0bf355…、path skills/canghe-compress-image、license MIT 与 bundle §0 核定值一致。
6Verdict & Scenarios
346c02cfdb2597bb…