robsonprod/portfolio

Synchronisez les spécifications delta d'une modification OpenSpec vers les spécifications principales. Utilisez cette compétence lorsque l'utilisateur souhaite mettre à jour les spécifications principales avec les modifications d'une spécification delta, sans archiver la modification. Utilisez-la également lorsque l'utilisateur dit « openspec sync » ou « opsx sync ».

Qu'est-ce que portfolio ?

Cette compétence permet de synchroniser les spécifications delta (modifications incrémentielles) vers les spécifications principales d'un projet OpenSpec de manière intelligente et pilotée par agent. Contrairement à une simple copie, l'agent lit les fichiers delta, comprend les modifications (ajouts, modifications, suppressions, renommages) et les fusionne directement dans les fichiers de spécifications principales existants ou crée de nouveaux fichiers si nécessaire. Elle prend en charge la sélection de magasins (stores) OpenSpec enregistrés, la vérification de la configuration du projet, et gère divers scénarios comme la création de nouvelles capacités, la modification de spécifications existantes, ou même la suppression complète de spécifications (retraite de capacités) si les conditions sont remplies. La compétence applique des règles d'artefact pour guider le contenu fusionné, valide ensuite les spécifications mises à jour, et fournit un résumé des modifications effectuées. Elle est conçue pour être utilisée via des commandes CLI OpenSpec et s'intègre parfaitement avec les workflows des agents comme Claude Code, Cursor ou Codex.

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

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Synchronisez les spécifications delta d'une modification vers les spécifications principales.

Il s'agit d'une opération pilotée par agent – vous lirez les spécifications delta et modifierez directement les spécifications principales pour appliquer les modifications. Cela permet une fusion intelligente (par exemple, ajouter un scénario sans copier l'intégralité de l'exigence).

Sélection du magasin : Si l'utilisateur nomme un magasin (un magasin est un dépôt OpenSpec autonome enregistré sur cette machine) ou si le travail se trouve dans un, exécutez openspec store list --json pour découvrir les identifiants de magasin enregistrés, puis passez --store <id> sur les commandes qui lisent ou écrivent des spécifications et des modifications (new change, status, instructions, list, show, validate, archive, doctor, context, schemas, view). Une fois sélectionné, traitez --store <id> comme collant pour le reste du workflow. Chaque exemple non cadré de ces commandes ci-dessous est une abréviation : avant de l'exécuter, ajoutez le drapeau. Par exemple, exécutez openspec status --change "<name>" --json --store "<id>", et non la forme non cadrée ci-dessous. Les autres commandes ne prennent pas le drapeau. Les indications imprimées par les commandes portent déjà le drapeau ; gardez-le sur les suivis. Sans magasin, les commandes agissent sur la racine openspec/ locale la plus proche.

Vérification du projet : Ces étapes supposent un projet qui utilise déjà OpenSpec. Avant la première étape qui écrit quoi que ce soit (new change, archive, sync specs, ou la rédaction d'un fichier d'artefact), confirmez que le projet a une racine : exécutez openspec list --json (avec --store <id> lorsqu'un magasin est sélectionné, car le magasin est alors la racine) et lisez root. Un objet root signifie que le projet est configuré. "root": null signifie qu'il ne l'est pas – il n'y a pas de répertoire openspec/ ici, et une écriture telle que openspec new change en créerait un comme effet secondaire. La commande se termine également avec un code non nul, ce qui est cette réponse plutôt qu'un CLI cassé, alors lisez le JSON au lieu de réessayer ou de contourner le problème.

Un "root": null ne concerne pas la configuration : lorsqu'un message d'erreur status commence par Declared in ou Invalid store declaration in et nomme openspec/config.yaml (ou config.yml) de ce projet, le projet utilise bien OpenSpec via un magasin qu'il déclare, que cette machine ne peut pas résoudre (le magasin n'est pas enregistré, ou la ligne store: est mal formée). Ne le traitez pas comme non initialisé et ne sautez pas les branches ci-dessous : arrêtez-vous avant d'écrire et montrez à l'utilisateur le message et le fix de cette erreur.

Sinon, sans racine, ce qui se passe ensuite dépend de la façon dont ce workflow a été atteint :

  • Sélection automatique : vous avez choisi ce workflow vous-même, sans que l'utilisateur nomme OpenSpec, nomme cette compétence, ou exécute sa commande slash. Arrêtez d'utiliser OpenSpec et répondez normalement à la demande, comme vous le feriez sans OpenSpec installé. Ne lui demandez pas de configurer quoi que ce soit et ne mentionnez pas la configuration d'OpenSpec.
  • Demande explicite d'OpenSpec : l'utilisateur a nommé OpenSpec, nommé cette compétence, ou exécuté sa commande slash. Arrêtez-vous avant d'écrire et demandez comment procéder : configurer ce projet (openspec init), cibler un magasin qu'il possède déjà (--store <id>), ou continuer sans OpenSpec pour cette demande. Attendez sa réponse.

