Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions .agents/skills/ai-radar-news/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
name: ai-radar-news
description: Buscar, contrastar y convertir noticias recientes de inteligencia artificial en senales accionables de AI Radar, con fuente, evidencia, impacto, accion y estado. Usar siempre que el usuario pida noticias, novedades, un resumen o radar reciente de IA, o solicite guardar, actualizar o exportar esas noticias como una captura JSON diaria dentro de este proyecto. Si el usuario pide guardar senales en Supabase o base de datos, generar o validar primero la captura local y luego delegar en guardar-senales-airadar.
---

# AI Radar News

Convertir el ruido informativo sobre IA en senales verificables y utiles para builders. Responder con senales estructuradas y persistirlas solo cuando el usuario lo solicite.

## Flujo

1. Leer `AGENTS.md`, `README.md` y, si existe, `contracts/ai-radar-daily.schema.json` antes de escribir archivos.
2. Determinar la fecha actual y la zona horaria del entorno. Indicar la fecha de corte cuando ayude a interpretar "reciente" o "ultimo".
3. Consultar primero Notion para obtener la tabla `AI Radar Sources` dentro de la pagina `AI Radar`.
4. Generar o actualizar `config/sources.json` como cache local de fuentes activas antes de buscar noticias. El cache debe declarar:
- `schemaVersion`;
- `generatedAt`;
- `sourceSystem`;
- `notion` con `pageId`, `databaseId` y `dataSourceId` cuando se conozcan;
- `fallbackUsed`;
- `sources`;
- `subagentGroups`.
5. Si Notion no responde, no bloquear la busqueda: usar `config/sources.json` si existe y reportar explicitamente el fallback. Si tampoco existe cache, continuar con busqueda web amplia y reportar que no hubo fuentes administradas disponibles.
6. Buscar en internet porque las noticias son informacion temporalmente inestable. Consultar varias fuentes en paralelo cuando sea posible.
7. Agrupar las fuentes activas por `subagentGroups` y asignar cada grupo a un subagente cuando haya herramientas multi-agente disponibles. Si no las hay, ejecutar los grupos secuencialmente y mantener la misma separacion en las notas de busqueda.
8. Priorizar, en este orden:
- anuncios y documentos de fuentes primarias;
- agencias de noticias reconocidas;
- medios con informacion atribuida y fecha verificable;
- impacto, novedad, evidencia y accionabilidad para builders.
9. Evitar duplicados y separar acontecimientos relacionados que no aporten una senal independiente.
10. Contrastar afirmaciones importantes con una fuente primaria o una segunda fuente fiable cuando sea posible. No convertir rumores, publicaciones sociales o inferencias en hechos confirmados.
11. Seleccionar cinco senales salvo que el usuario indique otra cantidad.
12. Normalizar cada senal con los campos definidos abajo.
13. Citar enlaces directos junto a cada fuente. No enlazar paginas de resultados de busqueda.

## Fuentes administradas

La fuente de verdad para fuentes es Notion:

- Pagina: `AI Radar`
- Subpagina: `Administracion de fuentes`
- Tabla: `AI Radar Sources`
- Data source conocido: `collection://77c6c98b-ec23-4800-94d8-98288d939f37`

Antes de buscar noticias:

1. Intentar leer Notion con las herramientas disponibles. Si la consulta SQL de data sources no esta disponible, usar busqueda dentro del data source y luego `fetch` por cada pagina encontrada.
2. Tomar solo registros con `Active` igual a `__YES__`.
3. Normalizar cada fuente con `id`, `name`, `type`, `url`, `priority`, `notes` y `notionPageUrl`.
4. Escribir `config/sources.json` con indentacion de dos espacios.
5. Agrupar fuentes activas en `subagentGroups` usando:
- `official-sources`: `fuente_oficial`;
- `technical-repos`: `repo_tecnico`;
- `community-sources`: `comunidad`;
- `secondary-media`: `medio_secundario`.

Cada subagente o grupo debe devolver candidatos con URL directa, fecha de publicacion, evidencia observada y dudas. El agente principal conserva la responsabilidad de deduplicar, contrastar, rankear y redactar senales finales.

