open-design/CONTRIBUTING.fr.md
Zakaria a46764fb1b
Some checks failed
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
first-commit
2026-05-04 14:58:14 -04:00

19 KiB
Raw Permalink Blame History

Contribuer à Open Design

Merci d'envisager de contribuer. OD reste volontairement petit : l'essentiel de la valeur vit dans des fichiers (Skills, Design Systems, morceaux de prompt) plutôt que dans du code de framework. Les contributions les plus utiles sont donc souvent un dossier, un fichier Markdown ou un petit adapter qui tient dans une PR.

Ce guide indique où intervenir pour chaque type de contribution et quel niveau une PR doit atteindre avant dêtre mergée.

English · Deutsch · Français · 简体中文 · 日本語


Trois contributions faisables en un après-midi

Si vous voulez… Vous ajoutez en réalité Où cela vit Taille
Faire générer à OD un nouveau type d'artifact (facture, écran iOS Settings, one-pager…) un Skill skills/<your-skill>/ un dossier, ~2 fichiers
Faire parler à OD le langage visuel d'une nouvelle marque un Design System design-systems/<brand>/DESIGN.md un fichier Markdown
Brancher une nouvelle CLI de coding agent un Agent adapter apps/daemon/src/agents.ts ~10 lignes dans un tableau
Ajouter une feature, corriger un bug, reprendre un pattern UX de open-codesign du code apps/web/src/, apps/daemon/ PR classique
Améliorer la doc, porter une section en Français / Deutsch / 中文, corriger une faute documentation README.md, README.fr.md, README.de.md, README.zh-CN.md, docs/, QUICKSTART.md une PR

Si vous ne savez pas dans quelle catégorie tombe votre idée, ouvrez d'abord une discussion ou une issue et nous vous orienterons vers la bonne surface.


Configuration locale

Le setup complet en une page se trouve dans QUICKSTART.fr.md. TL;DR pour contribuer :

git clone https://github.com/nexu-io/open-design.git
cd open-design
corepack enable           # sélectionne la version de pnpm définie par packageManager
pnpm install
pnpm tools-dev run web    # boucle daemon + web au premier plan
pnpm typecheck            # tsc -b --noEmit
pnpm build                # build production

Node ~24 et pnpm 10.33.x sont requis. nvm / fnm sont optionnels ; utilisez nvm install 24 && nvm use 24 ou fnm install 24 && fnm use 24 si vous gérez Node comme cela. macOS, Linux et WSL2 sont les environnements principaux pris en charge. Windows natif devrait fonctionner, mais ce n'est pas la cible principale : ouvrez une issue si ce n'est pas le cas.

Vous n'avez pas besoin d'une CLI d'agent dans votre PATH pour développer OD. Le daemon indiquera "no agents found" ; utilisez alors le mode API/BYOK (Anthropic, OpenAI, Azure OpenAI ou Google Gemini), qui est souvent la boucle de dev la plus rapide.


Ajouter un nouveau Skill

Un Skill est un dossier sous skills/ avec un SKILL.md à la racine. Il suit la convention Claude Code SKILL.md, plus notre extension optionnelle od:. Aucune étape d'enregistrement. Déposez le dossier, redémarrez le daemon, et le picker l'affiche.

Structure d'un dossier Skill

skills/your-skill/
├── SKILL.md                    # requis
├── assets/template.html        # optionnel mais recommandé — seed file
├── references/                 # optionnel — fichiers de connaissance lus par l'agent
│   ├── layouts.md
│   ├── components.md
│   └── checklist.md
└── example.html                # fortement recommandé — vrai exemple construit à la main

Frontmatter de SKILL.md

Les trois premières clés sont la spec Claude Code de base : name, description, triggers. Tout ce qui est sous od: est spécifique à OD et optionnel, mais od.mode décide dans quel groupe le Skill apparaît. La valeur est extensible ; les modes courants incluent Prototype, Deck, Image, Video, Audio, Design system et Utility.

---
name: your-skill
description: |
  One-paragraph elevator pitch. The agent reads this verbatim to decide
  if the user's brief matches. Be concrete: surface, audience, what's in
  the artifact, what's not.  
triggers:
  - "your trigger phrase"
  - "another phrase"
  - "中文触发词"
