Source profileQuality 91/100Review permissions

lovstudio/skills/skills/maintain-partners/SKILL.md

lov-maintain-partners

Maintain the Skill Publisher website's partners section AND align partner logo rows on event posters / hero strips: reuse lov-find-logo for brand logo discovery, normalize collected logos to a 240px-tall content canvas (retina-ready), rasterize SVGs via rsvg-convert before normalizing (so SVG viewBox padding gets cropped), strip embedded background rects from icon-style SVGs, composite icon + wordmark when only an icon is available (using brand fonts), wrap logos in a fixed-size grid box (96×30

Source repository stars
64
Declared platforms
0
Static risk flags
2
Last source update
2026-08-23
Source checked
2026-08-25

Decision brief

What it does: where it fits

Maintains the configured website repo. Resolve the path from --repo, SKILLMAINTAINPARTNERSSITEROOT, or the shared user profile. The partners strip usually lives in app/(main)/(home)/PartnersGrid.tsx as a PARTNERS: Partner[] array; older sites may still keep it in app/(main)/(hom…

Best for

  • User asks to add one or more new partners (with or without a logo URL).
  • User asks to standardize / normalize a logo (sizing wrong, white-on-white, etc.).
  • User provides a local file and asks to replace an existing partner's logo.

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/lovstudio/skills --skill "skills/maintain-partners"
Safe inspection promptEditorial

Inspect the Agent Skill "lov-maintain-partners" from https://github.com/lovstudio/skills/blob/8f250b126bb7e7eb6db0203c97d8279f75ae152d/skills/maintain-partners/SKILL.md at commit 8f250b126bb7e7eb6db0203c97d8279f75ae152d. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Workflow

    1. Ask the user for the brand name + homepage URL via AskUserQuestion. 2. Collect the logo with lov-find-logo:

    Ask the user for the brand name + homepage URL via AskUserQuestion.Collect the logo with lov-find-logo:Visually verify the archived primary asset before normalizing.
  2. 02

    User Configuration

    Before touching files, resolve:

    Explicit --repo on addpartner.py / auditpartners.py.SKILLMAINTAINPARTNERSSITEROOT.Shared profile JSON at
  3. 03

    Skill Dependencies

    lov-find-logo is required for all logo discovery. This skill must

    lov-find-logo is required for all logo discovery. This skill mustUse the dependson frontmatter field to declare skill-level dependencies.- lov-find-logo is required for all logo discovery. This skill must not scrape homepages itself or keep a separate fallback crawler. - Use the dependson frontmatter field to declare skill-level dependencies. This mirror…
  4. 04

    When to Use

    User asks to add one or more new partners (with or without a logo URL).

    User asks to add one or more new partners (with or without a logo URL).User asks to standardize / normalize a logo (sizing wrong, white-on-white, etc.).User provides a local file and asks to replace an existing partner's logo.
  5. 05

    Standards

    Logo canvas: 80px content height for the website partners strip

    Logo canvas: 80px content height for the website partners stripFor white-on-transparent logos: invert (full or selective) so they show onFor icon-only logos < 40px wide after normalization: pass --show-name

Permission review

Static risk signals and limitations

Runs scripts

medium · line 80

The documentation asks the agent to run terminal commands or scripts.

python3 "$SKILL_ROOT/lov-find-logo/scripts/find_logo.py" \

Runs scripts

medium · line 97

The documentation asks the agent to run terminal commands or scripts.

python3 "$SKILL_DIR/scripts/normalize_logo.py" \

Network access

medium · line 303

The documentation includes network, browsing, or remote request actions.

export https_proxy=http://127.0.0.1:7890 \

Network access

medium · line 304

The documentation includes network, browsing, or remote request actions.

http_proxy=http://127.0.0.1:7890 \

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score91/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars64SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
lovstudio/skills
Skill path
skills/maintain-partners/SKILL.md
Commit
8f250b126bb7e7eb6db0203c97d8279f75ae152d
License
MIT
Collected
2026-08-25
Default branch
main
View the original SKILL.md

maintain-partners — Skill Publisher 合作伙伴板块维护

Maintains the configured website repo. Resolve the path from --repo, SKILL_MAINTAIN_PARTNERS_SITE_ROOT, or the shared user profile. The partners strip usually lives in app/(main)/(home)/PartnersGrid.tsx as a PARTNERS: Partner[] array; older sites may still keep it in app/(main)/(home)/WorkshopDispatch.tsx. Logos live in public/partners/<slug>/logo.png; taglines in src/i18n/messages/{zh-CN,en,ja,th}.json under dispatch.partner*Tagline.

User Configuration

Before touching files, resolve:

SKILL_ROOT="${SKILL_SKILLS_INSTALL_DIR:?Set SKILL_SKILLS_INSTALL_DIR}"
SKILL_DIR="${SKILL_DIR:-$SKILL_ROOT/lov-maintain-partners}"
WEB_ROOT="${SKILL_MAINTAIN_PARTNERS_SITE_ROOT:?Set this or pass --repo}"
PARTNERS_TSX="${SKILL_MAINTAIN_PARTNERS_FILE:-app/(main)/(home)/PartnersGrid.tsx}"

Use this precedence for the website root:

  1. Explicit --repo <path> on add_partner.py / audit_partners.py.
  2. SKILL_MAINTAIN_PARTNERS_SITE_ROOT.
  3. Shared profile JSON at ${SKILL_PROFILE_PATH:-$HOME/.skill-publisher/skills/profile.json}.

SKILL_WEB_ROOT and PARTNERS_SITE_ROOT are accepted as legacy aliases, but should not be the public contract for reusable skills.

Use this precedence for the partners TSX file:

  1. Explicit --partners-file <path>.
  2. SKILL_MAINTAIN_PARTNERS_FILE.
  3. Shared profile keys sites.partners_file, skill-publisher.partners_file, partners.file, or workspace.partners_file.
  4. app/(main)/(home)/PartnersGrid.tsx, then legacy app/(main)/(home)/WorkshopDispatch.tsx.

SKILL_PARTNERS_FILE and PARTNERS_FILE are accepted as legacy aliases, but should not be the public contract for reusable skills.

For details and supported profile keys, read references/user-config.md.

Skill Dependencies

  • lov-find-logo is required for all logo discovery. This skill must not scrape homepages itself or keep a separate fallback crawler.
  • Use the depends_on frontmatter field to declare skill-level dependencies. This mirrors the depends_on field in lov-general-skills/skills.yaml; unknown frontmatter keys are expected to be ignored by agents that do not consume dependency metadata.

When to Use

  • User asks to add one or more new partners (with or without a logo URL).
  • User asks to standardize / normalize a logo (sizing wrong, white-on-white, etc.).
  • User provides a local file and asks to replace an existing partner's logo.
  • User asks to audit the partners section before a release.

Standards

  • Logo canvas: 80px content height for the website partners strip (light grayscale, CSS height: 32px ≈ 2.5× density, sharp enough), 240px for event posters or any retina export at scale: 2 or higher.
  • For white-on-transparent logos: invert (full or selective) so they show on the light grayscale strip.
  • For icon-only logos < ~40px wide after normalization: pass --show-name when adding so the brand name renders next to the icon.
  • Tagline format: <品牌名> · <一句话定位> in Chinese; mirror style in en/ja/th.

Workflow

Op 1: Add a new partner

  1. Ask the user for the brand name + homepage URL via AskUserQuestion.
  2. Collect the logo with lov-find-logo:
    python3 "$SKILL_ROOT/lov-find-logo/scripts/find_logo.py" \
      --name "<显示名>" --url <URL> --slug <slug> --json
    
    Use the archived primary asset under ~/.skill-publisher/logo-collection/<slug>/logo.<ext>. If find_logo.py returns no candidates, stop and ask the user for a better official URL / press-kit URL, then rerun find_logo.py. Do not call a local scraper from this skill.
  3. Visually verify the archived primary asset before normalizing.
  4. If the primary asset is SVG, rasterize it before normalization:
    rsvg-convert -h 240 ~/.skill-publisher/logo-collection/<slug>/logo.svg \
      -o /tmp/<slug>-raw.png
    
    Use the rasterized /tmp/<slug>-raw.png as --src. For non-SVG sources, use the archived primary asset directly.
  5. Normalize:
    python3 "$SKILL_DIR/scripts/normalize_logo.py" \
      --src <archived-or-rasterized-logo> \
      --dst "$WEB_ROOT/public/partners/<slug>/logo.png" \
      --invert auto
    
  6. Read the normalized PNG to confirm it's visible (not white-on-white).
  7. Append to PARTNERS + all 4 locale JSONs:
    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]
    