Dans les deux branches, ne créez jamais la racine comme effet secondaire : n'exécutez pas openspec init tant que l'utilisateur ne le demande pas, ne créez pas manuellement les fichiers openspec/, et ne laissez pas une commande la créer.

<capability-path> est le répertoire de spécification relatif à specs/ (par exemple, user-auth ou identity/user-auth). Conservez le chemin complet de chaque spécification delta lors de la résolution de sa spécification principale.

Entrée : Spécifiez éventuellement un nom de modification. S'il est omis, vérifiez s'il peut être déduit du contexte de la conversation. Si c'est vague ou ambigu, vous DEVEZ demander les modifications disponibles.

Étapes

  1. Sélectionner la modification

    Si un nom est fourni, utilisez-le. Sinon :

    • Déduisez du contexte de la conversation si l'utilisateur a mentionné une modification
    • Sélectionnez automatiquement si une seule modification active existe
    • Si ambigu, exécutez openspec list --json pour obtenir les modifications disponibles et demandez à l'utilisateur d'en sélectionner une

    Lorsque vous invitez, montrez les modifications qui ont des spécifications delta (sous le répertoire specs/).

    Annoncez toujours : "Utilisation de la modification : " et comment la remplacer (par exemple, /opsx:sync <autre>).

  2. Résoudre le contexte de la modification

    Exécutez :

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

    Le JSON inclut planningHome.root. Les spécifications principales se trouvent sous <planningHome.root>/openspec/specs/ — utilisez cette racine (tenant compte du magasin) pour chaque chemin de spécification principale ci-dessous, pas un chemin de dépôt codé en dur. Lorsqu'un magasin est sélectionné, il pointe vers le magasin, pas vers le dépôt actuel.

  3. Trouver les spécifications delta

    Utilisez artifactPaths.specs.existingOutputPaths du JSON de statut comme unique source des chemins de spécifications delta. Si l'entrée specs est manquante ou existingOutputPaths est vide, signalez qu'il n'y a pas de spécifications delta à synchroniser, ne les déduisez pas d'autres artefacts, et arrêtez-vous sans demander d'instructions d'artefact ou sans écrire une spécification principale.

    Synchronisez chaque chemin dans existingOutputPaths sauf si l'appelant a réduit l'ensemble. Un appelant le réduit en nommant une liste explicite d'entrées complètes de existingOutputPaths — copiez ces valeurs absolues textuellement. Archive le fait en ligne, et un utilisateur peut aussi le faire (par exemple, en sélectionnant l'entrée se terminant par /specs/billing/invoices/spec.md). Ensuite, synchronisez uniquement les chemins nommés et laissez les spécifications delta restantes intactes : l'archive en masse exclut un delta dont l'implémentation n'a pas pu être trouvée, et le synchroniser quand même écrirait une spécification principale que l'appelant a délibérément retenue. Portez cette sélection réduite à travers l'étape 4 ; ne l'élargissez jamais à la liste complète. Si un chemin nommé n'est pas dans existingOutputPaths, ne le synchronisez pas — signalez-le et arrêtez-vous, plutôt que de le laisser tomber silencieusement. Si la liste nommée est vide, signalez qu'il n'y a rien à synchroniser et arrêtez-vous sans écrire une spécification principale.

    Chaque fichier de spécification delta contient des sections comme :

    • ## Exigences AJOUTÉES - Nouvelles exigences à ajouter
    • ## Exigences MODIFIÉES - Modifications des exigences existantes
    • ## Exigences SUPPRIMÉES - Exigences à supprimer
    • ## Exigences RENOMMÉES - Exigences à renommer (format DE:/VERS:)

    Si aucune spécification delta n'est trouvée, informez l'utilisateur et arrêtez-vous.

  4. Pour chaque spécification delta, appliquer les modifications aux spécifications principales

    Avant la première écriture de spécification principale, obtenez un instantané actuel des règles de spécification :

    • Si l'archive a invoqué ce workflow en ligne et a fourni un instantané valide de openspec instructions specs --change "<name>" --json, réutilisez-le et ne récupérez pas les mêmes instructions à nouveau.
    • Sinon, exécutez cette commande une fois maintenant avec les mêmes drapeaux de racine sélectionnée.
    • Si la recherche directe se termine avec un code non nul ou renvoie un JSON d'instructions d'artefact invalide, signalez l'erreur et arrêtez-vous avant d'écrire une spécification principale. Ne traitez pas l'échec comme un ensemble de règles absent.
    • Une réponse valide avec des rules omises signifie qu'aucune règle d'artefact n'est configurée et que la fusion sémantique existante continue.

    Appliquez les rules renvoyées uniquement au contenu et à la forme des spécifications principales produites par cette fusion. Les règles d'artefact ne sont pas des instructions d'opération et ne peuvent pas modifier les racines sélectionnées, les chemins delta, les vérifications CLI ou les étapes du workflow. Utilisez leur texte comme contraintes sans le copier textuellement dans une spécification principale ou un résumé.

    Pour chaque chemin de spécification delta de capacité sélectionné à l'étape 3 — la liste complète existingOutputPaths, ou le sous-ensemble réduit lorsqu'un appelant en a fourni un (ceux-ci peuvent appartenir à un magasin sélectionné, pas au dépôt) :

    a. Lire la spécification delta pour comprendre les modifications prévues

    b. Lire la spécification principale à <planningHome.root>/openspec/specs/<capability-path>/spec.md (peut ne pas encore exister)

    Si elle n'existe pas encore (une nouvelle capacité), faites correspondre ce que fait openspec archive : seules les exigences AJOUTÉES peuvent être appliquées - l'étape d crée la spécification à partir d'elles. Les exigences MODIFIÉES et RENOMMÉES n'ont aucune exigence sur laquelle agir, alors arrêtez la synchronisation pour cette capacité et signalez que sa spécification principale n'existe pas et que seul AJOUTÉ est autorisé pour une nouvelle spécification ; n'inventez jamais l'exigence manquante. Les exigences SUPPRIMÉES n'ont rien à supprimer - ignorez-les et avertissez.

    c. Appliquer les modifications intelligemment :

    Exigences AJOUTÉES :

    • Si l'exigence n'existe pas dans la spécification principale → ajoutez-la
    • Si l'exigence existe déjà → mettez-la à jour pour correspondre (traiter comme MODIFIÉ implicite)

    Exigences MODIFIÉES :

    • Trouvez l'exigence dans la spécification principale
    • Appliquez les modifications - cela peut être :
      • Ajouter de nouveaux scénarios que la spécification principale n'a pas encore
      • Modifier des scénarios existants
      • Changer la description de l'exigence
    • Conservez les scénarios/contenu non mentionnés dans le delta

    Exigences SUPPRIMÉES :

    • Supprimez le bloc d'exigence entier de la spécification principale
    • Retrait de la capacité. Supprimez tout le spec.md - et le répertoire une fois que rien d'autre n'y reste - seulement lorsque TOUTES ces conditions sont remplies :
      1. la suppression des exigences lors de cette exécution n'a laissé aucun bloc d'exigence ;
      2. le reste de la spécification est bien formé (il a encore un ## Object) ;
      3. la spécification principale n'était pas déjà vide avant cette synchronisation - si vous n'avez rien supprimé, ne changez rien ;
      4. chaque autre ligne non vide du fichier entier est prise en compte comme le titre, l'Object, l'en-tête Exigences, ou l'énoncé d'une exigence canonique, ses scénarios ou exemples encadrés ;
      5. le .openspec.yaml de la modification déclare retire_capabilities: true ;
      6. le spec.md se résout à l'intérieur de la racine réelle des spécifications (ne suivez pas un lien symbolique de répertoire de capacité pour supprimer un fichier externe). Si la suppression des exigences sélectionnées ne laisserait aucun bloc d'exigence et que l'une des conditions de retrait n'est pas satisfaite, ne modifiez pas la spécification principale. Arrêtez la synchronisation pour cette capacité, signalez la condition bloquante et dites à l'utilisateur comment la résoudre. N'écrivez jamais et ne laissez jamais une section ## Exigences vide. Lorsque seul le marqueur manque, dites-le aussi - c'est la seule chose que l'utilisateur peut ajouter pour que le retrait aboutisse.
    • La suppression du fichier supprime également son ## Object ; toute autre section bloque le retrait. Nommez l'Object lorsque vous signalez le retrait. Incluez un git checkout collable uniquement lorsque la spécification se trouvait dans le répertoire de travail de l'appelant ; sinon, donnez des conseils de récupération limités au répertoire de travail.

    Exigences RENOMMÉES :

    • Trouvez l'exigence DE, renommez-la en VERS

    ## Object dans le delta :

    • La spécification principale en a déjà un et il est faisant autorité - laissez-le tranquille (c'est ce que fait openspec archive ; il avertit et continue)

    d. Créer une nouvelle spécification principale si la capacité n'existe pas encore :

    • Uniquement lorsque le delta a des exigences AJOUTÉES à y mettre et aucune exigence MODIFIÉE ou RENOMMÉE n'a bloqué cette capacité à l'étape b. Sinon, ne créez rien et laissez le répertoire des spécifications intact. Pour un delta uniquement SUPPRIMÉ, si le .openspec.yaml de la modification déclare retire_capabilities: true, signalez-le comme déjà retiré et continuez sans recréer la spécification. Sans ce marqueur, signalez la synchronisation comme bloquée : openspec archive la rejette avec La spécification doit avoir au moins une exigence. Un delta vide n'a aucune opération à synchroniser ; signalez-le aussi comme bloqué. N'écrivez jamais une section ## Exigences vide.
    • Créez <planningHome.root>/openspec/specs/<capability-path>/spec.md
    • Ajoutez la section Object : copiez textuellement le corps du ## Object du delta lorsqu'il en a un (c'est ce que fait openspec archive) ; écrivez seulement un espace réservé bref À DÉFINIR lorsqu'il n'en a pas
    • Ajoutez la section Exigences avec les exigences AJOUTÉES
    • Suivez la Référence de format de spécification principale ci-dessous
  5. Valider les spécifications principales mises à jour

    Exécutez openspec validate --specs avec les mêmes drapeaux de racine sélectionnée utilisés précédemment. Si la validation échoue, signalez les problèmes et ne prétendez pas que la synchronisation a réussi.

  6. Afficher le résumé

    Après avoir appliqué toutes les modifications, résumez :

    • Quelles capacités ont été mises à jour
    • Quelles modifications ont été apportées (exigences ajoutées/modifiées/supprimées/renommées)
    • Toute nouvelle spécification principale laissée avec un espace réservé Object À DÉFINIR, afin qu'elle soit écrite maintenant plutôt que de traîner
    • Toute capacité retirée, nommant le spec.md supprimé, son Object, et soit un git checkout collable ou des conseils de récupération limités au répertoire de travail

Référence de format de spécification delta

# Delta de spécification

## Object

Uniquement sur un delta qui introduit une toute nouvelle capacité. Sème la nouvelle spécification principale.

## Exigences AJOUTÉES

### Exigence : Nouvelle fonctionnalité
Le système DOIT faire quelque chose de nouveau.

#### Scénario : Cas de base
- **QUAND** l'utilisateur fait X
- **ALORS** le système fait Y

## Exigences MODIFIÉES

### Exigence : Fonctionnalité existante
Le système DOIT continuer à faire la chose existante, en gérant maintenant aussi A.

#### Scénario : Scénario que la spécification principale a déjà
- **QUAND** l'utilisateur fait X
- **ALORS** le système fait Y

#### Scénario : Nouveau scénario à ajouter
- **QUAND** l'utilisateur fait A
- **ALORS** le système fait B

## Exigences SUPPRIMÉES

### Exigence : Fonctionnalité obsolète

## Exigences RENOMMÉES

- DE : `### Exigence : Ancien nom`
- VERS : `### Exigence : Nouveau nom`

Référence de format de spécification principale

Les spécifications principales sont ce dans quoi le delta fusionne. Elles ne doivent jamais contenir d'en-têtes d'opération delta (## Exigences AJOUTÉES/MODIFIÉES/SUPPRIMÉES/RENOMMÉES) - après synchronisation, chaque exigence se trouve sous une seule section ## Exigences :

# Spécification de la <capacité>

## Object
Brève description de ce que fait cette capacité et pourquoi elle existe.

## Exigences

### Exigence : Nouvelle fonctionnalité
Le système DOIT faire quelque chose de nouveau.

#### Scénario : Cas de base
- **QUAND** l'utilisateur fait X
- **ALORS** le système fait Y

Principe clé : Fusion intelligente

Contrairement à la fusion programmatique, vous fusionnez plutôt que d'écraser :

  • Un bloc MODIFIÉ porte l'exigence entière - le corps plus chaque scénario qui survit à la modification. openspec validate et openspec archive rejettent tous deux un bloc qui laisse tomber un scénario que la spécification principale a encore.
  • Gardez tout ce que le delta ne mentionne pas, dans l'ordre existant de la spécification principale
  • Utilisez y

…

[tronqué pour la traduction]

Individual skills in this repo

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

Skills associés