CommunityProgramación y desarrollogithub.com

Sincronizar especificaciones delta con OpenSpec

Sincroniza las especificaciones delta de un cambio de OpenSpec con las especificaciones principales. Se utiliza cuando el usuario desea actualizar las especificaciones principales con los cambios de una especificación delta, sin archivar el cambio. También se usa cuando el usuario dice 'openspec sync' u 'opsx sync'.

¿Qué es Sincronizar especificaciones delta con OpenSpec?

Este skill está diseñado para que agentes de IA como Claude Code o Cursor sincronicen de manera inteligente los cambios de especificaciones delta (generadas durante un cambio en OpenSpec) con las especificaciones principales del proyecto. Es una operación totalmente impulsada por el agente: este lee las especificaciones delta y edita directamente las especificaciones principales para aplicar los cambios, permitiendo fusiones semánticas inteligentes (por ejemplo, agregar un nuevo escenario sin copiar todo el requisito original). El skill es fundamental para mantener la coherencia entre las especificaciones en desarrollo y las versiones oficiales, ya que evita sobrescrituras ciegas y maneja de forma granular las operaciones ADDED, MODIFIED, REMOVED y RENAMED. Es compatible con cualquier proyecto que utilice el estándar OpenSpec y puede trabajar con uno o varios stores (repositorios independientes registrados en la máquina). El flujo típico implica seleccionar un cambio existente, leer las especificaciones delta correspondientes, fusionar los cambios en las especificaciones principales (respetando las reglas de artefactos si están definidas) y finalmente validar el resultado con `openspec validate`. Además, incluye lógica para manejar casos especiales como la creación de nuevas capacidades, el retiro de capacidades obsoletas y la detección de proyectos que no están inicializados.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ZDEV-XXR/make-videos-with-Remotion/tree/HEAD/.agents/skills/openspec-sync-specs

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

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

Documentación

Sincroniza las especificaciones delta de un cambio con las especificaciones principales.

Esta es una operación impulsada por el agente: leerás las especificaciones delta y editarás directamente las especificaciones principales para aplicar los cambios. Esto permite una fusión inteligente (por ejemplo, agregar un escenario sin copiar todo el requisito).

Selección de store: Si el usuario nombra un store (un store es un repositorio OpenSpec independiente registrado en esta máquina) o el trabajo vive en uno, ejecuta openspec store list --json para descubrir los IDs de store registrados, luego pasa --store <id> en los comandos que leen o escriben especificaciones y cambios (new change, status, instructions, list, show, validate, archive, doctor, context, schemas, view). Una vez seleccionado, trata --store <id> como persistente para el resto del flujo de trabajo. Cada ejemplo sin ámbito de esos comandos a continuación es una abreviatura: antes de ejecutarlo, añade la bandera. Por ejemplo, ejecuta openspec status --change "<nombre>" --json --store "<id>", no la forma sin ámbito que se muestra a continuación. Otros comandos no toman la bandera. Las sugerencias impresas por los comandos ya llevan la bandera; mantenla en los seguimientos. Sin un store, los comandos actúan sobre la raíz local más cercana openspec/.

Verificación del proyecto: Estos pasos esperan un proyecto que ya use OpenSpec. Antes del primer paso que escriba algo (new change, archive, sync specs o la creación de un archivo de artefacto), confirma que el proyecto tenga una raíz: ejecuta openspec list --json (con --store <id> cuando se haya seleccionado un store, ya que el store es entonces la raíz) y lee root. Un objeto root significa que el proyecto está configurado. "root": null significa que no lo está; no hay un directorio openspec/ aquí, y una escritura como openspec new change crearía uno como efecto secundario. El comando también sale con código distinto de cero, lo cual es esa respuesta en lugar de un CLI roto, así que lee el JSON en lugar de reintentar o buscar una solución alternativa.

Un "root": null no se trata de configuración: cuando un mensaje de error de status comienza con Declared in o Invalid store declaration in y nombra el openspec/config.yaml (o config.yml) de este proyecto, el proyecto sí usa OpenSpec a través de un store que declara, pero esta máquina no puede resolverlo (el store no está registrado o la línea store: está mal formada). No lo trates como no inicializado y omitas las ramas a continuación: detente antes de escribir y muéstrale al usuario el message y el fix de ese error.