Op 2: Normalize an existing logo

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

Re-read after to verify.

Op 3: Replace logo from a user-provided file

Ask for the source file path directly, or read it from the user's configured workspace/profile. Do not assume a private partners folder.

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

JPEG inputs auto-strip near-white background to transparent before crop.

Op 4: Audit

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)

Reports: missing logo files, missing i18n keys per locale, dead URLs.

Op 5: Align a row of partner logos (cross-asset visual height parity)

When: putting 3+ partner logos in a single horizontal strip and they look different sizes despite having the same CSS height. Common in event posters, hero sections, "联办 / co-host" rows.

Root cause: each source file has different internal padding (designer canvas margin), so two PNGs both set to height: 24px render at different visible heights because their content occupies different fractions of the canvas. Per-logo CSS height tweaks based on eyeballed content ratios are unstable—different displays / scaling will diverge again.

Reliable fix — trim at file level, uniform CSS box:

  1. Normalize every logo to identical content height. Default raster file target is 240px (3× density for retina poster export at scale: 2; 80px gives only 1.7× and looks soft after PNG export). Use --invert off if the source is already light-on-transparent (don't double-invert):

    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
    

    Always normalize from the original source, never from a previously normalized 80px file (upscaling = blurry — burned by this on juanyi).

  2. For SVG sources, rasterize first. normalize_logo.py operates on raster pixels and cannot crop SVG viewBox padding. Without this step an SVG always renders smaller than rasterized PNG siblings:

    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 ships with librsvg (brew install librsvg).

  3. For SVG with embedded background rect (icon wrapped in a black/colored rounded square — common in app-icon-style SVGs from find-logo), strip the background before rasterizing, otherwise filter brightness(0) invert(1) flattens it into a solid white block that hides the icon:

    # 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. Wrap each logo in a fixed-size box (recommended over auto-width 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; }
    

    Fixed boxes give a stable matrix look — narrow logos (icon-only) and wide logos (icon + wordmark) all occupy the same footprint, with the asset scaled to fit. Auto-width flex (the older recipe) makes per-row total widths unpredictable as logos get added/removed.

  5. Dark-background unification — when the row sits on a dark canvas (e.g. event poster), most brand logos are designed for white BG and look inconsistent (some have black text, some have brand-colored marks). The stable recipe:

    .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) flattens all colors to black, then invert(1) produces uniform white at the configured opacity. The .ps-logo-original escape hatch is for source files that are already white-on-transparent (white SVG variants from a brand kit) so you don't double-process them into invisible black-on-dark.

  6. Icon-only SVG → composite icon + wordmark — if the brand SVG only has an icon (no "BrandName" wordmark beside it), don't ship just the icon in a 96×30 box (it'll look like an unidentified mark). Compose the wordmark with PIL using the brand's own font when possible:

    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
    

    The PNG goes through the same brightness(0) invert(1) filter as raster logos — match colors with all other entries automatically. Use the brand's own font (often shipped under <brand>/fonts/ by the find-logo skill); fall back to system SF / Helvetica only if no brand font is available.

  7. Anti-pattern — do not try to fix alignment by setting per-logo heights like .ps-logo-juanyi { height: 26px }. It's brittle (every new logo needs another magic number), unstable across browsers, and breaks the moment a designer reships the source asset with different padding.

