关于 lovstudio-maintain-partners
用于维护 LovStudio 网站合作伙伴板块的技能,面向负责添加、规范化或审核合作伙伴信息的维护者。它涵盖标志处理、伙伴列表和多语言标语更新及审计。
主要功能
- 01添加合作伙伴及多语言标语
- 02规范化或替换标志图像
- 03审计标志、翻译键和链接
- 04按配置定位网站及伙伴文件
适用场景
- 01将新合作伙伴加入网站展示
- 02修正已有标志的尺寸或可见性
- 03发布前检查合作伙伴板块
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lovstudio/ skills --skill lovstudio-maintain-partners安装后在 Claude Code 中输入/lovstudio-maintain-partners确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreCHANGELOG.mdREADME.mdreferences/user-config.mdscripts/add_partner.pyaudit_partners.pynormalize_logo.py详细介绍
maintain-partners — 维护 LovStudio 合作伙伴板块
维护已配置的网站仓库。按 --repo、
LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT 或共享用户配置文件解析路径。合作伙伴
栏通常位于 app/(main)/(home)/PartnersGrid.tsx,作为 PARTNERS: Partner[] 数组;较旧的网站可能仍将其放在
app/(main)/(home)/WorkshopDispatch.tsx 中。Logo 位于
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}"
网站根目录按以下优先级确定:
add_partner.py/audit_partners.py上明确指定的--repo <path>。LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT。- 共享配置文件 JSON,路径为
${LOVSTUDIO_SKILLS_PROFILE:-$HOME/.lovstudio/skills/profile.json}。
LOVSTUDIO_WEB_ROOT 和 PARTNERS_SITE_ROOT 可作为旧版别名接受,
但不应作为可复用技能的公开约定。
合作伙伴 TSX 文件按以下优先级确定:
- 明确指定的
--partners-file <path>。 LOVSTUDIO_MAINTAIN_PARTNERS_FILE。- 共享配置文件中的
sites.partners_file、lovstudio.partners_file、partners.file或workspace.partners_file。 - 先查找
app/(main)/(home)/PartnersGrid.tsx,再查找旧版app/(main)/(home)/WorkshopDispatch.tsx。
LOVSTUDIO_PARTNERS_FILE 和 PARTNERS_FILE 可作为旧版别名接受,
但不应作为可复用技能的公开约定。
详情及支持的配置文件键,请阅读 references/user-config.md。
技能依赖
- 所有 Logo 查找都必须使用
lovstudio-find-logo。本技能不得自行抓取首页内容, 也不得保留独立的备用爬虫。 - 使用
depends_onfrontmatter 字段声明技能级依赖。这与lovstudio-general-skills/skills.yaml中的depends_on字段一致; 不使用依赖元数据的 Agent 应会忽略未知的 frontmatter 键。
使用场景
- 用户要求添加一个或多个新合作伙伴(可提供或不提供 Logo URL)。
- 用户要求标准化 / 规范化 Logo(尺寸错误、白色 Logo 融入白底等)。
- 用户提供本地文件,并要求替换现有合作伙伴的 Logo。
- 用户要求在发布前审查合作伙伴板块。
标准
- Logo 画布:网站合作伙伴栏的内容高度为 80px
(浅色灰度显示,CSS
height: 32px,约为 2.5× 密度,足够清晰); 活动海报或任何scale: 2及以上的视网膜屏导出图为 240px。 - 对于白色且背景透明的 Logo:进行整体或局部反色,使其能在浅色灰度栏中显示。
- 对于规范化后宽度小于约 40px 的纯图标 Logo:添加时传入
--show-name, 让品牌名称显示在图标旁。 - 标语格式:
<品牌名> · <一句话定位>(中文);en/ja/th 版本保持相同风格。
工作流
操作 1:添加新合作伙伴
- 通过
AskUserQuestion询问用户品牌名称和主页 URL。 - 使用
lovstudio-find-logo收集 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,然后重新运行find_logo.py。不要在本技能中调用本地爬虫。 - 规范化之前,先目视确认归档的主资源文件。
- 如果主资源文件是 SVG,先将其栅格化,再进行规范化:
将栅格化后的rsvg-convert -h 240 ~/.lovstudio/logo-collection/<slug>/logo.svg \ -o /tmp/<slug>-raw.png/tmp/<slug>-raw.png用作--src。对于非 SVG 源文件, 直接使用归档的主资源文件。 - 规范化:
python3 "$SKILL_DIR/scripts/normalize_logo.py" \ --src <archived-or-rasterized-logo> \ --dst "$WEB_ROOT/public/partners/<slug>/logo.png" \ --invert auto - 读取规范化后的 PNG,确认其可见(不是白色融入白底)。
- 追加到 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:规范化现有 Logo
python3 "$SKILL_DIR/scripts/normalize_logo.py" \
--src public/partners/<slug>/logo.png \
--dst public/partners/<slug>/logo.png \
--invert auto
之后重新读取以进行验证。
操作 3:从用户提供的文件替换徽标
直接询问源文件路径,或从用户配置的工作区/个人资料中读取。不要假设存在私有合作伙伴文件夹。
python3 "$SKILL_DIR/scripts/normalize_logo.py" \
--src "<user-provided path>" \
--dst "$WEB_ROOT/public/partners/<slug>/logo.png" \
--invert auto
JPEG 输入会在裁剪前自动去除近白色背景并将其设为透明。
操作 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。
操作 5:对齐一排合作伙伴徽标(跨素材视觉高度一致)
适用情况:将 3 个或更多合作伙伴徽标放在同一水平行中,即使 CSS height 相同,视觉大小仍有差异。常见于活动海报、主视觉区、“联办 / 联合主办”行。
根本原因:每个源文件的内部留白(设计稿画布边距)不同,因此,两个 PNG 即使都设为 height: 24px,渲染出的可见高度也不同,因为内容在画布中所占比例不同。根据目测的内容比例逐个调整 CSS 高度并不可靠——不同显示设备/缩放比例下仍会出现差异。
可靠的修复方法 — 在文件层面裁剪,使用统一的 CSS 框:
-
将所有徽标规范化为相同的内容高度。默认栅格文件的目标尺寸为 240px(
scale: 2时可用于视网膜屏幕海报导出的 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 就是因此吃过亏)。
-
对于 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 offrsvg-convert随librsvg提供(brew install librsvg)。 -
对于包含嵌入式背景矩形的 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 -
将每个徽标放入固定尺寸的框中(建议使用此方法,而不是自动宽度的 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(旧方案)会导致每行总宽度难以预测,尤其是在增删徽标时。
-
统一深色背景上的徽标 — 当这一行位于深色画布上时(例如活动海报),大多数品牌徽标都是为白色背景设计的,显示效果会不一致(有些是黑色文字,有些是品牌色图案)。稳定的方案如下:
.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 变体),以免重复处理后变成深色背景上看不见的黑色图案。 -
仅含图标的 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。 -
反面模式 — 不要尝试通过为每个徽标单独设置高度(例如
.ps-logo-juanyi { height: 26px })来修复对齐问题。这种做法很脆弱(每新增一个徽标就要再加一个神奇数字),在不同浏览器中也不稳定,而且设计师一旦重新提交留白不同的源素材,就会失效。
CLI 参考
normalize_logo.py
| 标志 | 默认值 | 说明 |
|---|---|---|
--src | 必填 | 输入图像(PNG/JPG/栅格化 SVG) |
--dst | 必填 | 输出 PNG 路径;自动创建父目录 |
--height | 80 | 目标内容高度。用于视网膜屏海报导出时请使用 240(scale: 2)——缩小 2 倍后,80 会显得模糊。 |
--invert | auto | auto / off / full / selective(selective 会保留彩色图标) |
add_partner.py
| 标志 | 说明 |
|---|---|
--repo | 网站仓库根目录;默认使用 LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT、配置文件 JSON,或旧版 LOVSTUDIO_WEB_ROOT / PARTNERS_SITE_ROOT |
--partners-file | PARTNERS TSX 文件;默认使用 LOVSTUDIO_MAINTAIN_PARTNERS_FILE、配置文件 JSON、旧版 LOVSTUDIO_PARTNERS_FILE / PARTNERS_FILE、PartnersGrid.tsx 或 WorkshopDispatch.tsx |
--name | 显示名称(可使用 CJK 字符) |
--href | 品牌 URL |
--logo | /public 下的路径,例如 /partners/foo/logo.png |
--key | i18n 键,例如 partnerFooTagline |
--category | compute / peer / invest / media / community;默认值为 community |
--zh / --en / --ja / --th | 标语字符串(均为必填) |
--show-name | 对较窄的 Logo,在图标旁显示名称 |
audit_partners.py
| 标志 | 说明 |
|---|---|
--repo | 网站仓库根目录;默认使用 LOVSTUDIO_MAINTAIN_PARTNERS_SITE_ROOT、配置文件 JSON,或旧版 LOVSTUDIO_WEB_ROOT / PARTNERS_SITE_ROOT |
--partners-file | PARTNERS TSX 文件;默认使用 LOVSTUDIO_MAINTAIN_PARTNERS_FILE、配置文件 JSON、旧版 LOVSTUDIO_PARTNERS_FILE / PARTNERS_FILE、PartnersGrid.tsx 或 WorkshopDispatch.tsx |
--probe | 对每个 href 进行 HTTP 探测(速度较慢,需要代理环境变量) |
网络代理
沙盒子进程不会继承系统 ClashX 代理。使用 lovstudio-find-logo 获取 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