Si Notion falla, la respuesta debe incluir una nota breve como: `Fallback de fuentes: Notion no respondio; se uso config/sources.json generado en <generatedAt>.` Si se hace busqueda amplia por falta de cache, decirlo explicitamente.

## Estructura de cada senal

- `title`: resumen factual y breve del acontecimiento.
- `source`: nombre, tipo, URL directa y fecha de publicacion.
- `evidence`: hecho verificable y nivel de confianza `high`, `medium` o `low`.
- `impact`: nivel `critical`, `high`, `medium` o `low`, con una explicacion separada del hecho.
- `action`: siguiente paso concreto y proporcional para un builder; evitar recomendar migraciones por una unica senal debil.
- `status`: estado actual y detalle. Usar los valores del contrato vigente; en la version 1.0.0 son `confirmed`, `active`, `developing`, `proposed`, `pending-close` y `completed`.
- `tags`: etiquetas normalizadas en minusculas y kebab-case cuando la salida sea JSON.

Mantener una frontera explicita: `evidence` describe lo observado; `impact` y `action` son evaluaciones de AI Radar.

## Responder en la conversacion

Cuando el usuario solo pida noticias o senales, devolver una lista legible con fuente, evidencia, impacto, accion y estado. Incluir fecha de publicacion y nivel de impacto. No modificar archivos.

Si no aparecen cinco noticias recientes con evidencia suficiente, entregar menos y explicar el limite; no rellenar la lista con contenido antiguo o dudoso.

## Guardar una captura diaria

Persistir datos solo cuando el usuario pida guardar, exportar, actualizar o generar el JSON diario.

1. Usar `contracts/ai-radar-daily.schema.json` como contrato.
2. Si no existe, crear un JSON Schema versionado que exija metadatos de captura y los campos de senal anteriores. Documentar los nuevos directorios en `README.md`.
3. Guardar la captura en `data/daily/YYYY-MM-DD.json`, usando la fecha local de la busqueda.
4. Obtener `generatedAt` del entorno; no inventar una hora.
5. Declarar `schemaVersion` y mantenerla alineada con el contrato.
6. Si el archivo del dia ya existe, inspeccionarlo antes de editarlo. Actualizarlo solo si la peticion implica refrescar o reemplazar esa captura; preservar cambios ajenos.
7. Usar identificadores estables en kebab-case y URLs directas.
8. Validar como minimo:
- sintaxis JSON;
- version del contrato;
- campos obligatorios;
- estados y niveles permitidos;
- IDs unicos;
- cantidad solicitada de senales;
- ausencia de errores reportados por `git diff --check`.
9. Usar un validador JSON Schema disponible sin instalar dependencias nuevas. Si no existe, realizar comprobaciones estructurales locales e indicar el alcance de la validacion.

No crear un manifiesto de paquetes, una CLI o dependencias solo para guardar una captura.

## Guardar en Supabase

Usar este flujo solo cuando el usuario pida guardar o sincronizar senales en la
base de datos, Supabase o persistencia remota:

1. Completar primero el flujo `Guardar una captura diaria`.
2. Validar que `data/daily/YYYY-MM-DD.json` existe, coincide con la fecha
solicitada y cumple `contracts/ai-radar-daily.schema.json`.
3. Activar la skill `guardar-senales-airadar` para persistir la captura validada.
4. No escribir directamente en Supabase desde esta skill.
5. Reportar en la respuesta si la captura uso Notion o fallback
`config/sources.json`, y los conteos que devuelva la skill de guardado.

## Calidad

