mcpField
L
lovstudio-maintain-partners

lovstudio-maintain-partners

github.com/lovstudioデザイン・UI7368 回インストール今日更新
リポジトリ

lovstudio-maintain-partners について

LovStudio の Web サイトリポジトリにあるパートナー欄を保守するスキルです。パートナーの追加、ロゴの調整、多言語のタグライン更新、項目の監査を支援します。

主な機能

  1. 01パートナーと多言語タグラインの追加
  2. 02ロゴ画像の調整や差し替え
  3. 03ロゴ、翻訳キー、リンクの監査
  4. 04サイトとパートナーファイルの特定

活用シーン

  1. 01サイトに新しいパートナーを追加
  2. 02既存ロゴのサイズや視認性を修正
  3. 03リリース前にパートナー欄を確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lovstudio/skills --skill lovstudio-maintain-partners

インストール後、Claude Code で/lovstudio-maintain-partnersを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

.gitignore
CHANGELOG.md
README.md
references/
user-config.md
scripts/
add_partner.py
audit_partners.py
normalize_logo.py

詳細

maintain-partners — LovStudio パートナーズセクションのメンテナンス

設定されたウェブサイトリポジトリをメンテナンスします。パスは --repo、 LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT、または共有ユーザープロファイルから解決します。パートナー一覧は通常、 app/(main)/(home)/PartnersGrid.tsx の PARTNERS: Partner[] 配列にあります。古いサイトでは、 app/(main)/(home)/WorkshopDispatch.tsx にある場合もあります。ロゴは public/partners/<slug>/logo.png に、タグラインは src/i18n/messages/{zh-CN,en,ja,th}.json の dispatch.partner*Tagline の下にあります。

ユーザー設定

ファイルを操作する前に、以下を解決します。

SKILL_ROOT="${LOVSTUDIO_SKILLS_INSTALL_DIR:?Set LOVSTUDIO_SKILLS_INSTALL_DIR}"
SKILL_DIR="${SKILL_DIR:-$SKILL_ROOT/lovstudio-maintain-partners}"
WEB_ROOT="${LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT:?Set this or pass --repo}"
PARTNERS_TSX="${LOVSTUDIO_MAINTAIN_PARTNERS_FILE:-app/(main)/(home)/PartnersGrid.tsx}"

ウェブサイトのルートには、以下の優先順位を使用します。

  1. add_partner.py/audit_partners.py で明示的に指定された --repo <path>。
  2. LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT。
  3. ${LOVSTUDIO_SKILLS_PROFILE:-$HOME/.lovstudio/skills/profile.json} にある共有プロファイル JSON。

LOVSTUDIO_WEB_ROOT と PARTNERS_SITE_ROOT はレガシーエイリアスとして使用できますが、 再利用可能なスキルの公開コントラクトとしては使用しないでください。

パートナー TSX ファイルには、以下の優先順位を使用します。

  1. 明示的に指定された --partners-file <path>。
  2. LOVSTUDIO_MAINTAIN_PARTNERS_FILE。
  3. 共有プロファイルのキー sites.partners_file、lovstudio.partners_file、 partners.file、または workspace.partners_file。
  4. app/(main)/(home)/PartnersGrid.tsx、次にレガシーの app/(main)/(home)/WorkshopDispatch.tsx。

LOVSTUDIO_PARTNERS_FILE と PARTNERS_FILE はレガシーエイリアスとして使用できますが、 再利用可能なスキルの公開コントラクトとしては使用しないでください。

詳細とサポートされているプロファイルキーについては、references/user-config.md をお読みください。

スキルの依存関係

  • すべてのロゴ検索には lovstudio-find-logo が必要です。このスキルで ホームページをスクレイピングしたり、別のフォールバッククローラーを 用意したりしてはいけません。
  • スキルレベルの依存関係は、フロントマターの depends_on フィールドで宣言してください。 これは lovstudio-general-skills/skills.yaml の depends_on フィールドに対応するものです。 依存関係のメタデータを読み取らないエージェントでは、未知のフロントマターキーは無視される想定です。

使用する場面

  • ユーザーが新しいパートナーの追加を依頼した場合(ロゴの URL の有無は問いません)。
  • ユーザーがロゴの標準化/正規化を依頼した場合(サイズが違う、白地に白抜きなど)。
  • ユーザーがローカルファイルを渡し、既存のパートナーのロゴの差し替えを依頼した場合。
  • ユーザーがリリース前にパートナーセクションの監査を依頼した場合。

