baoyu-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": for webp, it prioritizes cwebp, then ImageMagick's convert, and falls back to sharp; for non-webp, it uses sips directly on macOS, otherwise convert, and falls back to sharp.
if (await commandExists("cwebp")) return "cwebp";
Availability detection relies on which + child_process.spawn; compression itself also spawns system CLIs and parses exit codes/stderr.
const proc = spawn("which", [cmd], { stdio: "pipe" });
sharp serves as a pure JS fallback and is lazily loaded via dynamic import (the loading cost is incurred only when none of the first three paths match).
const sharp = (await import("sharp")).default;
Disk writes use a "temporary file + atomic rename" pattern: it writes to output + '.tmp' first, then renames to the target filename upon success to avoid leaving incomplete files on mid-run failure.
renameSync(tempOutput, output);
Defaults to "convert rather than save as a copy": same directory, same base name, different extension; only outputs {base}-compressed.{ext} when --keep is enabled and the extensions match.
return join(dir, `${base}-compressed${ext}`);
Directory mode recursively collects files based on an extension whitelist, processes them one by one, and aggregates total file size; failure of a single file prints an error without aborting the entire batch.
const SUPPORTED_EXTS = [".png", ".jpg", ".jpeg", ".webp", ".gif", ".tiff"];
Preferences are declared only at the SKILL.md layer (three-tier EXTEND.md lookup, falling back to default format/quality/retention policy if not found); the script itself does not parse configuration files.
If none found, use defaults.
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 by -o), temporary files <output>.tmp, renames original to {base}_original.{ext} when --keep is not enabled
5Second-Pass Verification
- [ok] 无网络调用 / 无凭证读取 — 全文无 fetch/http/curl/API key/cookie/process.env 命中;唯一子进程是 which 与四个图像 CLI。
- [ok] “默认覆盖原图”的初判修正 — 第一遍曾疑为删除原图;逐行读后确认为 renameSync(absInput, `${base}_original${ext}`)——原图被改名保留,结论已按此更正写进 risks。
- [ok] sharp 依赖可解析性 — skill 目录无 package.json;仓库根 dependencies 含 sharp ^0.34.5。非 workspace 环境需自行安装 sharp 或依赖 cwebp/convert/sips 分支。
- [ok] 四个压缩器的参数与退出码处理 — sips 用 -s format/-s formatOptions/--out;cwebp 用 -q/-o;convert 用 [-quality];sharp 走 pipeline.webp/png/jpeg。均检查 code!==0 并抛错。
- [ok] 批量容错与汇总 — 目录模式下 processFile 抛错被 catch 后仅 console.error 继续;--json 输出 files[] + summary(compressor/totals/ratio)。
- [ok] meta 元数据 — GitHub API:MIT、25926 stars、pushed_at 2026-09-10T15:13:43Z;本地 HEAD 与任务 pin 1567581c26ec… 一致。
6Verdict & Scenarios
5c0a427092d20497…