コマンド一つで画像を圧縮 —— ターミナルでも、ビルドでも、エージェントでも。
PiPic CLI は、ウェブと同じ圧縮をスクリプト・CI パイプライン・AI コーディングエージェントに届けます。Node 20 以上が必要。テレメトリなし。画像は圧縮された瞬間に削除されます。
なぜ pipic CLI なのか?
- エージェントネイティブ:NDJSON 出力と安定した終了コードで、AI エージェントは文章を読み解くことなく直接パースして分岐できます。
- コマンド一つでフォルダ全体を圧縮 —— その場での上書きでも、新しいディレクトリへの出力でも。ローカルの一括処理にもビルド成果物にも使えます。
- 一度サインインすれば、その後は無人で動きます:スクリプト、CI(PIPIC_TOKEN 経由)、エージェントのいずれも、都度の承認なしで使えます。
- テレメトリは一切なし。画像は圧縮が完了した瞬間にサーバーから削除されます。
必要環境
Node 20 以上が必要です。コマンド名は pipic です。
クイックスタート(人間向け)
一度だけpipic login はブラウザを開いてリクエストの承認を求めます。承認すると、認証情報はこのマシンに保存されます —— 以降はあなたとして動くどのツール(AI コーディングエージェントを含む)も、再サインインなしで pipic を使えます。
ブラウザがない場合は?SSH・コンテナ・CI
pipic login --no-browser、あるいは CLI が非対話環境(SSH・CI・コンテナ)を検知した場合は、デバイスコード方式に切り替わり、ブラウザが使える別のデバイスから承認できます。
クイックスタート(AI エージェント向け)
毎回このマシンにはすでにインストール・サインイン済みですか?以下をそのままコーディングエージェントに貼り付けてください:
Use the `pipic` CLI to compress the images in ./assets.
It's already installed and signed in — do not install it or run
`pipic login` yourself.
pipic ./assets --replace --json
It prints one JSON object per file:
{"file":"a.png","status":"ok","before":102400,"after":41000,"saved":61400}
status is "ok", "skipped" or "error". "skipped" is not a failure — it
carries an `error` string explaining why (e.g. already small enough).
Exit 0 = all good, 1 = some files failed, 3 = not signed in,
4 = monthly quota exhausted.
Don't retry on exit 2 (usage error), 3 or 4 — on 3, stop and tell the
user to sign in. On exit 1, re-run only the paths whose rows had status
"error": a full re-run re-uploads every file and spends quota again.エージェントがコンテナやサンドボックスで動いていて ~/.config が見えない場合は、アカウントページでトークンを作成し、その環境の PIPIC_TOKEN に設定してください。
コマンド
pipic <パス…>ファイルまたはディレクトリを圧縮します。これがデフォルトのコマンドです。pipic login [--no-browser]ブラウザまたはデバイスコードでこのマシンを認証します。pipic logoutサインアウトし、このマシンのトークンを失効させます。pipic whoamiサインイン中のアカウントとプランを表示します。pipic quota今月の残り利用枠を表示します。pipic token listトークンをプレフィックスと最終利用日時つきで一覧表示します。pipic token createウェブサイトで作成するためのリンクを表示します —— セキュリティ上、トークンの作成は必ずウェブ上で行い、CLI 自体では作成しません。pipic token revoke <id>自分のトークンを失効させます。通常 1 分程度で反映されます。login・logout・whoami・quota・token は、パスとして扱われる前にサブコマンドとして優先的にマッチします。同じ名前のフォルダを圧縮したい場合は ./login や login/ のように書いてください —— パス区切りを含む形であれば圧縮コマンドとして扱われます。
圧縮オプション
--replace元の画像をその場で上書きします —— アトミックな置き換え、権限を維持、シンボリックリンクを解決。-o, --out <dir>結果をこのディレクトリに書き出します。--jsonファイルごとに 1 行の NDJSON を出力します —— スクリプトやエージェント向け。--concurrency <n>並列アップロード数。デフォルトは 4。--replace か -o のどちらか一方を必ず指定してください —— 両者は排他的で、どちらもデフォルトではありません。どちらも指定しない場合、pipic は用法エラー(終了コード 2)で終了します。
知っておきたいこと
- 結果が実際に小さくなった場合のみ書き戻します —— すでに最適化済みの画像はスキップされ、理由が表示されます。-o の場合は元の画像がそのままコピーされるため、出力ディレクトリは常に完全な一式になります。
- --replace は一時ファイルに書き込んでからリネームするため、Ctrl-C で中断しても中途半端なファイルが残りません。
- 8 MB を超えるファイルは明確な理由つきでスキップされ、黙って捨てられることはありません。
- JPG・PNG・WebP・AVIF に対応。テレメトリは一切送信されません。
- -o では、別々のサブフォルダにある同名ファイル同士が衝突します。pipic はどちらを残すか推測せず、両方をエラーとして報告します。
JSON 出力コントラクト
--json はファイルごとに 1 行、固定 6 フィールドの JSON オブジェクトを出力します:
file渡したパスがそのまま入ります。status"ok"・"skipped"・"error" のいずれか —— それ以外の値は取りません。before元のサイズ(バイト)。after圧縮後のサイズ(バイト)—— skipped/error 行では 0。saved節約したバイト数(before から after を引いた値)—— 割合ではありません。errorskipped と error の行にのみ存在 —— コードではなく、人が読める理由です。終了コード
0すべて成功1一部失敗2用法エラー3サインインが必要4利用枠を使い切ったこれは安定した契約です:スクリプトやエージェントは status と終了コードで分岐してください —— error の文字列内容で判定してはいけません。
HTTP API
Node が使えない環境でも、同じ圧縮エンジンを HTTP で直接呼び出せます —— 1 リクエストにつき画像 1 枚、SDK も multipart フォームも不要です。
POST https://pipic.cc/compress/image
トークンを取得
API は CLI と同じ Personal Access Token を使います。GitHub または Google でサインインし、アカウントページで発行してください —— 平文のトークンはその場限りしか表示されないので、安全な場所に保存してください。
トークンを作成リクエスト
AuthorizationBearer <token> —— すべてのリクエストで必須。Content-Typeimage/png、image/jpeg、image/webp、image/avif のいずれか —— 必須。実際に送るバイト列と一致させてください。X-Original-Name任意。先に URL エンコードしてください —— レスポンスには encodeURIComponent で使える文字だけがそのまま返ります。Body画像の生バイナリ。multipart/form-data ではありません。1 リクエストにつき画像 1 枚、最大 8MB。レスポンス
200 OK のレスポンスボディは圧縮済み画像そのもの —— 入力と同じ形式で返ります。Content-Type は圧縮後の形式を示し、取得できれば Content-Length と X-Original-Name も付きます。
エラー
200 以外のレスポンスはすべてこの形の JSON エラーを返します。判定は message の文字列ではなく code フィールドで行ってください —— 実例はこちら:
400INVALID_TYPE —— Content-Type が未指定、または画像タイプでない/NO_FILE —— リクエストボディが空401UNAUTHORIZED、TOKEN_EXPIRED、TOKEN_REVOKED —— 再サインイン、または新しいトークンを作成413FILE_TOO_LARGE —— 8MB 超過415UNSUPPORTED_TYPE —— 圧縮対象外の image/* タイプ(対応は PNG・JPEG・WebP・AVIF のみ)429RATE_LIMITED(Retry-After ヘッダーを参照)または MONTHLY_QUOTA_EXCEEDED —— 今月の利用枠を使い切った502UPSTREAM_ERROR —— 圧縮バックエンドがこの画像を拒否しました。同じバイト列を再送しても結果は変わりません。この試行は割り当てに払い戻されます503UPSTREAM_ERROR または ALL_KEYS_EXHAUSTED —— 一時的に容量が不足しています。バックオフして再試行できます。この試行は割り当てに払い戻されます知っておきたいこと
- リクエストは圧縮処理に受け付けられた時点で利用枠を 1 消費します —— そのあと 400・413・415 で失敗した場合も同様です。その前に拒否されたリクエストは消費しません:あらゆる 401、429 RATE_LIMITED、および宣言された Content-Length ヘッダーだけを理由に拒否されたファイルです。こちら側の問題(502/503)で失敗した場合は、その分は自動的に返却されます。
すべてのヘッダーとエラーコードを機械可読な 1 ファイルで確認するには: /openapi.json
よくある質問
エージェントが指示していないファイルを触ることはありますか?
ありません —— pipic は --replace か -o <dir> の明示指定を必須とし、どちらもなければ実行を拒否します。そのエラーを報告する前に、リクエストが送信されることも一切ありません。
一度サインインすれば、エージェントはずっと使い続けられますか?
はい。認証情報はこのマシンの ~/.config/pipic/config.json に保存されており、あなたとして動くどのツールも読み取れます —— エージェントごとに追加の承認は不要です。
エージェントが「サインインしていません」と言ってきたら?
多くの場合、~/.config が見えないコンテナやサンドボックスで動いています。アカウントページでトークンを作成し、その環境の PIPIC_TOKEN として設定してください。
無料の利用枠を使い切るとどうなりますか?
pipic は終了コード 4 で終了し、自動的に課金されることはありません。Free は月 100 枚、Pro なら月 5,000 枚まで増えます。
画像はどこかに保存されますか?
いいえ —— 圧縮が完了した瞬間にサーバーから削除され、長期的に保存されることはありません。
プライバシー
テレメトリは一切なし。画像は圧縮が完了した瞬間にサーバーから削除されます —— 長期的な保存は行いません。
プライバシーポリシー全文を読む