CommunityImagengithub.com

daily-card · 社交卡片生成器

Genera tarjetas de estilo social «Frase del día / Check-in» en formato PNG, ideales para WeChat Moments, Cuentas Oficiales, Xiaohongshu y más.

¿Qué es daily-card · 社交卡片生成器?

Esta skill, denominada **daily-card**, permite generar tarjetas visuales estilo «Frase del día» en formato PNG a partir de un título y un subtítulo. Es útil para creadores de contenido, Community Managers y desarrolladores que necesiten producir imágenes atractivas y consistentes para redes sociales como WeChat, Xiaohongshu o historias. La skill se ejecuta completamente en local, sin necesidad de conexión a Internet ni APIs externas, y ofrece control total sobre la tipografía china. Soporta múltiples plataformas con presets de tamaño predefinidos, personalización de temas mediante colores y stickers vectoriales, extracción automática de paletas desde imágenes de fondo y un modo de vista previa en tiempo real a través de un panel web opcional. Está diseñada para integrarse con asistentes como Claude Code, Cursor o Codex CLI y puede ser utilizada tanto desde línea de comandos (recomendado para agentes) como mediante un servidor web con API REST. La configuración se realiza mediante archivos JSON fácilmente editables, y la estructura del proyecto es autocontenida y portable.

Compatible con✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/ChenKuan1110/daily-card/tree/HEAD

Installed? Explore more Imagen skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

daily-card · Generador de tarjetas sociales

Resumen en una frase

Introduce título + subtítulo → obtén un PNG que incluye automáticamente la fecha actual, stickers vectoriales relacionados con el tema y una paleta de colores unificada. Renderizado completamente local, control total sobre el texto en chino y resultados reproducibles con los mismos parámetros.

Este repositorio es en sí mismo un directorio de skill: el directorio donde reside este SKILL.md es la raíz del proyecto; el código, las plantillas de configuración y la documentación están en el mismo nivel. Se puede colocar en las rutas de skills de WorkBuddy / Claude Code / Codex CLI, o ser importado por plataformas tipo skillhub desde GitHub.

Instalación y ubicación

Raíz del proyecto = directorio donde se encuentra este SKILL.md. Se puede ejecutar desde cualquier ruta — el código usa __file__ para localizarse, sin depender de rutas absolutas.

cd /ruta/a/daily-card          # Reemplazar con la ubicación real de instalación
python3 -m pip install -r requirements.txt
./install.sh                    # Instalación idempotente: dependencias, inicialización de configuraciones privadas, autoverificación
./scripts/selfcheck.sh          # A partir de entonces, se puede ejecutar la autoverificación en cualquier momento (también punto de entrada para CI)

No necesita conexión a internet, ni interfaz de IA, ni API Key. Detección automática de fuentes chinas: macOS usa Hiragino Sans GB / PingFang, Linux usa Noto Sans CJK, Windows usa Microsoft YaHei; si no se encuentra ninguna, se sale con un mensaje indicando que se especifique un archivo de fuente con --font / --font-bold.

El agente debe priorizar el uso de la CLI local, sin necesidad de iniciar ningún servicio. El panel web y la API remota son opcionales (ver «Dos backends opcionales»).

Uso más común: generación por línea de comandos (prioritario para agentes)

python3 cardgen.py "Vive bien hoy" "Haz que los días ordinarios suenen más fuertes"

El comando imprimirá la ruta completa archivo: ...; entrega esta ruta PNG al usuario mediante present_files e incluye en la respuesta el tema y las dimensiones. El directorio de salida por defecto es output/, y el nombre del archivo es <título>-<fecha>-<plataforma>.png.

Parámetros comunes