od:
  mode: prototype           # prototype | deck | image | video | audio | design-system | utility
  platform: desktop         # desktop | mobile
  scenario: marketing       # free-form tag for grouping
  featured: 1               # any positive integer surfaces it under "Showcase examples"
  preview:
    type: html              # html | jsx | pptx | markdown
    entry: index.html
  design_system:
    requires: true          # does the skill read the active DESIGN.md?
    sections: [color, typography, layout, components]
  example_prompt: "A copy-pastable prompt that nicely shows what this skill does."
---

# Your Skill

Body is free-form Markdown describing the workflow the agent should follow…

La grammaire complète — typed inputs, paramètres de sliders, capability gating — se trouve dans docs/skills-protocol.md.

Critères de merge pour un nouveau Skill

Nous sommes exigeants sur les Skills parce qu'ils constituent la partie la plus visible pour l'utilisateur. Un nouveau Skill doit :

  1. Livrer un vrai example.html. Construit à la main, ouvrable directement depuis le disque, avec un niveau qu'un designer pourrait réellement livrer. Pas de lorem ipsum, pas de hero placeholder en <svg><rect/></svg>. Si vous ne pouvez pas construire l'exemple vous-même, le Skill n'est probablement pas prêt.
  2. Passer l'anti-AI-slop checklist dans le body. Pas de gradients violets, pas d'icônes emoji génériques, pas de carte arrondie avec accent en bord gauche, pas d'Inter comme fonte display, pas de statistiques inventées. Lisez la section Anti-AI-slop machinery du README pour la liste complète.
  3. Utiliser des placeholders honnêtes. Si l'agent n'a pas de vraie donnée, écrivez ou un bloc gris libellé, pas "10× faster".
  4. Avoir un references/checklist.md avec au moins les gates P0, c'est-à-dire ce que l'agent doit vérifier avant d'émettre <artifact>. Reprenez le format de skills/guizang-ppt/references/checklist.md ou skills/dating-web/references/checklist.md.
  5. Ajouter une capture sous docs/screenshots/skills/<skill>.png si le Skill est featured. PNG, environ 1024×640 retina, capturé depuis le vrai example.html avec un zoom navigateur adapté.
  6. Rester dans un dossier autonome. Pas d'import CDN au-delà de ce que les autres Skills utilisent déjà ; pas de fonte sans licence ; pas d'image de plus d'environ 250 KB.

Si vous forkez un Skill existant (par exemple partir de dating-web pour en faire recruiting-web), conservez la LICENSE et l'attribution d'auteur dans references/, et mentionnez-le dans la description de la PR.

Skills existants à imiter


Ajouter un nouveau Design System

Un design system est un seul fichier DESIGN.md sous design-systems/<slug>/. Un fichier, pas de code. Déposez-le, redémarrez le daemon, le picker l'affiche dans sa catégorie.

Structure d'un dossier Design System

design-systems/your-brand/
└── DESIGN.md

Forme de DESIGN.md

# Design System Inspired by YourBrand

> Category: Developer Tools
> One-line summary that shows in the picker preview.

## 1. Visual Theme & Atmosphere
## 2. Color
- Primary: `#hex` / `oklch(...)`
-## 3. Typography
## 4. Spacing & Grid
## 5. Layout & Composition
## 6. Components
## 7. Motion & Interaction
## 8. Voice & Brand
## 9. Anti-patterns

Le schéma à 9 sections est fixe : c'est ce que les Skill bodies cherchent. Le premier H1 devient le label dans le picker (le préfixe Design System Inspired by est retiré automatiquement), et la ligne > Category: … décide du groupe. Les catégories existantes sont listées dans design-systems/README.md ; si votre marque ne rentre vraiment nulle part, vous pouvez en introduire une nouvelle, mais essayez d'abord les catégories existantes.

Critères de merge pour un nouveau Design System

  1. Les 9 sections sont présentes. Des sections vides sont acceptables pour les informations difficiles à trouver (par exemple des tokens de motion), mais les headings doivent exister, sinon la recherche utilisée par le prompt risque de casser.
  2. Les hex codes sont réels. Échantillonnez directement depuis le site ou le produit de la marque, pas de mémoire ni à partir d'une supposition de l'IA. Le protocole d'extraction brand-spec en 5 étapes du README s'applique aussi aux mainteneurs.
  3. Les valeurs OKLch pour les couleurs d'accent sont un plus : elles rendent les palettes plus prévisibles entre light/dark.
  4. Pas de fluff marketing. La tagline d'une marque n'est pas un design token. Coupez-la.
  5. Le slug utilise l'ASCII : linear.app devient linear-app, x.ai devient x-ai. Les systèmes importés suivent déjà cette convention ; imitez-la.