基準

  • ロゴのキャンバスサイズ:ウェブサイトのパートナー一覧ではコンテンツの高さを80pxにします (明るいグレースケール、CSS の height: 32px に対して約 2.5 倍の密度で、十分に鮮明です)。 イベントポスターや scale: 2 以上で書き出すあらゆる Retina 画像では240pxにします。
  • 透明背景に白抜きのロゴは、明るいグレースケールの一覧で見えるよう、全体または一部を反転します。
  • 正規化後の幅が約 40px 未満になるアイコンのみのロゴを追加する場合は、ブランド名をアイコンの横に表示するため --show-name を指定します。
  • タグラインの形式:中国語では <ブランド名> · <一言の説明> とします。en/ja/th も同じスタイルにします。

ワークフロー

操作 1:新しいパートナーを追加する
  1. AskUserQuestion で、ブランド名とホームページ URL をユーザーに尋ねます。
  2. lovstudio-find-logo でロゴを収集します。
    python3 "$SKILL_ROOT/lovstudio-find-logo/scripts/find_logo.py" \
      --name "<显示名>" --url <URL> --slug <slug> --json
    
    ~/.lovstudio/logo-collection/<slug>/logo.<ext> に保存された主要アセットを使用します。find_logo.py から候補が返されない場合は、処理を中断し、公式 URL またはプレスキットの URL をユーザーに確認してから、find_logo.py を再実行します。このスキルからローカルスクレイパーを呼び出してはいけません。
  3. 正規化する前に、保存された主要アセットを目視で確認します。
  4. 主要アセットが SVG の場合は、正規化の前にラスタライズします。
    rsvg-convert -h 240 ~/.lovstudio/logo-collection/<slug>/logo.svg \
      -o /tmp/<slug>-raw.png
    
    ラスタライズした /tmp/<slug>-raw.png を --src として使用します。SVG 以外のソースでは、保存された主要アセットをそのまま使用します。
  5. 正規化します。
    python3 "$SKILL_DIR/scripts/normalize_logo.py" \
      --src <archived-or-rasterized-logo> \
      --dst "$WEB_ROOT/public/partners/<slug>/logo.png" \
      --invert auto
    
  6. 正規化した PNG を読み込み、見えること(白地に白抜きではないこと)を確認します。
  7. PARTNERS と 4 つすべてのロケール JSON に追加します。
    python3 "$SKILL_DIR/scripts/add_partner.py" \
      --repo "$WEB_ROOT" \
      --partners-file "$PARTNERS_TSX" \
      --name "<显示名>" --href "<URL>" \
      --logo "/partners/<slug>/logo.png" \
      --key partner<Slug>Tagline \
      --category community \
      --zh "..." --en "..." --ja "..." --th "..." \
      [--show-name]
    
操作 2:既存のロゴを正規化する
python3 "$SKILL_DIR/scripts/normalize_logo.py" \
  --src public/partners/<slug>/logo.png \
  --dst public/partners/<slug>/logo.png \
  --invert auto

処理後に再度読み込み、確認します。

Op 3: ユーザー提供ファイルからロゴを差し替える

ソースファイルのパスを直接尋ねるか、ユーザーが設定した ワークスペース/プロファイルから読み取ってください。非公開のパートナー用フォルダーにあると決めつけないでください。

python3 "$SKILL_DIR/scripts/normalize_logo.py" \
  --src "<user-provided path>" \
  --dst "$WEB_ROOT/public/partners/<slug>/logo.png" \
  --invert auto

JPEG 入力は、トリミング前にほぼ白い背景を自動で削除し、透明にします。

Op 4: 監査
python3 "$SKILL_DIR/scripts/audit_partners.py" \
  --repo "$WEB_ROOT" \
  --partners-file "$PARTNERS_TSX"
# add --probe to also HTTP-check every href (slow, requires proxy)

レポート内容:ロゴファイルの不足、ロケールごとの i18n キーの不足、リンク切れの URL。

Op 5: パートナーロゴの行を揃える(アセット間の視覚的な高さを統一)

対象:3 つ以上のパートナーロゴを横一列に並べ、CSS の height が同じなのにサイズが違って見える場合です。イベントポスター、ヒーローセクション、「联办 / co-host」の行などでよく見られます。

根本原因:ソースファイルごとに内部の余白(デザイナーがキャンバスに設けたマージン)が異なるため、どちらも height: 24px に設定した PNG でも、コンテンツがキャンバスに占める割合が異なり、実際に見える高さに差が出ます。目視したコンテンツの比率に基づいてロゴごとに CSS の高さを調整しても安定せず、ディスプレイや拡大縮小率が異なると再びずれます。