ParámetroFunciónEjemplo
-t / -sTítulo / Subtítulo-t "Buenos días" -s "Primero levántate"
--platformPreset de tamañoxhs(1080×1440) / moments(1080×1080) / wechat(900×500) / story(1080×1920) / wechat2(1080×460)
--themeForzar tema; por defecto se detecta automáticamente por palabras clave--theme study
--dateEspecificar fecha--date 2026-01-01
--brandPie de página--brand "Claw · Frase del día"
--outRuta de salida específica--out /tmp/card.png
--seedSemilla de composición; misma semilla, misma composición--seed 42
--bg-imageImagen de fondo personalizada (extracción automática de color)--bg-image ./bg.jpg
--bg-schemeElegir la enésima paleta de la imagen, o un color primario personalizado--bg-scheme 2 / --bg-scheme "#C2185B"
--list-schemesMostrar las paletas candidatas de la imagen de fondo en JSONpython3 cardgen.py --bg-image bg.jpg --list-schemes
--list-themesListar todos los temas y stickers
--config-dirUsar otro directorio de configuración
--init-configReconstruir config/themes.json desde la plantilla de fábrica (sobrescribe temas privados, haz copia de seguridad primero)

Flujo completo de extracción de color de imagen de fondo

# 1. Ver primero qué paletas puede extraer la imagen (devuelve JSON: name / base / colors / ratio)
python3 cardgen.py --bg-image ./bg.jpg --list-schemes

# 2. Elegir una para generar (0 es el color principal, 1/2/3 son colores secundarios; también se puede dar directamente #RRGGBB)
python3 cardgen.py "El atardecer es la respuesta del día a la noche" "Hoy también has trabajado duro" \
  --bg-image ./bg.jpg --bg-scheme 2 --platform xhs

La paleta (fondo, texto, acento, tarjeta, stickers) se deriva completamente del esquema seleccionado, por lo que los colores de los stickers coinciden inevitablemente con la gama cromática de la imagen; el tipo de sticker sigue coincidiendo automáticamente con el tema del título.

Archivos de configuración (modificar configuración, no código)

ArchivoContenido¿En el repositorio?
config/themes.default.jsonPlantilla de fábrica, 11 temas, solo lectura, para «restaurar valores predeterminados»Sí
config/stickers.jsonNombres chinos / grupos de 28 stickers + registro de 6 patrones de fondo (con descripción semántica desc)Sí
config/themes.jsonConfiguración activa de temas: label, keywords, 10 colores, motif, stickers, darkNo, datos privados
config/settings.jsonPlataforma predeterminada, pie de página, factor de sobremuestreo, intensidad de granulado, directorio de salida, número de paleta predeterminadaNo, datos privados

themes.json y settings.json pertenecen a datos privados del usuario, no se incluyen en el control de versiones ni se publican con el repositorio público. En la primera ejecución, cardconfig.ensure_config() los copia automáticamente desde la plantilla de fábrica, sin necesidad de crearlos manualmente. Para usar otro directorio de configuración, usa la variable de entorno DAILY_CARD_CONFIG o --config-dir. Ver config/README.md para más detalles.

Temas integrados (11): study morning night coffee sport nature mood work tech festival quote.