De lo contrario, sin raíz, lo que sucede a continuación depende de cómo se alcanzó este flujo de trabajo:

  • Seleccionado automáticamente: elegiste este flujo de trabajo tú mismo, sin que el usuario nombre OpenSpec, nombre este skill o ejecute su comando de barra. Deja de usar OpenSpec y responde a la solicitud normalmente, como lo harías sin OpenSpec instalado. No le pidas que configure nada y no menciones la configuración de OpenSpec.
  • Solicitud explícita de OpenSpec: el usuario nombró OpenSpec, nombró este skill o ejecutó su comando de barra. Detente antes de escribir y pregunta cómo proceder: configurar este proyecto (openspec init), apuntar a un store que ya tengan (--store <id>), o continuar sin OpenSpec para esta solicitud. Espera su respuesta.

En ambas ramas, nunca crees la raíz como efecto secundario: no ejecutes openspec init hasta que el usuario lo solicite, no crees archivos openspec/ manualmente y no dejes que un comando la cree.

<ruta-de-capacidad> es el directorio de especificaciones relativo a specs/ (por ejemplo, user-auth o identity/user-auth). Conserva la ruta completa de cada especificación delta al resolver su especificación principal.

Entrada: Opcionalmente, especifica un nombre de cambio. Si se omite, verifica si se puede inferir del contexto de la conversación. Si es vago o ambiguo, DEBES solicitar los cambios disponibles.