確実な修正方法 — ファイルレベルでトリミングし、CSS のボックスを統一する:

  1. すべてのロゴを正規化して、コンテンツの高さを揃えます。ラスター画像ファイルの既定の目標サイズは 240px です(scale: 2 でポスターを Retina 向けに書き出す場合の 3 倍密度です。80px では 1.7 倍にしかならず、PNG 書き出し後にぼやけます)。ソースがすでに透明背景に明るいロゴの場合は、二重反転を避けるため --invert off を使います。

    for f in lujiazui juanyi citic-bookstore citic-thinker-lab; do
      python3 "$SKILL_DIR/scripts/normalize_logo.py" \
        --src "<configured-partners-source>/<brand>/<file>.png" \
        --dst <event-assets>/partners/$f.png \
        --height 240 --invert auto
    done
    

    必ず元のソースから正規化し、以前に正規化した 80px のファイルからは行わないでください(拡大するとぼやけます。juanyi で実際に失敗しました)。

  2. SVG ソースは、最初にラスター化します。normalize_logo.py はラスター画像のピクセルを処理するため、SVG の viewBox の余白はトリミングできません。この手順を省くと、SVG は常にラスター化した PNG のロゴより小さく表示されます。

    rsvg-convert -h 720 brand.svg -o /tmp/brand-raw.png   # 3× of 240
    python3 "$SKILL_DIR/scripts/normalize_logo.py" \
      --src /tmp/brand-raw.png --dst <event-assets>/partners/brand.png \
      --height 240 --invert off
    

    rsvg-convert は librsvg に含まれています(brew install librsvg)。

  3. 背景の矩形が埋め込まれた SVG の場合(黒や色付きの角丸四角形で囲まれたアイコン。find-logo のアプリアイコン風 SVG でよく見られます)は、ラスター化の前に背景を削除してください。そうしないと、フィルター brightness(0) invert(1) で背景が不透明な白いブロックになり、アイコンが隠れてしまいます。

    # Drop the outer <rect fill="#000"...> wrapper
    sed -E 's|<rect[^/]*fill="#0+"[^/]*/>||' brand.svg > /tmp/brand-clean.svg
    rsvg-convert -h 720 /tmp/brand-clean.svg -o /tmp/brand-raw.png
    
  4. 各ロゴを固定サイズのボックスで囲みます(自動幅の flex より推奨)。

    <span class="ps-logo-box"><img src="..." class="ps-logo"></span>
    
    .ps-logo-box {
      width: 96px; height: 30px;             /* fixed grid cell */
      display: inline-flex;
      align-items: center; justify-content: center;
      border: 1px solid rgba(255,255,255,0.10);
      border-radius: 4px;
      padding: 3px 6px;
      box-sizing: border-box;
    }
    .ps-logo { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }
    

    固定ボックスにすると、安定したマトリックス状の見た目になります。アイコンのみの幅の狭いロゴも、アイコンとワードマークを含む幅の広いロゴも、アセットをボックスに合わせて拡大縮小することで同じ領域に収まります。自動幅の flex(以前の方法)では、ロゴの追加や削除に伴って行全体の幅が予測できなくなります。

  5. 暗い背景で統一する — 行が暗いキャンバス(イベントポスターなど)に置かれる場合、ブランドロゴの多くは白い背景向けにデザインされているため、見た目に統一感がなくなります(黒い文字のロゴもあれば、ブランドカラーのマークもあります)。安定した方法は次のとおりです。

    .ps-logo { filter: brightness(0) invert(1) opacity(0.88); }
    /* logos already white-on-transparent — opt out of inversion */
    .ps-logo.ps-logo-original { filter: opacity(0.88); }
    

    brightness(0) ですべての色を黒にし、続く invert(1) で設定した不透明度の均一な白にします。.ps-logo-original は、すでに透明背景に白いロゴがあるソースファイル(ブランドキットの白い SVG バリエーションなど)向けの例外指定です。二重処理によって、暗い背景に黒いロゴが表示されなくなるのを防ぎます。

  6. アイコンのみの SVG → アイコンとワードマークの合成 — ブランドの SVG にアイコンしかなく、「BrandName」のワードマークが隣にない場合、96×30 のボックスにアイコンだけを配置して公開しないでください(何のロゴか判別できなくなります)。可能であればブランド独自のフォントを使い、PIL でワードマークを合成します。

    from PIL import Image, ImageDraw, ImageFont, ImageOps
    # 1. rasterize cleaned SVG, invert white→black so default filter works
    icon = Image.open('/tmp/brand-icon.png').convert('RGBA')
    r, g, b, a = icon.split()
    inv = Image.merge('RGB', (ImageOps.invert(r), ImageOps.invert(g), ImageOps.invert(b)))
    icon = Image.merge('RGBA', (*inv.split(), a))
    icon = icon.crop(icon.getbbox())
    target_h = 240
    icon = icon.resize((int(icon.width * target_h / icon.height), target_h), Image.LANCZOS)
    # 2. render wordmark in brand font (find-logo bundles fonts/ when found)
    font = ImageFont.truetype('partners/<brand>/fonts/<Family>.ttf', 150)
    # 3. compose icon + gap + text on transparent canvas
    

    PNG はラスター画像ロゴと同じ brightness(0) invert(1) フィルターを通るため、他のすべてのロゴと色が自動的に揃います。ブランド独自のフォントを使ってください(多くの場合、find-logo スキルの <brand>/fonts/ にあります)。ブランドフォントがない場合に限り、システムの SF/Helvetica を使います。

  7. アンチパターン — ロゴごとに高さを設定して揃えようとしないでください。たとえば .ps-logo-juanyi { height: 26px } のような指定です。壊れやすく(ロゴを追加するたびに新たな任意の数値が必要になります)、ブラウザーによって結果が安定せず、デザイナーが余白の異なるアセットを再納品した途端に崩れます。