Les product systems livrés sont importés depuis VoltAgent/awesome-design-md via scripts/sync-design-systems.ts. Si votre marque appartient à cet upstream, envoyez d'abord la PR là-bas : OD le récupérera au prochain sync. Le dossier design-systems/ sert aux systèmes qui ne rentrent pas upstream, plus nos starters écrits à la main.


Ajouter une nouvelle CLI de coding agent

Brancher un nouvel agent (par exemple une CLI foo-coder) revient à ajouter une entrée dans apps/daemon/src/agents.ts :

{
  id: 'foo',
  name: 'Foo Coder',
  bin: 'foo',
  versionArgs: ['--version'],
  buildArgs: (prompt) => ['exec', '-p', prompt],
  streamFormat: 'plain',           // or 'claude-stream-json' if it speaks that
}

C'est tout : le daemon la détecte dans le PATH, le picker l'affiche et le chemin chat fonctionne. Si la CLI émet des typed events (comme --output-format stream-json de Claude Code), ajoutez un parser dans apps/daemon/src/claude-stream.ts et mettez streamFormat: 'claude-stream-json'.

Critères de merge :

  1. Une vraie session fonctionne end-to-end avec le nouvel agent. Collez le log daemon dans la description de la PR pour montrer qu'il a streamé un artifact.
  2. docs/agent-adapters.md documente les particularités de la CLI : fichier de clé requis, support de l'image, flag non interactif, etc.
  3. La table "Supported coding agents" du README reçoit une ligne.

Mettre à jour les métadonnées max_tokens des modèles

En mode API, le chat envoie max_tokens au provider upstream à chaque requête. Le client web choisit ce nombre avec une lookup à trois niveaux dans apps/web/src/state/maxTokens.ts :

  1. L'override explicite de l'utilisateur dans Settings, s'il existe.
  2. Sinon, la valeur par modèle dans apps/web/src/state/litellm-models.json, un extrait vendored du model_prices_and_context_window.json de BerriAI/litellm (MIT). Il couvre environ 2k modèles chat chez Anthropic, OpenAI, DeepSeek, Groq, Together, Mistral, Gemini, Bedrock, Vertex, OpenRouter et autres.
  3. Sinon, FALLBACK_MAX_TOKENS = 8192.

Pour récupérer un modèle nouvellement lancé, régénérez le JSON vendored :

node --experimental-strip-types scripts/sync-litellm-models.ts

Le script récupère le catalogue LiteLLM, filtre les entrées mode: 'chat', projette chacune vers son max_output_tokens (ou fallback max_tokens), puis écrit un snapshot trié. Commitez le litellm-models.json régénéré avec la PR qui motive cette mise à jour.

La table OVERRIDES dans maxTokens.ts est réservée aux rares cas où LiteLLM est absent ou incorrect pour un model id réellement utilisé, par exemple mimo-v2.5-pro. Gardez-la petite ; tout ce que LiteLLM sait déjà correctement doit rester upstream.


Maintenance des localisations

Les PR de locale doivent traduire le chrome UI, la documentation cœur et les métadonnées display-only de galerie dans apps/web/src/i18n/content*.ts, mais ne doivent pas traduire skills/, design-systems/ ni les prompt bodies que les agents exécutent. Ces prompts source sont des entrées de workflow ; garder une langue source commune évite de multiplier la QA de prompts sur toutes les locales. Lorsqu'un Skill, un Design System ou un prompt template est ajouté ou renommé, mettez à jour les métadonnées display de la locale concernée et lancez pnpm --filter @open-design/web test ; content.test.ts échoue si la coverage couverture des métadonnées d'affichage d'une locale déclarée dérive. Les erreurs daemon, noms de fichiers d'export et textes d'artifact générés par agent restent des limites connues, sauf si une PR les inclut explicitement.

Pour les étapes détaillées d'ajout d'une locale (dictionnaire UI, README, language switcher, terminologie régionale), voir TRANSLATIONS.md.


Style de code

Nous ne sommes pas maniaques du formatting (Prettier on save est très bien), mais deux règles ne sont pas négociables parce qu'elles apparaissent dans le prompt stack et l'API visible :

  1. Single quotes en JS/TS. Les strings utilisent des single quotes sauf si l'échappement les rend illisibles. La codebase est déjà cohérente ; suivez-la.
  2. Commentaires en anglais. Même si une PR traduit quelque chose en français, allemand ou chinois, les commentaires de code restent en anglais afin de garder une référence greppable unique.

