robsonprod/portfolio

Sincroniza especificações delta de uma alteração do OpenSpec para as especificações principais. Use quando o usuário quiser atualizar as especificações principais com alterações de uma especificação delta sem arquivar a alteração.

O que é portfolio?

Esta skill permite que um agente de IA sincronize alterações de especificações delta (geradas a partir de mudanças no OpenSpec) de volta para as especificações principais de um projeto. Ao invés de sobrescrever arquivos inteiros, a skill realiza uma mesclagem inteligente, adicionando, modificando, renomeando ou removendo requisitos específicos com base no conteúdo das especificações delta. É útil para desenvolvedores e agentes que gerenciam especificações com o OpenSpec e precisam aplicar alterações incrementais de forma controlada, sem perder o histórico ou contexto da especificação principal. A skill suporta a seleção de armazenamentos (stores) do OpenSpec e inclui etapas de validação para garantir que as especificações finais estejam corretas. O processo envolve ler as especificações delta, aplicar as alterações nas especificações principais (que seguem um formato específico), validar o resultado com `openspec validate` e fornecer um resumo das alterações realizadas.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/robsonprod/portfolio/tree/HEAD/.claude/skills/openspec-sync-specs

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Sincroniza especificações delta de uma alteração para as especificações principais.

Esta é uma operação orientada por agente - você lerá as especificações delta e editará diretamente as especificações principais para aplicar as alterações. Isso permite uma mesclagem inteligente (por exemplo, adicionar um cenário sem copiar o requisito inteiro).

Seleção de armazenamento: Se o usuário nomear um armazenamento (um armazenamento é um repositório OpenSpec independente registrado nesta máquina) ou o trabalho estiver em um, execute openspec store list --json para descobrir os IDs de armazenamento registrados e, em seguida, passe --store <id> nos comandos que leem ou escrevem especificações e alterações (new change, status, instructions, list, show, validate, archive, doctor, context, schemas, view). Uma vez selecionado, trate --store <id> como fixo para o restante do fluxo de trabalho. Cada exemplo sem escopo desses comandos abaixo é uma abreviação: antes de executá-lo, anexe a flag. Por exemplo, execute openspec status --change "<nome>" --json --store "<id>", não a forma sem escopo mostrada abaixo. Outros comandos não aceitam a flag. Dicas impressas pelos comandos já carregam a flag; mantenha-a nas ações de acompanhamento. Sem um armazenamento, os comandos agem na raiz local mais próxima openspec/.

Verificação do projeto: Estas etapas esperam um projeto que já usa o OpenSpec. Antes da primeira etapa que escreve algo (new change, archive, sync specs ou criar um arquivo de artefato), confirme que o projeto tem uma raiz: execute openspec list --json (com --store <id> quando um armazenamento for selecionado, pois o armazenamento é então a raiz) e leia root. Um objeto root significa que o projeto está configurado. "root": null significa que não está - não há um diretório openspec/ aqui, e uma gravação como openspec new change criaria um como efeito colateral. O comando também sai com código não zero, que é essa resposta em vez de uma CLI quebrada, então leia o JSON em vez de tentar novamente ou contornar.

Um caso de "root": null não é sobre configuração: quando uma mensagem de erro status começa com Declared in ou Invalid store declaration in e nomeia o openspec/config.yaml (ou config.yml) deste projeto, o projeto usa o OpenSpec através de um armazenamento que declara, mas que esta máquina não pode resolver (o armazenamento não está registrado, ou a linha store: está malformada). Não trate como não inicializado e pule os ramos abaixo: pare antes de escrever e mostre ao usuário a message e o fix desse erro.

Caso contrário, sem raiz, o que acontece a seguir depende de como este fluxo de trabalho foi alcançado:

  • Selecionado automaticamente: você escolheu este fluxo de trabalho por conta própria, sem o usuário nomear OpenSpec, nomear esta skill ou executar seu comando de barra. Pare de usar OpenSpec e responda à solicitação normalmente, como faria sem o OpenSpec instalado. Não peça para configurar nada e não mencione a configuração do OpenSpec.
  • Solicitação explícita do OpenSpec: o usuário nomeou o OpenSpec, nomeou esta skill ou executou seu comando de barra. Pare antes de escrever e pergunte como proceder: configurar este projeto (openspec init), direcionar um armazenamento que eles já têm (--store <id>) ou continuar sem o OpenSpec para esta solicitação. Aguarde a resposta.