CLI リファレンス

normalize_logo.py
フラグデフォルト備考
--src必須入力画像(PNG/JPG/ラスタライズされた SVG)
--dst必須出力 PNG パス。親ディレクトリは自動作成されます
--height80コンテンツの目標高さ。Retina 向けのポスターをエクスポートする場合は 240 を使用してください(scale: 2)。80 では 2 倍に縮小した後にぼやけます
--invertautoauto / off / full / selective(selective は色付きアイコンを保持します)
add_partner.py
フラグ備考
--repoWeb サイトのリポジトリルート。デフォルトでは、LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT、profile JSON、または従来の LOVSTUDIO_WEB_ROOT / PARTNERS_SITE_ROOT を使用します
--partners-filePARTNERS TSX ファイル。デフォルトでは、LOVSTUDIO_MAINTAIN_PARTNERS_FILE、profile JSON、従来の LOVSTUDIO_PARTNERS_FILE / PARTNERS_FILE、PartnersGrid.tsx、または WorkshopDispatch.tsx を使用します
--name表示名(CJK 可)
--hrefブランド URL
--logo/public 以下のパス。例:/partners/foo/logo.png
--keyi18n キー。例:partnerFooTagline
--categorycompute / peer / invest / media / community。デフォルトは community
--zh / --en / --ja / --thタグライン文字列(すべて必須)
--show-name横幅の狭いロゴでは、アイコンの横に名前を表示します
audit_partners.py
フラグ備考
--repoWeb サイトのリポジトリルート。デフォルトでは、LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT、profile JSON、または従来の LOVSTUDIO_WEB_ROOT / PARTNERS_SITE_ROOT を使用します
--partners-filePARTNERS TSX ファイル。デフォルトでは、LOVSTUDIO_MAINTAIN_PARTNERS_FILE、profile JSON、従来の LOVSTUDIO_PARTNERS_FILE / PARTNERS_FILE、PartnersGrid.tsx、または WorkshopDispatch.tsx を使用します
--probeすべての href に HTTP プローブを実行します(時間がかかり、プロキシ環境変数が必要です)

ネットワークプロキシ

サンドボックスの子プロセスには、システムの ClashX プロキシが引き継がれません。lovstudio-find-logo でロゴを取得したり、パートナーの URL をプローブしたりする前に、次をエクスポートしてください。

export https_proxy=http://127.0.0.1:7890 \
       http_proxy=http://127.0.0.1:7890 \
       all_proxy=socks5://127.0.0.1:7891

audit_partners.py は、curl の呼び出し時にこれらをすでに設定しています。

依存関係

git clone https://github.com/lovstudio/find-logo-skill \
  "${LOVSTUDIO_SKILLS_INSTALL_DIR:?Set LOVSTUDIO_SKILLS_INSTALL_DIR}/lovstudio-find-logo"
python3 -m pip install Pillow
brew install librsvg  # for SVG logo sources

コメント