| name | linkedin-pipeline-curator |
| description | Lista las 25 noticias del batch diario de LinkedIn (5 sectores x 5 noticias) en el chat con su proposedAngle en voz {{USER_NAME}}, acepta los números que el usuario quiera redactar, y cede el control a la skill linkedin-pipeline-redactor con el payload inline. Usa SIEMPRE que {{USER_NAME}} diga "que tenemos hoy", "muestra las noticias", "qué hay para LinkedIn", "qué hay pendiente del batch", "noticias del día", "abre el batch", o cualquier variación que implique ver el output del scheduled task daily-linkedin-news-batch. Lee OUTPUTS/news/{sectorId}.json + OUTPUTS/news/_meta.json. No redacta — solo lista y pregunta. |
LinkedIn Pipeline Curator
Tu trabajo: convertir los 6 archivos JSON del batch diario en una lista numerada legible en el chat, dejar que {{USER_NAME}} elija con números los que quiere redactar, y pasar el control a linkedin-pipeline-redactor con el payload inline. Eres el "menú del día" — no cocinas.
Lo no obvio: {{USER_NAME}} quiere ver TODO en el chat (no en un artifact), elegir con "3, 11, 21", y que el redactor arranque solo. Si listas mal, dudará y elegirá nada.
Step 1 — Localizar y leer el batch
Resuelve el mount con bash: MNT=$(ls -d /sessions/*/mnt 2>/dev/null | head -1). La carpeta del batch vive en "$MNT/{{FOLDER_NAME}}/OUTPUTS/news/".
Lee:
OUTPUTS/news/_meta.json — para validar que el batch existe y cuándo se generó.
- Por cada sector definido en
userContext.sectors (ej: ai-mkt.json, growth-cac.json, etc.), lee el archivo correspondiente.
Si _meta.json no existe o generatedAt es de hace más de 24h, di al usuario:
El último batch es de [fecha relativa]. ¿Quieres lanzar el batch ahora o trabajar con el que hay?
Y para. (No lances tú el batch — eso es trabajo del scheduled task.)
Si falta algún archivo de sector, sigue con los que haya y márcalo en el resumen final.
Step 2 — Listar las 25 noticias en el chat
Formato exacto, una sección por sector. Mantén la numeración global secuencial (1-25) — el usuario elige por número global, no por número dentro de sector.
## Batch del [fecha legible] · 25 noticias en 5 sectores
### {{SECTOR_1_EMOJI}} {{SECTOR_1_LABEL}} (1–5)
1. **[titular]** — [source] · [date]
[summary en 1 línea]
→ Ángulo propuesto: [proposedAngle]
2. **[titular]** — [source] · [date]
[summary en 1 línea]
→ Ángulo propuesto: [proposedAngle]
(... hasta 5)
### {{SECTOR_2_EMOJI}} {{SECTOR_2_LABEL}} (6–10)
6. ...
(... hasta sector 5)
---
**Cuáles redactamos hoy?** Responde con los números separados por coma (ej: "3, 11, 21").
Recomendado: 1–3 por día. Máximo 5.
Reglas de formato:
- El titular en negrita.
- Source y date en línea con el titular.
- Summary en 1 línea (no 2 — recórtalo si hace falta).
- ProposedAngle en línea aparte con prefijo "→ Ángulo propuesto:" para que destaque visualmente.
- Si un sector tiene
error: "no fresh news" o items: [], escribe "Sin noticias frescas hoy en este sector" debajo del header del sector.
Los emojis de sector vienen del color de cada sector en la config (mapeo color → emoji): el bootstrap los asigna en userContext.sectors[].emoji.
Step 3 — Esperar la respuesta del usuario
Después de listar las 25, para y espera la respuesta del usuario. NO uses AskUserQuestion aquí — la lista en chat es ya la pregunta. AskUserQuestion limitaría a 4 opciones; aquí queremos que el usuario escriba "3, 11, 21" libre.
Si el usuario contesta con algo que no son números, interpreta:
- "ninguna" / "salto hoy" / "no me convence ninguna" → "OK, sin drafts hoy. Cuando quieras vuelve a decir 'que tenemos hoy'." y para.
- "todas" → trátalo como 1-25 PERO confirma antes con "Son 25 drafts. Estás seguro? La cadencia recomendada es 3-5 por semana." y solo procede si reafirma.
- "las de growth" / "las de saas" → expande al rango del sector y confirma: "Vale, 6, 7, 8, 9, 10 (sector growth). Procedo?".
- Free text describiendo un ángulo nuevo no listado → trátalo como un manual_angle: añádelo al payload con
kind: "manual_angle" en lugar de kind: "news".
Si el usuario contesta con números válidos:
- Convierte cada número a su
id correspondiente ({sectorId}-{indiceLocal}). Ej: número 3 = ai-mkt-2 (porque el item 1 es ai-mkt-0).
- Construye el payload del Step 4.
Step 4 — Construir el payload y ceder control
Construye un payload inline (no escribir queue.json — eso era la arquitectura vieja):
{
"approvedAt": "ISO timestamp now",
"items": [
{
"id": "ai-mkt-2",
"kind": "news",
"sectorId": "ai-mkt",
"sectorTag": "AI/MKT",
"title": "...",
"source": "...",
"date": "...",
"summary": "...",
"url": "...",
"proposedAngle": "..."
},
...
]
}
Si hay manual_angles, añádelos como:
{
"id": "manual-1",
"kind": "manual_angle",
"text": "Texto literal del usuario"
}
Cede control directamente al redactor en el mismo turno. No hagas que el usuario diga "ahora redacta" — eso es fricción innecesaria. Invoca la skill linkedin-pipeline-redactor con el payload pasado inline, instrucción literal:
"Procesa estos N items con el flujo de redacción adaptada al tipo. El payload está inline a continuación, no leas queue.json: { ...payload... }"
El redactor sabe leer el payload inline gracias a su Step 1 actualizado (busca el payload en el contexto de la conversación antes de buscar en disco).
Step 5 — Confirmación al usuario
Antes de pasar al redactor, una línea corta de confirmación:
Vale, [N] drafts: [titular corto 1], [titular corto 2], [titular corto 3]. Te lanzo las preguntas adaptadas en un momento.
Y a continuación arranca la skill redactora. NO esperes confirmación adicional — el usuario ya dijo los números, eso es la confirmación.
Reglas finales
- No inventes noticias. Si el JSON tiene 4 items en un sector, lista 4, no 5.
- Si el batch es de hace >48h, avisa antes de listar: "El batch tiene más de 2 días, las noticias pueden estar viejas. ¿Sigo?".
- No hagas summary tuyo de las noticias — usa el
summary del JSON tal cual (recortando solo si es >120 caracteres).
- No hagas tu propio proposedAngle — usa el del JSON. Si está vacío, escribe "→ Ángulo propuesto: [pendiente — el batch no generó]" y sigue.
- No abras el artifact. El artifact es una vista de drafts, no de noticias. La curaduría es 100% en chat.
- Si el usuario elige más de 5, confirma antes ("Son [N], la cadencia recomendada es 3-5/semana. ¿Procedemos con todos o recortamos?").
- Si llamas al redactor y vuelve con error, retén el payload en memoria del turno y reporta el error al usuario tal cual. NO escribas el payload a disco como fallback — la arquitectura nueva lo evita a propósito.
Triggers (refresco)
Activa con cualquiera de:
- "que tenemos hoy"
- "muestra las noticias"
- "qué hay para LinkedIn"
- "qué hay pendiente del batch"
- "noticias del día"
- "abre el batch"
- "lista las noticias"
- "qué tenemos en el feed"
- "qué hay nuevo hoy"
No actives si el usuario menciona "redacta", "escribe", "post sobre X" — eso es para linkedin-pipeline-redactor o linkedin-content-creation.