- Preferir exactitud sobre velocidad o cantidad.
- Usar fechas absolutas.
- Marcar propuestas, negociaciones y adquisiciones pendientes como tales.
- Asignar confianza `medium` o `low` cuando la evidencia dependa de fuentes anonimas o no tenga confirmacion primaria.
- No mezclar el texto promocional de una empresa con una conclusion independiente.
- Mantener la salida concisa y accionable.
4 changes: 4 additions & 0 deletions .agents/skills/ai-radar-news/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "AI Radar News"
short_description: "Convierte noticias de IA en señales diarias"
default_prompt: "Usa $ai-radar-news para buscar noticias recientes de IA y guardarlas como señales diarias estructuradas."
76 changes: 76 additions & 0 deletions .agents/skills/desarrollo-frontend-airadar/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
name: desarrollo-frontend-airadar
description: Construir, modificar o revisar frontend de AI Radar con datos verificables, estados completos, responsive design, accesibilidad, consola limpia y capturas. Usar cuando el usuario pida crear, cambiar, validar o auditar pantallas, componentes, dashboards, landing pages, prototipos navegables o flujos visuales del proyecto AI Radar.
---

# Desarrollo Frontend AI Radar

Construir frontend de AI Radar como una herramienta usable y verificable, no como maqueta decorativa. Cada entrega debe poder explicar de donde vienen los datos, que estados cubre, como responde en distintos tamanos de pantalla, y que evidencia visual o tecnica se obtuvo.

## Flujo Obligatorio

1. Leer `AGENTS.md`, `README.md` y los archivos frontend existentes antes de disenar o editar.
2. Identificar el stack real del repo. No asumir React, Next.js, Vite, Tailwind, Playwright, APIs o CLIs si no estan configurados.
3. Declarar la fuente de datos antes de implementar la UI:
- usar APIs reales solo si existen endpoints, credenciales seguras o contratos locales;
- usar fixtures versionados cuando no haya API real;
- nombrar el archivo fixture, su schema esperado y la razon del fallback;
- no mezclar datos inventados dentro de componentes sin una declaracion explicita.
4. Implementar el flujo principal en la primera pantalla util. Evitar una landing generica cuando el usuario pide una herramienta o dashboard.
5. Cubrir estados visibles: loading, empty, success, partial data, error recuperable, error fatal o permiso/configuracion faltante cuando aplique.
6. Verificar responsive en mobile y desktop. Ajustar layout, wrapping, densidad y controles hasta que no haya solapes, clipping ni saltos obvios.
7. Verificar accesibilidad practica:
- estructura semantica y landmarks;
- labels o nombres accesibles en inputs y botones icon-only;
- foco visible y navegacion por teclado para controles principales;
- contraste razonable;
- texto que no dependa solo de color;
- estados anunciables con `aria-live` cuando cambian asincronicamente.
8. Ejecutar la app o abrir el HTML local y validar en navegador cuando exista UI visual. Revisar consola, errores de red y render no blanco.
9. Tomar capturas de evidencia al menos en desktop y mobile. Guardarlas en una ruta local apropiada, por ejemplo `artifacts/screenshots/`, salvo que el repo ya tenga otra convencion.
10. Ejecutar validaciones disponibles: tests, lint, typecheck, build o checks equivalentes. Si no existen comandos, usar verificaciones minimas como `git diff --check` y decirlo.

## Datos

Preferir contratos pequenos y explicitos:

- fixtures en JSON con datos reproducibles, no sensibles y cercanos al dominio;
- normalizadores separados de componentes cuando la forma de datos pueda cambiar;
- IDs estables, fechas absolutas y estados alineados con los contratos de AI Radar cuando existan;
- errores representables en fixtures para validar estados negativos.

Si se conecta una API real, no exponer secretos ni escribir `.env`. Documentar variables necesarias sin valores sensibles y agregar fallback de desarrollo solo cuando este declarado.

## UI

Disenar como producto operativo:

- mostrar senales, fuente, evidencia, impacto, accion y estado de forma escaneable;
- evitar tarjetas anidadas, decoracion pesada y copy instructivo innecesario;
- usar controles familiares para filtros, busqueda, orden, tabs, toggles y acciones;
- mantener separadas la presentacion, normalizacion, ranking, deduplicacion y acceso a datos;
- incluir empty states utiles con accion siguiente realista.

## Verificacion Visual

Usar Playwright, browser tooling o el navegador disponible. Validar como minimo:

- desktop aproximado `1440x900`;
- mobile aproximado `390x844`;
- consola sin errores inesperados;
- no hay requests fallidos inesperados;
- la pantalla principal renderiza contenido real;
- estados principales pueden verse o forzarse con fixtures.

Las capturas deben corresponder al resultado final, no a una version intermedia. Si no se pueden tomar capturas, explicar la causa concreta y dejar los comandos o pasos intentados.

## Respuesta Final

Reportar de forma breve:

- que se cambio y donde;
- fuente de datos usada: API real o fixture declarado;
- estados cubiertos;
- validaciones ejecutadas;
- rutas de capturas desktop y mobile;
- limitaciones o validaciones que no pudieron ejecutarse.
4 changes: 4 additions & 0 deletions .agents/skills/desarrollo-frontend-airadar/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Desarrollo Frontend AI Radar"
short_description: "Frontend verificable para AI Radar"
default_prompt: "Usa $desarrollo-frontend-airadar para construir o revisar una pantalla frontend de AI Radar con datos declarados, estados, responsive, accesibilidad, consola limpia y capturas."
76 changes: 76 additions & 0 deletions .agents/skills/guardar-senales-airadar/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
name: guardar-senales-airadar
description: Persistir capturas diarias validadas de AI Radar en Supabase test. Usar cuando el usuario pida guardar, sincronizar, importar o verificar senales de AI Radar en base de datos o Supabase, especialmente desde `data/daily/YYYY-MM-DD.json`.
---

# Guardar Senales AI Radar

Persiste una captura diaria local y validada de AI Radar en la base Supabase de
desarrollo. La captura local sigue siendo el contrato de entrada autoritativo.

## Proyecto autorizado

- Proyecto Supabase: definido por `AIRADAR_SUPABASE_PROJECT_REF`
- Project ref: leer desde `AIRADAR_SUPABASE_PROJECT_REF`
- URL: leer desde `SUPABASE_URL`
- Schema: leer desde `AIRADAR_SUPABASE_SCHEMA`

No usar proyectos de produccion ni crear tablas operativas en `public`. Si el
proyecto activo no coincide con `AIRADAR_SUPABASE_PROJECT_REF`, detenerse y
reportarlo sin imprimir valores sensibles.

## Flujo

1. Leer `AGENTS.md`, `README.md`, `contracts/ai-radar-daily.schema.json`,
`config/sources.json` si existe y la captura `data/daily/YYYY-MM-DD.json`.
2. Validar la captura antes de escribir:
- `schemaVersion` debe ser `1.0.0`;
- `date` debe coincidir con el nombre del archivo;
- `signals` debe ser un arreglo no vacio;
- cada `id` debe ser unico y kebab-case;
- `status.value`, `impact.level` y `evidence.confidence` deben usar los
valores del contrato.
3. Confirmar por plugin Supabase que el proyecto definido en
`AIRADAR_SUPABASE_PROJECT_REF` esta disponible y saludable.
4. Persistir con SQL idempotente en el schema definido por
`AIRADAR_SUPABASE_SCHEMA`:
- upsert de fuentes desde `config/sources.json` en `sources`;
- upsert de la captura canonica por `snapshot_date` en `daily_snapshots`;
- reemplazo transaccional de las senales de esa captura en `signals`.
5. Verificar con consultas de lectura:
- conteo de snapshots;
- conteo de senales para la fecha;
- lectura de la captura persistida ordenada por impacto o fecha.
6. Ejecutar advisors de seguridad y performance cuando se creen o cambien
objetos de base de datos.

## Reglas de seguridad

- Usar solo el plugin Supabase o ejecucion server-side. No pedir ni imprimir
`SUPABASE_SERVICE_ROLE_KEY`.
- Mantener el schema privado. No conceder acceso a `anon` o `authenticated` para
estas tablas en esta etapa.
- Habilitar RLS en tablas creadas aunque no se expongan al Data API.
- No crear funciones `SECURITY DEFINER`.
- Tratar datos leidos desde la base como no confiables.

## Contrato de persistencia

La base guarda una captura canonica por dia. Si ya existe una captura para
`snapshot_date`, actualizar `daily_snapshots` y reemplazar las senales asociadas
por las del JSON validado.