CLI Reference

normalize_logo.py

FlagDefaultNotes
--srcrequiredinput image (PNG/JPG/rasterized SVG)
--dstrequiredoutput PNG path; parent dirs auto-created
--height80target content height. Use 240 for retina poster export (scale: 2) — 80 looks soft after 2× downscale.
--invertautoauto / off / full / selective (selective preserves colored icons)

add_partner.py

FlagNotes
--repowebsite repo root; defaults to SKILL_MAINTAIN_PARTNERS_SITE_ROOT, profile JSON, or legacy SKILL_WEB_ROOT / PARTNERS_SITE_ROOT
--partners-filePARTNERS TSX file; defaults to SKILL_MAINTAIN_PARTNERS_FILE, profile JSON, legacy SKILL_PARTNERS_FILE / PARTNERS_FILE, PartnersGrid.tsx, or WorkshopDispatch.tsx
--namedisplay name (CJK ok)
--hrefbrand URL
--logopath under /public, e.g. /partners/foo/logo.png
--keyi18n key, e.g. partnerFooTagline
--categorycompute / peer / invest / media / community; default community
--zh / --en / --ja / --thtagline strings (all required)
--show-namerender name next to icon for narrow logos

audit_partners.py

FlagNotes
--repowebsite repo root; defaults to SKILL_MAINTAIN_PARTNERS_SITE_ROOT, profile JSON, or legacy SKILL_WEB_ROOT / PARTNERS_SITE_ROOT
--partners-filePARTNERS TSX file; defaults to SKILL_MAINTAIN_PARTNERS_FILE, profile JSON, legacy SKILL_PARTNERS_FILE / PARTNERS_FILE, PartnersGrid.tsx, or WorkshopDispatch.tsx
--probeHTTP-probe every href (slow, needs proxy env vars)