Au-delà de ça :

  • Ne racontez pas l'évidence. Pas de // import the module, pas de // loop through items. Si le code se lit déjà, le commentaire est du bruit. Gardez les commentaires pour l'intention non évidente ou les contraintes que le code ne peut pas exprimer.
  • TypeScript pour le code source de apps/web/src/ et apps/daemon/src/. Le JavaScript généré appartient aux dossiers dist/; les nouveaux fichiers .js, .mjs ou .cjs doivent avoir une raison générée, vendored ou compatibility explicite.
  • Pas de nouvelle dépendance top-level sans paragraphe dans la description de la PR expliquant ce qu'elle apporte et combien d'octets elle coûte. La liste des dépendances dans package.json est petite volontairement.
  • Lancez pnpm typecheck avant de push. CI le lance aussi ; s'il échoue, vous aurez un commentaire "please fix".

Commits et Pull Requests

  • Un seul sujet par PR. Ajouter un Skill, refactorer le parser et bumper une dépendance : ce sont trois PR.
  • Titre impératif + scope. add dating-web skill, fix daemon SSE backpressure when CLI hangs, docs: clarify .od layout.
  • Le body explique le pourquoi. Le diff montre souvent le quoi ; le pourquoi est rarement évident.
  • Référencez une issue s'il y en a une. S'il n'y en a pas et que la PR est non trivial, ouvrez-en d'abord une pour valider que le changement est souhaité.
  • Pas de squash pendant la review. Poussez des fixups ; les maintainers squashent au merge.
  • Pas de force-push sur une branche partagée sauf si un reviewer le demande.

Nous n'imposons pas de CLA. Apache-2.0 couvre le projet ; votre contribution est licenciée sous la même licence.


Signaler un bug

Ouvrez une issue avec :

  • La commande exacte lancée (pnpm tools-dev ...).
  • La CLI d'agent sélectionnée, ou le fait que vous étiez sur le chemin BYOK.
  • La paire Skill + Design System qui a déclenché le problème.
  • La fin du stderr du daemon concerné. La plupart des rapports "l'artifact n'a jamais rendu" se diagnostiquent en 30 secondes si on voit spawn ENOENT ou l'erreur réelle de la CLI.
  • Une capture d'écran si le problème touche l'UI.

Pour les bugs de prompt stack ("l'agent a généré un hero violet alors que la blacklist slop devait l'interdire"), incluez le message assistant complet afin de voir si la violation vient du modèle ou du prompt.


Poser des questions

  • Question d'architecture, question de design, "bug ou mauvaise utilisation ?" → GitHub Discussions (préféré, car searchable pour la personne suivante).
  • "Comment écrire un Skill qui fait X ?" → ouvrez une discussion. Nous y répondrons et transformerons la réponse en ajout dans docs/skills-protocol.md si c'est un pattern manquant.

Ce que nous n'acceptons pas

Pour garder le projet focalisé, merci de ne pas ouvrir de PR qui :

  • Vendor un runtime de modèle. Tout le pari d'OD est "votre CLI existante suffit". Nous ne livrons pas pi-ai, de clés OpenAI ou de model loaders.
  • Réécrit le frontend hors de la stack actuelle sans discussion préalable. Next.js 16 App Router + React 18 + TS est la ligne. Pas de réécriture Astro, Solid, Svelte ou autre framework sauf si les maintainers veulent explicitement cette migration.
  • Remplace le daemon par une fonction serverless. Le rôle du daemon est de posséder un vrai cwd et de spawn une vraie CLI. Déployer la SPA sur Vercel est très bien ; le daemon reste un daemon.
  • Ajoute de la télémétrie / analytics / phone-home. OD est local-first. Les seuls appels sortants vont vers des providers explicitement configurés par l'utilisateur.
  • Bundle un binaire sans fichier de licence ni attribution d'auteur à côté.

Si vous n'êtes pas sûr que votre idée rentre dans le projet, ouvrez une discussion avant d'écrire le code.


Licence

En contribuant, vous acceptez que votre contribution soit licenciée sous la licence Apache-2.0 de ce repo, à l'exception des fichiers dans skills/guizang-ppt/, qui conservent leur licence MIT originale et l'attribution d'auteur à op7418.