Em ambos os ramos, nunca crie a raiz como efeito colateral: não execute openspec init até que o usuário peça, não crie manualmente arquivos openspec/ e não deixe um comando criá-lo.

<caminho-da-capacidade> é o diretório da especificação relativo a specs/ (por exemplo, user-auth ou identity/user-auth). Preserve o caminho completo de cada especificação delta ao resolver sua especificação principal.

Entrada: Opcionalmente, especifique um nome de alteração. Se omitido, verifique se pode ser inferido do contexto da conversa. Se vago ou ambíguo, você DEVE solicitar as alterações disponíveis.

Passos

  1. Selecionar a alteração

    Se um nome for fornecido, use-o. Caso contrário:

    • Infira do contexto da conversa se o usuário mencionou uma alteração
    • Selecione automaticamente se apenas uma alteração ativa existir
    • Se ambíguo, execute openspec list --json para obter as alterações disponíveis e peça ao usuário para selecionar uma

    Ao solicitar, mostre as alterações que têm especificações delta (sob o diretório specs/).

    Sempre anuncie: "Usando alteração: " e como substituir (por exemplo, /opsx:sync <outro>).

  2. Resolver contexto da alteração

    Execute:

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

    O JSON inclui planningHome.root. As especificações principais residem em <planningHome.root>/openspec/specs/ — use essa raiz (ciente do armazenamento) para cada caminho de especificação principal abaixo, não um caminho de repositório codificado. Quando um armazenamento for selecionado, ele aponta para o armazenamento, não para o repositório atual.

  3. Encontrar especificações delta

    Use artifactPaths.specs.existingOutputPaths do JSON de status como a única fonte de caminhos de especificação delta. Se a entrada specs estiver faltando ou existingOutputPaths estiver vazio, informe que não há especificações delta para sincronizar, não as infira de outros artefatos e pare sem solicitar instruções de artefato ou escrever uma especificação principal.

    Sincronize cada caminho em existingOutputPaths a menos que o chamador tenha restringido o conjunto. Um chamador restringe nomeando uma lista explícita de entradas completas de existingOutputPaths — copie esses valores absolutos literalmente. Archive faz isso embutido, e um usuário também pode (por exemplo, selecionando a entrada que termina em /specs/billing/invoices/spec.md). Em seguida, sincronize apenas os caminhos nomeados e deixe as especificações delta restantes intocadas: o arquivamento em massa exclui um delta cuja implementação não pôde encontrar, e sincronizá-lo de qualquer maneira escreveria uma especificação principal que o chamador reteve deliberadamente. Carregue essa seleção restringida através do passo 4; nunca a amplie de volta para a lista completa. Se um caminho nomeado não estiver em existingOutputPaths, não o sincronize — relate e pare, em vez de descartá-lo silenciosamente. Se a lista nomeada estiver vazia, informe que não há nada para sincronizar e pare sem escrever uma especificação principal.

    Cada arquivo de especificação delta contém seções como:

    • ## ADDED Requirements - Novos requisitos a adicionar
    • ## MODIFIED Requirements - Alterações em requisitos existentes
    • ## REMOVED Requirements - Requisitos a remover
    • ## RENAMED Requirements - Requisitos a renomear (formato FROM:/TO:)

    Se nenhuma especificação delta for encontrada, informe o usuário e pare.

  4. Para cada especificação delta, aplicar alterações às especificações principais

    Antes da primeira gravação de especificação principal, obtenha um instantâneo atual das regras de especificação:

    • Se o arquivamento invocou este fluxo de trabalho embutido e forneceu um instantâneo válido de openspec instructions specs --change "<nome>" --json, reutilize-o e não busque as mesmas instruções novamente.
    • Caso contrário, execute esse comando uma vez agora com as mesmas flags de raiz selecionada.
    • Se a consulta direta sair com código não zero ou retornar JSON inválido de instrução de artefato, relate o erro e pare antes de escrever qualquer especificação principal. Não trate a falha como um conjunto de regras ausente.
    • Uma resposta válida com rules omitido significa que nenhuma regra de artefato está configurada e a mesclagem semântica existente continua.

    Aplique as rules retornadas apenas ao conteúdo e forma das especificações principais produzidas por esta mesclagem. Regras de artefato não são orientação operacional e não podem alterar raízes selecionadas, caminhos delta, verificações de CLI ou passos do fluxo de trabalho. Use seu texto como restrições sem copiá-lo literalmente para uma especificação principal ou resumo.

    Para cada caminho de especificação delta de capacidade selecionado no passo 3 — a lista completa existingOutputPaths, ou o subconjunto restringido quando um chamador forneceu um (estes podem pertencer a um armazenamento selecionado, não ao repositório):

    a. Leia a especificação delta para entender as alterações pretendidas

    b. Leia a especificação principal em <planningHome.root>/openspec/specs/<caminho-da-capacidade>/spec.md (pode não existir ainda)

    Se não existir ainda (uma nova capacidade), corresponda ao que openspec archive faz: apenas requisitos ADDED podem ser aplicados - o passo d cria a especificação a partir deles. MODIFIED e RENAMED não têm requisito para atuar, então pare a sincronização para essa capacidade e relate que sua especificação principal não existe e apenas ADDED é permitido para uma nova especificação; nunca invente o requisito ausente. REMOVED não tem nada a remover - ignore e avise.

    c. Aplique as alterações de forma inteligente:

    ADDED Requirements:

    • Se o requisito não existir na especificação principal → adicione-o
    • Se o requisito já existir → atualize-o para corresponder (trate como MODIFIED implícito)

    MODIFIED Requirements:

    • Encontre o requisito na especificação principal
    • Aplique as alterações - isso pode ser:
      • Adicionar novos cenários que a especificação principal ainda não tem
      • Modificar cenários existentes
      • Alterar a descrição do requisito
    • Preserve cenários/conteúdo não mencionados no delta

    REMOVED Requirements:

    • Remova o bloco de requisito inteiro da especificação principal
    • Aposentando a capacidade. Exclua todo o spec.md - e o diretório uma vez que nada mais reste nele - apenas quando TODOS os seguintes se aplicarem:
      1. remover os requisitos desta execução não deixou blocos de requisito;
      2. o restante da especificação está bem formado (ainda tem um ## Purpose);
      3. a especificação principal não estava vazia antes desta sincronização - se você removeu nada, não mude nada;
      4. toda outra linha não vazia no arquivo inteiro é contabilizada como o título, Purpose, cabeçalho Requirements, ou a declaração de um requisito canônico, cenários ou exemplos em bloco de código;
      5. o .openspec.yaml da alteração declara retire_capabilities: true;
      6. o spec.md resolve dentro da raiz real de especificações (não siga um link simbólico de diretório de capacidade para excluir um arquivo externo). Se remover os requisitos selecionados deixaria nenhum bloco de requisito e qualquer condição de aposentadoria não for satisfeita, não modifique a especificação principal. Pare a sincronização para essa capacidade, relate a condição bloqueadora e diga ao usuário como resolvê-la. Nunca escreva ou deixe uma seção ## Requirements vazia. Quando apenas o marcador estiver faltando, diga isso também - é a única coisa que o usuário pode adicionar para fazer a aposentadoria passar.
    • Excluir o arquivo também exclui seu ## Purpose; qualquer outra seção bloqueia a aposentadoria. Nomeie Purpose quando você relatar a aposentadoria. Inclua um git checkout copiável apenas quando a especificação estava no checkout do chamador; caso contrário, forneça orientação de recuperação com escopo de checkout.

    RENAMED Requirements:

    • Encontre o requisito FROM, renomeie para TO

    ## Purpose no delta:

    • A especificação principal já tem um e é autoritativo - deixe-o em paz (isto é o que openspec archive faz; ele avisa e segue em frente)

    d. Crie nova especificação principal se a capacidade ainda não existir:

    • Apenas quando o delta tem requisitos ADDED para colocar nela e nenhum requisito MODIFIED ou RENAMED bloqueou esta capacidade no passo b. Caso contrário, não crie nada e deixe o diretório de especificações intocado. Para um delta apenas REMOVED, se o .openspec.yaml da alteração declarar retire_capabilities: true, relate como já aposentado e continue sem recriar a especificação. Sem esse marcador, relate a sincronização como bloqueada: openspec archive rejeita com Spec must have at least one requirement. Um delta vazio não tem operações para sincronizar; relate como bloqueado também. Nunca escreva uma seção ## Requirements vazia.
    • Crie <planningHome.root>/openspec/specs/<caminho-da-capacidade>/spec.md
    • Adicione seção Purpose: copie o corpo do ## Purpose do delta literalmente quando tiver um (isto é o que openspec archive faz); escreva apenas um espaço reservado TBD breve quando não tiver
    • Adicione seção Requirements com os requisitos ADDED
    • Siga a Referência de Formato de Especificação Principal abaixo
  5. Validar especificações principais atualizadas

    Execute openspec validate --specs com as mesmas flags de raiz selecionada usadas anteriormente. Se a validação falhar, relate os problemas e não afirme que a sincronização foi bem-sucedida.

  6. Mostrar resumo

    Após aplicar todas as alterações, resuma:

    • Quais capacidades foram atualizadas
    • Quais alterações foram feitas (requisitos adicionados/modificados/removidos/renomeados)
    • Qualquer nova especificação principal deixada com um espaço reservado TBD Purpose, para que seja escrita agora em vez de ficar pendente
    • Qualquer capacidade aposentada, nomeando o spec.md excluído, seu Purpose, e um git checkout copiável ou orientação de recuperação com escopo de checkout

Referência de Formato de Especificação Delta

# Spec Delta

## Purpose

Apenas em um delta que introduz uma capacidade totalmente nova. Semear a nova especificação principal.

## ADDED Requirements

### Requirement: New Feature
O SISTEMA DEVE fazer algo novo.

#### Scenario: Basic case
- **WHEN** usuário faz X
- **THEN** sistema faz Y

## MODIFIED Requirements

### Requirement: Existing Feature
O SISTEMA DEVE continuar fazendo a coisa existente, agora também lidando com A.

#### Scenario: Scenario que a especificação principal já tem
- **WHEN** usuário faz X
- **THEN** sistema faz Y

#### Scenario: Novo cenário a adicionar
- **WHEN** usuário faz A
- **THEN** sistema faz B

## REMOVED Requirements

### Requirement: Recurso Depreciado

## RENAMED Requirements

- FROM: `### Requirement: Nome Antigo`
- TO: `### Requirement: Novo Nome`

Referência de Formato de Especificação Principal

As especificações principais são para onde o delta mescla. Elas nunca devem conter cabeçalhos de operação delta (## ADDED/MODIFIED/REMOVED/RENAMED Requirements) - após a sincronização, todo requisito fica sob uma única seção ## Requirements:

# Especificação da <capacidade>

## Purpose
Breve descrição do que esta capacidade faz e por que existe.

## Requirements

### Requirement: New Feature
O SISTEMA DEVE fazer algo novo.

#### Scenario: Basic case
- **WHEN** usuário faz X
- **THEN** sistema faz Y

Princípio Chave: Mesclagem Inteligente

Diferente da mesclagem programática, você mescla em vez de sobrescrever:

  • Um bloco MODIFIED carrega todo o requisito - corpo mais cada cenário que sobrevive à alteração. openspec validate e openspec archive ambos rejeitam um que elimina um cenário que a especificação principal ainda tem.
  • Mantenha qualquer coisa que o delta não menciona, na ordem existente da especificação principal
  • Use y

…

[truncado para tradução]

Individual skills in this repo

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

Habilidades Relacionadas