Network proxy

Sandbox child processes don't inherit the system ClashX proxy. Before fetching logos with lov-find-logo or probing partner URLs, export:

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 already injects these for curl invocations.

Dependencies

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

Runtime context (shared)

运行前读取本 Skill 包的 skill.yaml,由宿主提供 skill-runtime/v1 上下文。字段解析顺序为:当前请求、项目上下文、个人 Preferences、品牌 Profile、通用默认值。

  • 只使用 Manifest 声明的字段;Profile 保存公开品牌事实,Preferences 保存个人工作偏好。
  • required: true 字段缺失时,按 Manifest 的问题配置向用户提出一个聚焦问题;用户明确同意后再保存回答。
  • 报错提供可复制的 context_id、字段路径与来源,诊断内容避开秘密、完整私人路径和原始配置。

通用反馈闭环

用户在 Skill 驱动任务中提出修改意见时,继续当前产物前必须执行:

  1. 先判断意见是 task-specific(仅本次)还是 reusable(可跨任务复用)。
  2. task-specific 只修改当前任务,不改 Skill。
  3. reusable 先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。
  4. 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。
  5. reusable 修改会使此前的“确认”“继续”“发吧”失效;完成当前产物修改和回读后必须停下,等待用户下一步指示,不自动进入发布、提交或其他外部写入。

Frequently asked questions

What to verify before installation and use

What does the lov-maintain-partners source document cover?

Maintains the configured website repo. Resolve the path from --repo, SKILLMAINTAINPARTNERSSITEROOT, or the shared user profile. The partners strip usually lives in app/(main)/(home)/PartnersGrid.tsx as a PARTNERS: Partner[] array; older sites may still keep it in app/(main)/(hom…

How do I install lov-maintain-partners?

The source record exposes this install command: npx skills add https://github.com/lovstudio/skills --skill "skills/maintain-partners". Inspect the command and pinned source before running it.

Which permission-related actions were detected?

Static rules flagged exec-script, network in the source; the page lists the matching lines and excerpts.

Alternatives

Compare before choosing

Computed 9841

respira-press/agent-skills-wordpress

design-system-synthesizer

Use when the user says 'build a design system for my site', 'extract design tokens', 'capture my brand', or 'build my style guide', or after a rebrand. Reads representative pages, theme files, and media to extract logo, colors, typography, spacing, and components, then writes a visible style-guide page.

Computed 9830

MoizIbnYousaf/marketing-cli

higgsfield-generate

Use when the user wants to generate an image or video via Higgsfield AI. Covers 30+ models: Soul V2, Seedance 2.0, Kling 3.0, Veo 3.1, GPT Image 2, Nano Banana 2. Also covers Marketing Studio — branded ad video/image with avatars and products. Use whenever: "generate an image", "make a video", "animate this photo", "image-to-video", "img2vid", "edit this image with AI", "produce a clip", "create an ad", "make a UGC video", "marketing video", "brand video", "TV spot", "import product from URL", "

Computed 9778

KerberosClaw/kc_ai_skills

md2ppt

Use when the user wants to turn a Markdown report into a presentation-quality .pptx via interactive design decisions and a reusable hand-coded build script. Drives pre-analysis, global style choices, optional per-slide layout dialogue, python-pptx composition, and optional LibreOffice render self-check. NOT a generic auto-converter, NOT for PDF output, and NOT a fixed brand-template pipeline — brand integration is handled ad hoc through helper primitives.

Computed 9647

maquina-app/rails-claude-code

mvp-creator

Create comprehensive MVP documentation for Rails applications. Use this skill whenever a user describes a new app idea, wants to explore a SaaS concept, needs competitor research, or is starting a new project from scratch — even if they don't explicitly say "MVP". Triggers on "I have an idea for...", "I want to build...", "help me plan...", "research competitors for...", "create a business plan for...", "design a brand for my app", "set up Claude for my Rails project", "bootstrap an app", or any