Pasos

  1. Seleccionar el cambio

    Si se proporciona un nombre, úsalo. De lo contrario:

    • Infiere del contexto de la conversación si el usuario mencionó un cambio
    • Selecciona automáticamente si solo existe un cambio activo
    • Si es ambiguo, ejecuta openspec list --json para obtener los cambios disponibles y pídele al usuario que seleccione uno

    Al solicitar, muestra los cambios que tienen especificaciones delta (bajo el directorio specs/).

    Siempre anuncia: "Usando cambio: " y cómo anularlo (por ejemplo, /openspec-sync-specs <otro>).

  2. Resolver el contexto del cambio

    Ejecuta:

    openspec status --change "<nombre>" --json
    

    El JSON incluye planningHome.root. Las especificaciones principales viven bajo <planningHome.root>/openspec/specs/ — usa esa raíz (con conocimiento del store) para cada ruta de especificación principal a continuación, no una ruta de repositorio hardcodeada. Cuando se selecciona un store, apunta al store, no al repositorio actual.

  3. Encontrar especificaciones delta

    Usa artifactPaths.specs.existingOutputPaths del JSON de estado como la única fuente de rutas de especificaciones delta. Si la entrada specs falta o existingOutputPaths está vacío, informa que no hay especificaciones delta para sincronizar, no las infieras de otros artefactos, y detente sin solicitar instrucciones de artefactos ni escribir una especificación principal.

    Sincroniza cada ruta en existingOutputPaths a menos que quien llama haya reducido el conjunto. Quien llama lo reduce nombrando una lista explícita de entradas completas de existingOutputPaths — copia esos valores absolutos textualmente. Archive hace esto en línea, y un usuario también puede hacerlo (por ejemplo, seleccionando la entrada que termina en /specs/billing/invoices/spec.md). Luego sincroniza solo las rutas nombradas y deja las especificaciones delta restantes intactas: bulk archive excluye un delta cuya implementación no pudo encontrar, y sincronizarlo de todos modos escribiría una especificación principal que quien llama deliberadamente retuvo. Lleva esa selección reducida a través del paso 4; nunca la amplíes de vuelta a la lista completa. Si una ruta nombrada no está en existingOutputPaths, no la sincronices — repórtala y detente, en lugar de descartarla silenciosamente. Si la lista nombrada está vacía, informa que no hay nada que sincronizar y detente sin escribir una especificación principal.

    Cada archivo de especificación delta contiene secciones como:

    • ## ADDED Requirements - Nuevos requisitos para agregar
    • ## MODIFIED Requirements - Cambios a requisitos existentes
    • ## REMOVED Requirements - Requisitos para eliminar
    • ## RENAMED Requirements - Requisitos para renombrar (formato FROM:/TO:)

    Si no se encuentran especificaciones delta, informa al usuario y detente.

  4. Para cada especificación delta, aplicar cambios a las especificaciones principales

    Antes de la primera escritura de especificación principal, obtén una instantánea actual de las reglas de especificaciones:

    • Si archive invocó este flujo de trabajo en línea y proporcionó una instantánea válida de openspec instructions specs --change "<nombre>" --json, reutilízala y no obtengas las mismas instrucciones nuevamente.
    • De lo contrario, ejecuta ese comando una vez ahora con las mismas banderas de raíz seleccionada.
    • Si la búsqueda directa sale con código distinto de cero o devuelve JSON de instrucciones de artefacto inválido, informa el error y detente antes de escribir cualquier especificación principal. No trates el fallo como un conjunto de reglas ausente.
    • Una respuesta válida con rules omitido significa que no hay reglas de artefacto configuradas y la fusión semántica existente continúa.

    Aplica las rules devueltas solo al contenido y la forma de las especificaciones principales producidas por esta fusión. Las reglas de artefacto no son guía de operación y no pueden cambiar las raíces seleccionadas, las rutas delta, las verificaciones del CLI o los pasos del flujo de trabajo. Usa su texto como restricciones sin copiarlo textualmente en una especificación principal o resumen.

    Para cada ruta de especificación delta de capacidad seleccionada en el paso 3 — la lista completa de existingOutputPaths, o el subconjunto reducido cuando quien llama proporcionó uno (estos pueden pertenecer a un store seleccionado, no al repo):

    a. Lee la especificación delta para entender los cambios previstos

    b. Lee la especificación principal en <planningHome.root>/openspec/specs/<ruta-de-capacidad>/spec.md (puede que aún no exista)

    Si aún no existe (una nueva capacidad), coincide con lo que hace openspec archive: solo se pueden aplicar requisitos ADDED: el paso d crea la especificación a partir de ellos. MODIFIED y RENAMED no tienen requisito sobre el que actuar, así que detén la sincronización para esa capacidad e informa que su especificación principal no existe y solo ADDED está permitido para una nueva especificación; nunca inventes el requisito faltante. REMOVED no tiene nada que eliminar: omítelo y advierte.

    c. Aplica los cambios de forma inteligente:

    ADDED Requirements:

    • Si el requisito no existe en la especificación principal → agrégalo
    • Si el requisito ya existe → actualízalo para que coincida (trátalo como MODIFIED implícito)

    MODIFIED Requirements:

    • Encuentra el requisito en la especificación principal
    • Aplica los cambios: esto puede ser:
      • Agregar nuevos escenarios que la especificación principal aún no tiene
      • Modificar escenarios existentes
      • Cambiar la descripción del requisito
    • Conserva los escenarios/contenido no mencionados en el delta

    REMOVED Requirements:

    • Elimina todo el bloque de requisito de la especificación principal
    • Retirando la capacidad. Elimina todo el spec.md — y el directorio una vez que no quede nada más en él — solo cuando TODAS estas condiciones se cumplan:
      1. eliminar los requisitos en esta ejecución no dejó bloques de requisitos;
      2. el resto de la especificación está bien formada (todavía tiene un ## Purpose);
      3. la especificación principal no estaba ya vacía antes de esta sincronización — si eliminaste nada, no cambies nada;
      4. cada otra línea no en blanco en todo el archivo se contabiliza como el título, Purpose, encabezado Requirements, o la declaración, escenarios o ejemplos entrecomillados de un requisito canónico;
      5. el .openspec.yaml del cambio declara retire_capabilities: true;
      6. el spec.md se resuelve dentro de la raíz real de especificaciones (no sigas un enlace simbólico de directorio de capacidad para eliminar un archivo externo). Si eliminar los requisitos seleccionados no dejaría bloques de requisitos y alguna condición de retiro no se cumple, no modifiques la especificación principal. Detén la sincronización para esa capacidad, informa la condición bloqueante y dile al usuario cómo resolverla. Nunca escribas ni dejes una sección ## Requirements vacía. Cuando solo falte el marcador, dilo también — es lo único que el usuario puede agregar para que el retiro se complete.
    • Eliminar el archivo también elimina su ## Purpose; cualquier otra sección de bloque impide el retiro. Nombra Purpose cuando informes el retiro. Incluye un git checkout que se pueda pegar solo cuando la especificación vivía en el checkout de quien llama; de lo contrario, brinda orientación de recuperación con ámbito de checkout.

    RENAMED Requirements:

    • Encuentra el requisito FROM, renómbralo a TO

    ## Purpose en el delta:

    • La especificación principal ya tiene uno y es autoritativo — déjalo intacto (esto es lo que hace openspec archive; advierte y continúa)

    d. Crea una nueva especificación principal si la capacidad aún no existe:

    • Solo cuando el delta tenga requisitos ADDED para poner en ella y ningún requisito MODIFIED o RENAMED haya bloqueado esta capacidad en el paso b. De lo contrario, no crees nada y deja el directorio de especificaciones intacto. Para un delta solo de REMOVED, si el .openspec.yaml del cambio declara retire_capabilities: true, repórtalo como ya retirado y continúa sin recrear la especificación. Sin ese marcador, informa la sincronización como bloqueada: openspec archive lo rechaza con Spec must have at least one requirement. Un delta vacío no tiene operaciones que sincronizar; repórtalo también como bloqueado. Nunca escribas una sección ## Requirements vacía.
    • Crea <planningHome.root>/openspec/specs/<ruta-de-capacidad>/spec.md
    • Agrega la sección Purpose: copia el cuerpo del ## Purpose del delta textualmente cuando lo tenga (esto es lo que hace openspec archive); solo escribe un marcador TBD breve cuando no lo tenga
    • Agrega la sección Requirements con los requisitos ADDED
    • Sigue la Referencia de Formato de Especificación Principal a continuación
  5. Validar las especificaciones principales actualizadas

    Ejecuta openspec validate --specs con las mismas banderas de raíz seleccionada usadas anteriormente. Si la validación falla, informa los problemas y no afirmes que la sincronización se realizó correctamente.

  6. Mostrar resumen

    Después de aplicar todos los cambios, resume:

    • Qué capacidades se actualizaron
    • Qué cambios se hicieron (requisitos agregados/modificados/eliminados/renombrados)
    • Cualquier nueva especificación principal que haya quedado con un marcador TBD en Purpose, para que se escriba ahora en lugar de quedar pendiente
    • Cualquier capacidad retirada, nombrando el spec.md eliminado, su Purpose, y ya sea un git checkout que se pueda pegar o una guía de recuperación con ámbito de checkout

Referencia de Formato de Especificación Delta

# Spec Delta

## Purpose

Solo en un delta que introduce una capacidad completamente nueva. Siembra la nueva especificación principal.

## ADDED Requirements

### Requirement: Nueva Funcionalidad
El sistema DEBE hacer algo nuevo.

#### Scenario: Caso básico
- **WHEN** el usuario hace X
- **THEN** el sistema hace Y

## MODIFIED Requirements

### Requirement: Funcionalidad Existente
El sistema DEBE seguir haciendo lo existente, ahora también manejando A.

#### Scenario: Escenario que la especificación principal ya tiene
- **WHEN** el usuario hace X
- **THEN** el sistema hace Y

#### Scenario: Nuevo escenario para agregar
- **WHEN** el usuario hace A
- **THEN** el sistema hace B

## REMOVED Requirements

### Requirement: Funcionalidad Obsoleta

## RENAMED Requirements

- FROM: `### Requirement: Nombre Antiguo`
- TO: `### Requirement: Nuevo Nombre`

Referencia de Formato de Especificación Principal

Las especificaciones principales son en las que se fusiona el delta. Nunca deben contener encabezados de operación delta (## ADDED/MODIFIED/REMOVED/RENAMED Requirements) — después de la sincronización, cada requisito vive bajo una sola sección ## Requirements:

# Especificación de <capacidad>

## Purpose
Descripción breve de lo que hace esta capacidad y por qué existe.

## Requirements

### Requirement: Nueva Funcionalidad
El sistema DEBE hacer algo nuevo.

#### Scenario: Caso básico
- **WHEN** el usuario hace X
- **THEN** el sistema hace Y

Principio Clave: Fusión Inteligente

A diferencia de la fusión programática, fusionas en lugar de sobrescribir:

  • Un bloque MODIFIED lleva todo el requisito — cuerpo más cada escenario que sobrevive al cambio. Tanto openspec validate como openspec archive rechazan uno que elimine un escenario que la especificación principal aún tiene.
  • Mantén cualquier cosa que el delta no mencione, en el orden existente de la especificación principal.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Skills relacionados