Dev avec OpenCode et OpenSpec

Objectifs

Mes premiers essais de développements avec l'IA n'étaient pas concluants (vibe coding 'à l'arrache', avec un code généré 'au fil de l'eau', selon l'humeur du LLM.

Nous allons explorer le développement IA piloté par les spécifications (Spec-driven IA devlopment).

J'ai choisi d'utiliser OpenCode et OpenSpec pour cette expérimentation.

L'objectif final sera la création d'une application web pour calculer des hash de fichiers.

Installation et configuration de OpenCode

  • Installation d'opencode avec Brew
$ brew install opencode
  • Configuration de opencode:
 cat ~/.config/opencode/opencode.jsonc 
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {



    "my-ai-privider": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "MYGPT",
      "options": {
        "baseURL": "https://llm.provider.com/v1"
      },
      "models": {
        "gpt-5.5:latest": {
          "name": "gpt-5.5:latest"
        }
      }
    }
  }

}

  • Premier lancement

Le problème d'utiliser OpenCode tout seul

Un assistant de programmation comme OpenCode est capable de générer énormément de code très rapidement.

Mais cela pose un problème : si on demande directement à l'IA de développer une application, elle doit interpréter notre intention à partir du prompt.

Un prompt unique laisse trop de liberté a notre LLM pour générer du code.

La solution, c'est de confier à Open Spec la méthodologie, et à Open Code la génération du code (guidée par les directives issues de OpenSpec)

OpenSpec créer un contrat entre le développeur et l'agent IA.

Exemple de développement

Le projet s'appelle web-hasher.
Il se compose d'un serveur web autonome écrit en Go.
Le serveur exposera une API restpermettant de calculer le hash d'un fichier.
Le serveur fournira une page web avec son code javascript pour que l'utilisateur puisse charger son fichier et choisir l'algo de hash:

  1. Selectionner un fichier local et l'algo de hash
  2. Cliquer sur un bouton (Générer Hash)
  3. Appel de l'API et récupération du hash
  4. afficher le hash obtenu.

Nous allons utiliser:

  • Go pour le serveur ;
  • HTML/CSS pour l'interface ;
  • OpenCode pour l'implémentation ;
  • OpenSpec pour spécifier et piloter le développement.

Lancement du projet web-hasher

  • Installation d'opencode et openspec
$ brew install opencode openspec

$ openspec --version
1.9.0
$ opencode --version
1.17.5



  • Création du projet web-hasher

$ mkdir web-hasher
$ cd web-hasher
$ git init
  • Initialisation du contexte openspec
$ openspec init

openspec nous demande de choisir quel agent de dev nous allons utiliser, et va créer son espace de travail local au projet:

// Nouveau répertoire créé dans le projet
openspec/
  ├── config.yaml
  ├── specs/
  └── changes/
       └── archive/

... A ce stade, nous n'avons pas écrit de code.
Nous allons maintenant réfléchir à ce que nous voulons construire.

  • Workflow OpenSpec
┌──────────────┐
│    Explore   │
│  réfléchir   │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│   Propose    │
│ spécifier    │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│    Review    │
│    valider   │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│    Apply     │
│   coder      │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│    Verify    │
│   tester     │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│   Archive    │
│  officialiser│
└──────────────┘
  • Exploration

Cette étape permet de réfléchir au problème avec l'agent avant de produire un plan. Il n'y aura aucune modification de code, mais un échange entre OpenSpec et le développeur pour cadrer le projet :

opencode > /opsx-explore
...

Je veux réaliser une application web qui va me permettre d'uploader un fichier depuis un formulaire web, de choisir l'algo de hashage. 

Une fois que je validerai le formulaire, le hash du fichier sera affiché à l'utilisateur.

L'application sera écrite en Go, ouvrira une socket sur le port 8080. 
Elle servira les assets http et js pour afficher le formulaire. 

Elle exposera une API rest pour calculer le hash et l'afficher a l'utilisateur. 

Le code .js sera embarqué dans la page html

Si besoin, pose moi quelques questions pour préciser la demande

Maintenant, OpenSpec via OpenCode va poser des questions pour compléter les specifications:

Quels ciphers ? 
Accessible en local ou tout le réseau ?
Limiter la concurrence d'appels  ?
Authentification ou pas  ?

C'est l'occasion de donner plus de détails, et répondre aux questions posées pour mieux cadrer la demande.

Exemple:

Question centrale pour avancer : quelle taille maximale de fichier veux-tu accepter, et quels algorithmes veux-tu supporter au départ ?
▣  Build · fdj-gpt-5.5:latest · 24.2s

> max 100Mo, algo classiques disponibles en go 

Génération du changement et revue

Une fois qu'on a fini l'exploration, on va proposer un changement

opencode> /opsx-propose  hasher-web-base

OpenSpec va alors créer un change.

openspec/
└── changes/
    └── hasher-web-base/
        ├── proposal.md
        ├── specs/
        ├── design.md
        └── tasks.md

C'est maintenant qu'il faut faire la review des fichiers de specifications pour l'adapter a ce que l'on veut ou pour compléter / supprimer certaines rêgles.

On peut amender les specs manuellement ou via l'IA. exemple:

Opencode > Ajoute un readme.md avec les instructions de build et run, ajoute un copyright LICENCE bsd.

Génération du code

Maintenant que les specs sont bien cadrées, on peut lancer l'implémentation :

/opx-apply hasher-web-base

  • En cas de bug dans la feature en cours
J'ai trouvé un bug dans l'implémentation du change hasher-web-base

La spec existante a été mise à jour dans specs/....
pour préciser le comportement attendu dans le cas ou .... .

Je veux que tu :

1. relises la spec modifiée ;
2. identifies l'implémentation actuelle qui provoque le 500 ;
3. corriges le code pour respecter la spec ;
4. ajoutes un test automatisé couvrant le scénario "Invalid password" ;
5. exécutes les tests concernés ;
6. ne modifies pas le comportement des autres scénarios de login.

La suite

On continue avec un nouveau cycle explore - propose - apply 😄