daily-card · 社交卡片生成器 は何をしますか?
能力一句话
入力 タイトル + サブタイトル → PNG を出力:当日日付、文案テーマに関連するベクターステッカー、統一された配色を自動付与。完全ローカルレンダリング、日本語・中国語文字 100% 制御可能、同一パラメータで再現可能な結果。
このリポジトリ自体が skill ディレクトリです:本 SKILL.md があるディレクトリがプロジェクトルートで、コード、設定テンプレート、ドキュメントはすべて同階層。WorkBuddy / Claude Code / Codex CLI など各々の skills パスに配置するか、skillhub 系プラットフォームから GitHub インポート可能。
インストールと場所
プロジェクトルート = 本 SKILL.md があるディレクトリ。どのパスに置いても動作可能——コードは __file__ で自身の位置を特定し、絶対パスに依存しません。
cd /path/to/daily-card # 実際のインストール場所に変更
python3 -m pip install -r requirements.txt
./install.sh # 冪等インストール:依存関係、プライベート設定初期化、自己診断
./scripts/selfcheck.sh # その後はいつでも単独で自己診断(CI のエントリポイントでもある)
インターネット接続不要、AI インターフェース不要、API Key 不要。中文字体は自動検出:macOS は Hiragino Sans GB / PingFang、Linux は Noto Sans CJK、Windows は Microsoft YaHei;いずれも見つからない場合は終了し、--font / --font-bold でフォントファイルを指定するよう促します。
agent は優先的にローカル CLI を使用し、サービスの起動は不要です。 Web バックエンドとリモート API はどちらもオプションのバックエンドです。詳細は「2種類のオプションバックエンド」を参照。
最もよく使う:コマンドライン生成(agent はこれを優先)
python3 cardgen.py "今日もいい一日を" "普通の日々を、もっと輝かせよう"
コマンドは ファイル:... の完全パスを出力します。この PNG パスを present_files でユーザーに提示し、レスポンス内でテーマとサイズを説明してください。デフォルトの出力ディレクトリは output/、ファイル名は <タイトル>-<日付>-<プラットフォーム>.png。
よく使うパラメータ
| パラメータ | 説明 | 例 |
|---|---|---|
-t / -s | タイトル / サブタイトル | -t "おはよう" -s "まず起きよう" |
--platform | サイズプリセット | xhs(1080×1440) / moments(1080×1080) / wechat(900×500) / story(1080×1920) / wechat2(1080×460) |
--theme | テーマを強制指定(デフォルトはキーワード自動認識) | --theme study |
--date | 日付指定 | --date 2026-01-01 |
--brand | 下部のクレジット | --brand "Claw · 每日一句" |
--out | 出力パス指定 | --out /tmp/card.png |
--seed | 構図の乱数シード(同じシードで同一構図) | --seed 42 |
--bg-image | カスタム背景画像(自動配色抽出) | --bg-image ./bg.jpg |
--bg-scheme | 画像から抽出した N 番目の配色を選択、または主色をカスタム指定 | --bg-scheme 2 / --bg-scheme "#C2185B" |
--list-schemes | 背景画像の候補配色 JSON を出力 | python3 cardgen.py --bg-image bg.jpg --list-schemes |
--list-themes | 全テーマとステッカーを一覧表示 | |
--config-dir | 別の設定ディレクトリを使用 | |
--init-config | 出荷時テンプレートから config/themes.json を再作成(プライベートテーマを上書きします。事前にバックアップしてください) |
背景画像からの配色抽出の完全な流れ
# 1. 画像から抽出可能な配色セットを確認(JSON 出力:name / base / colors / ratio)
python3 cardgen.py --bg-image ./bg.jpg --list-schemes
# 2. 1 つのセットを選んで生成(0 は主色、1/2/3 は補色、直接 #RRGGBB も可)
python3 cardgen.py "夕暮れは昼から夜への返事" "今日もお疲れさま" \
--bg-image ./bg.jpg --bg-scheme 2 --platform xhs
配色(背景、文字、アクセント、カード、ステッカー)はすべて選択したスキームから派生するため、ステッカーの色は必ず画像と同系色になります。ステッカーの種類はタイトルのテーマに応じて自動マッチングされます。
設定ファイル(コードではなく設定を変更)
| ファイル | 内容 | リポジトリ管理 |
|---|---|---|
config/themes.default.json | 出荷時テンプレート、11 テーマ、読み取り専用、「デフォルトに戻す」用 | はい |
config/stickers.json | 28 個のステッカーの中国名/グループ + 6 種類の背景パターンレジストリ(意味説明 desc 付き) | はい |
config/themes.json | 実際に有効なテーマ設定:label、keywords、10 個の色、motif、stickers、dark | いいえ、プライベートデータ |
config/settings.json | デフォルトプラットフォーム、クレジット、スーパーサンプリング倍率、ノイズ強度、出力ディレクトリ、デフォルト配色スキーム番号 | いいえ、プライベートデータ |
themes.json と settings.json は利用者のプライベートデータであり、バージョン管理には含めず、公開リポジトリからも配布しません。初回実行時に cardconfig.ensure_config() が出荷時テンプレートから自動コピー生成するため、手動作成は不要です。別の設定ディレクトリを使いたい場合は DAILY_CARD_CONFIG 環境変数または --config-dir を使用。詳細は config/README.md を参照。
内蔵 11 テーマ:study morning night coffee sport nature mood work tech festival quote。
配色/ステッカーを変更する場合:直接 config/themes.json の該当テーマの colors / stickers / keywords を編集するか、バックエンド API を使用。スクリプトは実行のたびに再読み込みするため、編集後すぐ反映されます。新しいテーマを追加するには、10 個すべての色キー(#RRGGBB)と少なくとも 1 つの有効なステッカー ID が必要。プライベートデータであるため、編集しても git status には表示されません。バックアップが必要な場合はこのファイルを自分でコピーしてください。
2種類のオプションバックエンド
| バックエンド | 必要な時 | 有効化方法 |
|---|---|---|
| なし(デフォルト) | CLI でカード生成だけする場合 | 何もしない。直接 python3 cardgen.py ... |
| ローカル Web バックエンド(独立モード) | GUI、リアルタイムプレビュー、ビジュアルテーマ編集が必要な場合 | python3 server.py、ページと API を同時にホスト、インターフェースは http://127.0.0.1:8777 |
| リモートサーバー(API のみモード) | チーム共有、agent に安定したエンドポイントが必要な場合 | python3 server.py --api-only + nginx サブパスリバースプロキシ、DAILY_CARD_URL を設定 |
--api-only ではバックエンドは /api/* のみ応答(静的ファイルは nginx が直接配信)、/api/reveal は 403 を返します。GET /api/health は version / mode / serves_static / config_dir を返し、オンラインバージョンの確認に使用できます。
CLI は常に呼び出し元のローカルマシンで実行され、バックエンドとは無関係です。サービスを起動していないのに /api/* を呼び出すと接続エラーになります。
ローカル Web バックエンド(ビジュアル設定 + リアルタイムプレビュー)
python3 server.py # http://127.0.0.1:8777(独立モード)
python3 server.py --port 9000 --open
python3 server.py --api-only # クラウドデプロイ:API のみ提供、静的ファイルは nginx がホスト
# macOS では start-server.command をダブルクリックでも可
3 つのパネル:カードデザイン(フォーム + リアルタイムプレビュー + ダウンロード/保存)、テーマ設定(色/ステッカー/キーワードをビジュアル編集し JSON に書き戻し)、グローバル設定(デフォルト値とレンダリングパラメータ)。タブは #design / #config / #settings のディープリンクで切り替え可能。
テーマ設定パネルは 3 カラム:テーマ一覧 / エディター / リアルタイム効果プレビュー。色、背景パターン、ダークモード切り替え、ステッカーを編集すると、右側にまだ保存されていない下書き効果が即座に表示されます。これには実際のカード、配色セマンティック図(10 個の色がそれぞれどこに使われるか、現在のパターンが実際にどのように見えるか)、その配色でのステッカーの見え方、WCAG コントラスト/明暗一貫性診断が含まれます。プレビューはメモリ上でのみ読み取り専用で、config/themes.json に書き込まれることはありません。満足したら「設定を保存」をクリックして初めてディスクに書き込まれます。
同一ドメインサブパスデプロイ(クラウドサーバー)
フロントエンド URL はすべて web/app.js 上部のランタイム BASE から派生(document.baseURI)。ソースコードにはドメインルートパスをハードコードしません。index.html の style.css / app.js も相対パスを使用。API を独立したドメインに向ける必要がある場合は、app.js 読み込み前に window.DAILY_CARD_BASE を設定。nginx が /daily-card/api/* のプレフィックスを /api/* に剥ぎ取るため、バックエンドルートの変更は不要です。
| コマンド | 説明 |
|---|---|
./scripts/publish-web.sh | web/ をバージョンディレクトリに公開し、current シンボリックリンクをアトミックに切り替え |
./scripts/publish-web.sh --list | 公開済みバージョンと現在のリンク先を表示 |
./scripts/publish-web.sh --rollback [ver] | 瞬時にロールバック、Python の再起動不要 |
./scripts/test_subpath.py | プロセス内で nginx のプレフィックス剥ぎ取りをシミュレート、10 項目の連鎖アサーション |
フロントエンド静的バージョンはバックエンドとは独立してリリース/ロールバック可能。DAILY_CARD_WEB_ROOT(デフォルト /opt/daily-card-web)と DAILY_CARD_WEB_KEEP(デフォルト 5)で上書き可能。末尾スラッシュは必須:/daily-card は 301 で /daily-card/ にリダイレクトする必要があります。そうしないと相対パスがドメインルートに解決されてしまいます。完全な nginx 設定、systemd、キャッシュ、認証については docs/DEPLOY.md を参照。
agent がリモートインターフェースを呼び出す場合、DAILY_CARD_URL はプレフィックスまで入力します。例えば https://host/daily-card。コードは https://host/daily-card/api/save に結合します。ベアのドメイン名を入力しないでください。
JSON インターフェース(agent はブラウザ不要で直接呼び出し可能)
| インターフェース | 説明 |
|---|---|
GET /api/health | ヘルスチェック:バージョン、実行モード、設定ディレクトリ(フロントエンド起動不要) |
GET /api/bootstrap | themes_doc / settings / registry / platforms / パスを一度に取得 |
POST /api/render | プレビュー生成、{png: dataURL, path, theme, size, bytes} を返す |
POST /api/save | 生成して output/ に書き込み、ディスクパスを返す |
POST /api/theme-preview | 未保存のテーマ草案 → カード + セマンティック図 + ステッカー表示 + 可読性診断、設定ファイルには書き込まない |
POST /api/schemes | 背景画像 → 複数の配色スキーム。{"path":"/abs/bg.jpg"} または {"image":"data:image/png;base64,..."} を送信 |
GET /api/schemes?image_id=xxx | アップロード済み画像のスキームを再取得 |
POST /api/config/themes | {"themes_doc": {...}} テーマ設定を保存(検証あり) |
POST /api/config/settings | {"settings": {...}} グローバル設定を保存 |
POST /api/config/reset | 出荷時テーマにリセット(プライベートテーマを上書きします。事前にバックアップしてください) |
POST /api/reveal | 出力フォルダを開く |
GET /api/sticker?id=book&theme=study | ステッカーアイコン PNG |
/api/render と /api/save のリクエストボディ:
{
"title": "今日もいい一日を",
"subtitle": "普通の日々をもっと輝かせよう",
"platform": "xhs",
"theme": "auto",
"date": null,
"brand": "Claw · 每日一句",
"seed": null,
"bg_image_id": null,
"bg_path": "./bg.jpg",
"bg_scheme": 0,
"dark_override": null
}
bg_schemeは整数インデックスまたは#RRGGBBを指定可能;dark_overrideがtrue/falseの場合は強制的に明/暗カード、nullの場合は画像の判断に従う。bg_image_idは/api/schemesが返す値;直接bg_pathでサーバーがアクセス可能なパスを指定しても良い。- 返される
pngはdata:image/png;base64,...形式のため、デコードしてからファイルに書き込む。
例(DAILY_CARD_URL が未設定の場合はローカルを使用):
DC_URL="${DAILY_CARD_URL:-http://127.0.0.1:8777}"
curl -s "$DC_URL/api/save" \
-H 'Content-Type: application/json' \
-d '{"title":"今日もいい一日を","subtitle":"日々をもっと輝かせよう","platform":"xhs"}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["path"])'
テーマ草案プレビュー / 配色診断(保存前の確認)
設定に書き込む前に配色が良いかどうか、文字が読めるかどうかを判断したい場合、/api/theme-preview を呼び出します。theme は完全なテーマ草案で、サーバー側はメモリ上でのみ保持:
{
"theme": {
"label": "MY THEME · 新しいテーマ",
"keywords": ["打卡"],
"motif": "dots",
"dark": false,
"colors": {
"bg1": "#F7E9C8", "bg2": "#EED6A4", "card": "#FFFCF6",
"ink": "#2E3A2C", "sub": "#6D7570", "accent": "#E0703C",
"accent2": "#5D8B6A", "soft": "#F1D9A8", "pill": "#2E3A2C",
"pill_text": "#FFFDF5"
},
"stickers": ["book", "pencil", "sun"]
},
"title": "サンプルタイトル",
"subtitle": "サンプルサブタイトル",
"platform": "moments",
"date": "2026-11-11",
"seed": 7
}
返却フィールド(card / legend / stickers / sticker_sheet はすべて data:image/png;base64,...):
| フィールド | 意味 |
|---|---|
card | この草案で実際にレンダリングされたカード |
legend | セマンティック配色図:実際のパターン + カード階層 + 10 個の色がそれぞれ何を担当するか |
stickers | 選択されたステッカーの現在の配色での見え方 |
sticker_sheet | 全ステッカーのスプライト、sheet(cols/rows/cell/order)と組み合わせてスライス表示 |
diagnostics | [{level: ok/warn/tip, text: 中国語説明}] |
contrast | 各コントラスト値(ink_card / sub_card / pill_pair / card_bg / accent_bg / bg_light) |
motif / dark / draft_only | パターン名と説明、明暗フラグ、常に true で未保存を示す |
diagnostics は WCAG コントラストチェックを実行:メイン文字/サブ文字/ラベル文字の可読性、カードと背景の差別化、アクセントカラーが十分に目立つか、「背景が非常に暗いのにライトテーマに設定している」ような矛盾。推奨フロー:まず草案を POST して診断を確認 → warn があれば診断に従って色を修正して再実行 → warn が無くなったら /api/config/themes を呼び出して保存。
バックエンドを起動しない場合でも、モジュールを直接呼び出せます:
import base64, cardconfig as cfg, cardpreview as cp
draft = cfg.load_doc()["themes"]["study"] # ネスト構造、colors を含む
draft["colors"]["accent"] = "#C2185B" # 変更して確認
r = cp.build_preview({"theme": draft, "title": "サンプル", "subtitle": "サブタイトル"})
for it in r["diagnostics"]:
print(it["level"], it["text"])
open("/tmp/draft-card.png", "wb").write(base64.b64decode(r["card"].split(",", 1)[1]))
更新とマルチエンド同期
唯一のバージョン真実源は git リポジトリであり、その他のエンドはすべて派生で、一方向にのみ流出:
| エンド | 更新方法 | プライベート設定 |
|---|---|---|
| ローカル / クラウドサーバー | git pull && ./install.sh | 影響なし、上書きされない |
| クラウドサーバーフロントエンド静的バージョン | ./scripts/publish-web.sh、--rollback で瞬時にロールバック可能 | Python サービスから独立、再起動不要 |
| ローカル skill 登録 | ./scripts/install.sh --link-skill でシンボリックリンク作成、ファイルコピーのずれを防止 | 影響なし |
| skillhub などのプラットフォームスナップショット | メンテナーがタグを打った後に再インポート、自然にバージョン遅れあり | プラットフォームは出荷時テンプレートのみ取得 |
出荷時テンプレート themes.default.json はバージョン更新に伴い更新されます。利用者プライベートの themes.json は決して上書きされません。新しい出荷時テーマを自分の設定に統合する必要がある場合、手動で themes.default.json から該当エントリをコピーするか、バックエンドで「JSON エクスポート → マージ → インポート」を使用してください。--init-config / /api/config/reset は直接実行しないでください。
サーバーデプロイと CI/CD 連携の説明は docs/DEPLOY.md を参照。scripts/selfcheck.sh は全 8 ステップで、フロントエンドパスの移植性チェックとサブパスデプロイシミュレーション(プロセス内でプロキシを起動、実際の nginx は不要)を含みます。
Agent 推奨ワークフロー
- ユーザーの発言からタイトルとサブタイトルを抽出(サブタイトルがない場合は、文脈に合った短い文章を補足するか、空欄のままにする)。
- プラットフォームを判断:指定がない場合は
xhs;微信公衆号が言及されたらwechat、WeChat モーメンツならmoments。 - ユーザーが背景画像を提供した場合:まず
--list-schemesまたは/api/schemesで候補を確認し、選択後に生成。指定がなければスキーム 0 を使用。 - CLI を実行(サービス不要)。ユーザーが明示的にバックエンド/リモートを要求した場合のみ
/api/saveを呼び出す。 present_filesで完成画像をユーザーに提示。レスポンス内でテーマ、サイズ、日付、配色スキームを説明。- スタイル変更の希望 →
config/themes.jsonまたはバックエンド設定パネルを編集。cardgen.pyは変更しない。
注意事項
- コードの役割分担:
cardgen.pyはレンダリングのみ担当、cardconfig.pyは設定読み込み/保存/配色抽出、cardpreview.pyはテーマ草案プレビューと配色診断、server.pyはバックエンド。すべて同一のconfig/*.jsonを読み込む。 output/、uploads/、config/themes.json、config/settings.json、.envはすべて.gitignoreで無視。examples/はデモ完成画像(約 6.7 MB、実行には不要、削除可能)。- テーマ ID は英数字、
-、_のみ許可。色は#RRGGBB形式である必要あり。ステッカー ID はconfig/stickers.jsonに存在していなければならない。 - 画像サイズが大きいほど、スーパーサンプリングが高いほど遅くなる。デフォルトの 2x スーパーサンプリングで十分な鮮明さ。
server.pyは認証ゼロでデフォルトでは127.0.0.1のみをリッスン。公開デプロイ前には必ずリバースプロキシ認証または IP ホワイトリストを追加。クラウドデプロイでは--api-onlyを使用して API のみを公開。詳細はdocs/DEPLOY.mdを参照。- ソースコード内に
src="/..."/href="/..."/"/api/..."のようなドメインルート絶対パスを出現させてはならない。selfcheck.shがこのような回帰をブロック。すべてのリクエストは統一してurl()経由とする。
既知の制限 / 次バージョン計画
- ステッカーのカスタムアップロード不可(現バージョン):ステッカーは
config/stickers.jsonに登録された 28 個のベクターステッカーのみから選択可能。独立したステッカーライブラリ管理モジュールはなく、PNG/SVG のステッカーアップロードもサポートしない。形状を追加するには、現在は開発者がcardgen.pyでs_xxx描画関数を追加し、stickers.jsonに登録する必要がある。 - 次バージョン計画:カスタムステッカーアップロード(PNG/SVG、自動配色抽出によるテーマ適応)、ステッカーライブラリ管理パネル(追加/削除/編集/グループ化/プレビュー/再利用)、ステッカーとテーマの分離。ユーザーからはこの機能は次バージョンに明確に設定されており、今回のリリースでは含まれない。
- テーマ草案プレビューはレスポンス高速化のため 1x スーパーサンプリングを使用。最終的な 2x 出力とはごく細かい部分で若干の差異が生じる可能性があるが、レイアウトと配色は一致する。