Para cambiar colores/stickers: edita directamente colors / stickers / keywords del tema correspondiente en config/themes.json, o usa la API del panel; el script vuelve a leer la configuración en cada ejecución, los cambios surten efecto inmediatamente. Para añadir un tema nuevo, debe incluir las 10 claves de color (#RRGGBB) y al menos un ID de sticker válido. Como es privado, no aparecerá en git status; si necesitas respaldo, copia el archivo manualmente.

Dos backends opcionales

BackendCuándo usarloCómo activarlo
Ninguno (predeterminado)Solo para generar tarjetas con CLINo hacer nada, directamente python3 cardgen.py ...
Panel web local (modo independiente)Para GUI, vista previa en tiempo real, modificación visual de temaspython3 server.py, aloja página y API, interfaz en http://127.0.0.1:8777
Servidor remoto (modo solo API)Para compartir en equipo, agente necesita endpoint establepython3 server.py --api-only + proxy inverso nginx con subruta, configurar DAILY_CARD_URL

Con --api-only, el backend solo responde a /api/* (estáticos servidos por nginx), /api/reveal devuelve 403; GET /api/health muestra version / mode / serves_static / config_dir, útil para verificar la versión en línea.

La CLI siempre se ejecuta en la máquina local del llamante, independientemente del backend. Cuando no hay un servicio iniciado, no llames a /api/*, fallará la conexión.

Panel web local (configuración visual + vista previa en tiempo real)

python3 server.py                 # http://127.0.0.1:8777 (modo independiente)
python3 server.py --port 9000 --open
python3 server.py --api-only       # Despliegue en la nube: solo API, estáticos servidos por nginx
# macOS: también se puede hacer doble clic en start-server.command

Tres paneles: Diseño de tarjetas (formulario + vista previa en tiempo real + descarga/guardado), Configuración de temas (cambiar colores/stickers/palabras clave visualmente y escribir de vuelta a JSON), Configuración global (valores predeterminados y parámetros de renderizado). Las pestañas tienen enlaces profundos #design / #config / #settings.

El panel de configuración de temas tiene tres columnas: lista de temas / editor / vista previa en tiempo real. Al editar colores, patrones de fondo, modo oscuro o stickers, la derecha muestra inmediatamente el borrador sin guardar, incluyendo la tarjeta real, el diagrama semántico de colores (etiquetando dónde se usa cada uno de los 10 colores y cómo se ve el patrón actual), los stickers bajo esa paleta, y el diagnóstico de contraste WCAG / coherencia de luminosidad. La vista previa es solo en memoria, no escribe config/themes.json; solo cuando estés satisfecho, haz clic en «Guardar configuración» para escribir en disco.

Despliegue en subruta del mismo dominio (servidor en la nube)

Todas las URL del frontend se derivan del BASE en tiempo de ejecución (document.baseURI) en web/app.js, el código fuente no tiene rutas raíz de dominio fijas; index.html también usa rutas relativas para style.css / app.js. Si es necesario apuntar la API a un dominio independiente, establece window.DAILY_CARD_BASE antes de cargar app.js. nginx se encarga de eliminar el prefijo /daily-card/api/* a /api/*, no es necesario modificar las rutas del backend.

ComandoFunción
./scripts/publish-web.shPublicar web/ en un directorio versionado y cambiar atómicamente el enlace simbólico current
./scripts/publish-web.sh --listVer versiones publicadas y la actual
./scripts/publish-web.sh --rollback [ver]Reversión instantánea, sin necesidad de reiniciar Python
./scripts/test_subpath.pySimular en proceso la eliminación del prefijo por nginx, 10 aserciones encadenadas

La versión estática del frontend se puede publicar y revertir independientemente del backend. Se puede sobrescribir con DAILY_CARD_WEB_ROOT (por defecto /opt/daily-card-web) y DAILY_CARD_WEB_KEEP (por defecto 5). La barra inclinada final es un requisito estricto: /daily-card debe redirigir 301 a /daily-card/, de lo contrario las rutas relativas se resolverían en la raíz del dominio. Consulta la configuración completa de nginx, systemd, caché y autenticación en docs/DEPLOY.md.

Cuando el agente llame a interfaces remotas, DAILY_CARD_URL debe establecerse hasta el prefijo, por ejemplo https://host/daily-card; el código lo concatenará como https://host/daily-card/api/save; no lo escribas como dominio desnudo.

Interfaces JSON (el agente puede llamar directamente, sin navegador)

InterfazDescripción
GET /api/healthHealth check: versión, modo de operación, directorio de configuración (sin necesidad de iniciar el frontend)
GET /api/bootstrapObtener de una vez themes_doc / settings / registry / platforms / rutas
POST /api/renderGenerar vista previa, devuelve {png: dataURL, path, theme, size, bytes}
POST /api/saveGenerar y escribir en output/, devuelve la ruta en disco
POST /api/theme-previewBorrador de tema no guardado → tarjeta + diagrama semántico + tira de stickers + diagnóstico de legibilidad, sin escribir archivos de configuración
POST /api/schemesImagen de fondo → múltiples paletas. Enviar {"path":"/abs/bg.jpg"} o {"image":"data:image/png;base64,..."}
GET /api/schemes?image_id=xxxRecuperar las paletas de una imagen ya subida
POST /api/config/themes{"themes_doc": {...}} Guardar configuración de temas (con validación)
POST /api/config/settings{"settings": {...}} Guardar configuración global
POST /api/config/resetRestaurar temas de fábrica (sobrescribe temas privados, haz copia de seguridad primero)
POST /api/revealAbrir la carpeta de salida
GET /api/sticker?id=book&theme=studyPNG del icono de sticker

Cuerpo de la solicitud para /api/render y /api/save:

{
  "title": "Vive bien hoy",
  "subtitle": "Haz que los días ordinarios suenen más fuertes",
  "platform": "xhs",
  "theme": "auto",
  "date": null,
  "brand": "Claw · Frase del día",
  "seed": null,
  "bg_image_id": null,
  "bg_path": "./bg.jpg",
  "bg_scheme": 0,
  "dark_override": null
}
  • bg_scheme puede ser un número de índice o #RRGGBB; dark_override como true/false fuerza tarjeta clara/oscura, null sigue la detección de la imagen.
  • bg_image_id es devuelto por /api/schemes; también se puede dar bg_path con una ruta accesible por el servidor.
  • El png devuelto es data:image/png;base64,..., decodificar y escribir en archivo.

Ejemplo (cuando DAILY_CARD_URL no está establecido, usa local):

DC_URL="${DAILY_CARD_URL:-http://127.0.0.1:8777}"
curl -s "$DC_URL/api/save" \
  -H 'Content-Type: application/json' \
  -d '{"title":"Vive bien hoy","subtitle":"Haz que los días suenen más fuertes","platform":"xhs"}'
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["path"])'

Vista previa de borrador de tema / Diagnóstico de paleta (inspeccionar antes de guardar)

Para evaluar si una paleta es bonita y el texto legible antes de escribir la configuración, llama a /api/theme-preview. theme es el borrador completo del tema, el servidor solo lo mantiene en memoria:

{
  "theme": {
    "label": "MI TEMA · Nuevo tema",
    "keywords": ["check-in"],
    "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": "Título de ejemplo",
  "subtitle": "Subtítulo de ejemplo",
  "platform": "moments",
  "date": "2026-11-11",
  "seed": 7
}

Campos devueltos (card / legend / stickers / sticker_sheet son data:image/png;base64,...):

CampoSignificado
cardTarjeta renderizada con este borrador
legendDiagrama semántico de paleta: patrón real + jerarquía de tarjeta + qué gestiona cada uno de los 10 colores
stickersAspecto de los stickers seleccionados bajo la paleta actual
sticker_sheetSprite completo de stickers, junto con sheet (cols/rows/cell/order) para recortar y mostrar
diagnostics[{level: ok/warn/tip, text: explicación en chino}]
contrastValores de contraste (ink_card / sub_card / pill_pair / card_bg / accent_bg / bg_light)
motif / dark / draft_onlyNombre chino del patrón y descripción, indicador claro/oscuro, siempre true para indicar que no está en disco

diagnostics verifica el contraste según WCAG: legibilidad del texto principal/secundario/etiquetas, diferenciación entre tarjeta y fondo, si el color de acento resalta lo suficiente, y contradicciones como «fondo muy oscuro pero configurado como tema claro». Práctica recomendada: primero POST del borrador para ver el diagnóstico → si hay warn, ajustar colores según las sugerencias y volver a ejecutar → solo cuando no haya warn, llamar a /api/config/themes para guardar.

Sin iniciar el panel, se puede llamar directamente al módulo:

import base64, cardconfig as cfg, cardpreview as cp
draft = cfg.load_doc()["themes"]["study"]        # Estructura anidada, incluye colors
draft["colors"]["accent"] = "#C2185B"            # Modificar para probar
r = cp.build_preview({"theme": draft, "title": "Ejemplo", "subtitle": "Subtítulo"})
for it in r["diagnostics"]:
    print(it["level"], it["text"])
open("/tmp/draft-card.png", "wb").write(base64.b64decode(r["card"].split(",", 1)[1]))

Actualización y sincronización multi-dispositivo

La única fuente de verdad de versiones es el repositorio git; el resto son derivaciones, solo flujo unidireccional:

ExtremoMétodo de actualizaciónConfiguración privada
Local / Servidor en la nubegit pull && ./install.shNo se ve afectada, no se sobrescribe
Versión estática del frontend en servidor en la nube./scripts/publish-web.sh, --rollback permite reversión instantáneaDesacoplado del servicio Python, no requiere reinicio
Registro de skill local./install.sh --link-skill crea enlace simbólico para evitar desviaciones de copia de archivosNo se ve afectada
Instantánea en plataformas skillhubEl mantenedor etiqueta y reimporta, naturalmente hay desfase de versiónLa plataforma solo obtiene la plantilla de fábrica

La plantilla de fábrica themes.default.json se actualiza con las versiones; el themes.json privado del usuario nunca se sobrescribe. Para fusionar nuevos temas de fábrica en tu configuración, copia manualmente las entradas correspondientes de themes.default.json, o usa «Exportar JSON → Fusionar → Importar» en el panel; no ejecutes directamente --init-config / /api/config/reset.

Para instrucciones de despliegue en servidor e integración CI/CD, consulta docs/DEPLOY.md. scripts/selfcheck.sh tiene 8 pasos, incluyendo verificación de portabilidad de rutas del frontend y simulación de despliegue en subruta (proxy en proceso, sin necesidad de instalar nginx).

Flujo de trabajo recomendado para el agente

  1. Extraer título y subtítulo de las palabras del usuario (si no hay subtítulo, añadir una frase corta que se ajuste al tono, o dejarlo vacío).
  2. Determinar la plataforma: si no se especifica, usar xhs; si se menciona Cuenta Oficial, usar wechat; si son Momentos, usar moments.
  3. Si el usuario proporciona una imagen de fondo: primero --list-schemes o /api/schemes para ver las candidatas, luego seleccionar y generar; si el usuario no especifica, usar la opción 0.
  4. Ejecutar la CLI (sin servicio); solo llamar a /api/save si el usuario solicita explícitamente usar el panel/remoto.
  5. Usar present_files para mostrar la imagen final, explicando en la respuesta el tema, dimensiones, fecha y paleta de colores.
  6. Si el usuario quiere cambiar el estilo → modificar config/themes.json o el panel de configuración, no modificar cardgen.py.

Notas importantes

  • División del código: cardgen.py solo se encarga del renderizado, cardconfig.py de la carga/guardado/extracción de color, cardpreview.py de la vista previa de borradores y diagnóstico de paletas, server.py es el panel; todos leen los mismos config/*.json.
  • output/, uploads/, config/themes.json, config/settings.json, .env están ignorados por .gitignore; examples/ son imágenes demo (unos 6.7 MB, no participan en la ejecución, se pueden eliminar).
  • Los IDs de temas solo permiten letras, números, - y _; los colores deben ser #RRGGBB; los IDs de stickers deben existir en config/stickers.json.
  • Cuanto mayor sea el tamaño de la imagen y el sobremuestreo, más lento; el sobremuestreo 2x por defecto ya es suficientemente nítido.
  • server.py no tiene autenticación y por defecto solo escucha en 127.0.0.1. Antes del despliegue público, añade autenticación de proxy inverso o lista blanca de IPs; en la nube, usa --api-only para exponer solo la API (ver docs/DEPLOY.md).
  • En el código fuente no deben aparecer rutas absolutas como src="/..." / href="/..." / "/api/..."; selfcheck.sh bloqueará estas regresiones; todas las solicitudes deben pasar por url().

Limitaciones conocidas / Plan para la próxima versión

  • Los stickers no se pueden subir personalizadamente (versión actual): los stickers solo se pueden seleccionar de los 28 stickers vectoriales registrados en config/stickers.json; no hay un módulo de gestión de biblioteca de stickers independiente, ni se admite la subida de PNG/SVG como stickers. Para añadir formas, el desarrollador debe agregar funciones de dibujo s_xxx en cardgen.py y registrarlas en stickers.json.
  • Plan para la próxima versión: subida de stickers personalizados (PNG/SVG, extracción automática de color para adaptarse al tema), panel de gestión de biblioteca de stickers (añadir/eliminar/agrupar/vista previa/reutilizar), desacoplamiento de stickers y temas. El usuario ha confirmado que esta funcionalidad se implementará en la próxima versión, no en esta.
  • La vista previa de borradores de temas usa sobremuestreo 1x para acelerar la respuesta; puede diferir ligeramente en detalles muy finos con respecto a la salida final 2x, pero el diseño y la paleta son consistentes.

Skills relacionados