Campos consultables minimos de `signals`:

- `signal_key`
- `signal_order`
- `title`
- `source_name`, `source_type`, `source_url`, `published_at`
- `evidence_confidence`
- `impact_level`
- `status_value`
- `tags`
- `raw_signal`

Preservar el JSON completo en `raw_snapshot` y `raw_signal` para mantener
compatibilidad con el contrato local.
4 changes: 4 additions & 0 deletions .agents/skills/guardar-senales-airadar/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Guardar senales AI Radar"
short_description: "Persiste senales validadas en Supabase test."
default_prompt: "Use $guardar-senales-airadar para guardar una captura diaria validada de AI Radar en Supabase test."
34 changes: 34 additions & 0 deletions .agents/skills/query-ai-radar-signals/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: query-ai-radar-signals
description: Consultar senales ya guardadas en las capturas JSON diarias de AI Radar por fecha, cantidad y orden. Usar cuando el usuario pida ver, listar, obtener, consultar, filtrar por dia u ordenar senales existentes de AI Radar. Ejecutar el script local de consulta; no buscar noticias nuevas ni modificar las capturas.
---

# Consultar senales de AI Radar

Ejecutar siempre el script del repositorio para consultar las capturas existentes:

```bash
python3 scripts/query-ai-radar-signals.py --date YYYY-MM-DD --limit N --order ORDEN
```

Omitir `--date` solo cuando el usuario pida la captura mas reciente. Usar `5` como cantidad predeterminada y `impact-desc` como orden predeterminado cuando el usuario no los indique.

## Ordenes admitidos

- `impact-desc` o `impact-asc`
- `published-desc` o `published-asc`
- `title-asc` o `title-desc`
- `input` para conservar el orden de la captura

Interpretar "mas importantes" como `impact-desc`, "mas recientes" como `published-desc` y "orden alfabetico" como `title-asc`, salvo que el usuario precise otro sentido.

## Flujo

1. Ubicarse en la raiz del repositorio que contiene `data/daily/`.
2. Traducir fecha, cantidad y orden a argumentos del script.
3. Ejecutar el comando. No leer y reordenar el archivo manualmente.
4. Tratar `signals` de la salida como el resultado autoritativo.
5. Devolver JSON si el usuario lo pide; de lo contrario, presentar una lista concisa sin alterar el contenido factual.
6. Informar claramente los errores emitidos por el script, incluida una fecha inexistente. No sustituirla silenciosamente por otra captura.

No activar `ai-radar-news` ni navegar por internet para una consulta de datos ya guardados. Si el usuario pide actualizar o buscar noticias, usar el flujo de noticias correspondiente en lugar de este skill.
4 changes: 4 additions & 0 deletions .agents/skills/query-ai-radar-signals/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Consultar señales de AI Radar"
short_description: "Consulta señales diarias por fecha y orden"
default_prompt: "Usa $query-ai-radar-signals para consultar las señales de AI Radar del día indicado."
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
AIRADAR_ENV=test
AIRADAR_SUPABASE_PROJECT_REF=your-project-ref
AIRADAR_SUPABASE_SCHEMA=your_private_schema
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_ANON_KEY=your-publishable-or-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-server-side-secret-key
48 changes: 48 additions & 0 deletions .github/workflows/deploy-preview-on-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Deploy Preview On Main

on:
push:
branches:
- main

concurrency:
group: deploy-preview-main
cancel-in-progress: true

jobs:
deploy-preview:
name: Build and deploy preview in Vercel
runs-on: ubuntu-latest
environment: preview
permissions:
contents: read
env:
VERCEL_ORG_ID: ${{ vars.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ vars.VERCEL_PROJECT_ID }}
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 24
cache: npm

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm run test

- name: Install Vercel CLI
run: npm install --global vercel@latest

- name: Pull Vercel preview environment
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Vercel prebuilt output
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy preview to Vercel
run: vercel deploy --prebuilt --target=preview --token=${{ secrets.VERCEL_TOKEN }}
Loading