Maintenance du Plugin & Skill Chorus
Comment modifier le plugin Chorus, mettre à jour la documentation des skills, et publier de nouvelles versions. Trois packages de plugin sont maintenus en parallèle — Claude Code, Codex et OpenClaw — plus la surface skill autonome. Soit quatre surfaces skill au total ; quand tu changes le contenu d'un skill, balaye les quatre (voir Skill Content Changes — Four Surfaces).
Structure des fichiers
.claude-plugin/
marketplace.json ← Registre marketplace Claude Code (version ici)
public/chorus-plugin/ ← Package plugin Claude Code
.claude-plugin/
plugin.json ← Métadonnées du plugin (version ici)
hooks.json ← Définitions des hooks (SubagentStart, etc.)
bin/ ← Scripts des hooks (bash) — stateful via API state-get/set
skills/
chorus/SKILL.md ← Skill principal
develop/ idea/ proposal/ quick-dev/ review/ yolo/SKILL.md
agents/ ← Agents reviewers en .md (style Claude Code)
proposal-reviewer.md
task-reviewer.md
plugins/chorus/ ← Package plugin Codex (distinct de Claude Code)
.codex-plugin/
plugin.json ← Métadonnées du plugin (version ici)
hooks.json
hooks/ ← Scripts des hooks (bash) — intentionnellement stateless
on-session-start.sh
on-post-submit-proposal.sh
on-post-submit-for-verify.sh
chorus-mcp-call.sh ← Helper MCP (clientInfo.version en dur)
hook-output.sh
skills/
chorus/SKILL.md ← Port Codex — mentions syntaxe $skill, ~/.codex/config.toml
develop/ idea/ proposal/ quick-dev/ review/ yolo/SKILL.md
chorus-proposal-reviewer/SKILL.md ← Reviewers en tant que skills dans Codex (pas agents/)
chorus-task-reviewer/SKILL.md
packages/openclaw-plugin/ ← Package plugin OpenClaw (runtime TS + skills)
openclaw.plugin.json ← Manifeste du plugin (id, skills dir, activation, configSchema) — PAS de champ version
package.json ← Package npm (version ici; bloc `openclaw`: extensions, runtimeExtensions, install/compat)
src/ ← Runtime TypeScript (index.ts, mcp-client.ts, sse-listener.ts, event-router.ts, wake.ts)
— pont SSE d'événements temps réel + enregistrement MCP ; PAS de hooks bash
dist/ ← JS compilé (npm install charge ceci ; linked install charge src/ via jiti)
skills/
chorus/SKILL.md ← Port OpenClaw — outils namespaced `chorus__<tool>`, détection OpenSpec inline
develop/ idea/ proposal/ quick-dev/ review/ yolo/ brainstorm/ openspec-aware/SKILL.md
proposal-reviewer/SKILL.md ← Reviewers en tant que skills (comme Codex, pas agents/)
task-reviewer/SKILL.md
public/skill/ ← Skill autonome (tout agent compatible MCP)
chorus/SKILL.md ← Même structure, langage plus doux, agnostique à l'IDE
proposal-chorus/SKILL.md
quick-dev-chorus/SKILL.md
Plugin Claude Code vs Codex vs OpenClaw : différences clés
| Aspect | public/chorus-plugin/ (Claude Code) |
plugins/chorus/ (Codex) |
packages/openclaw-plugin/ (OpenClaw) |
|---|---|---|---|
| Invocation du skill | /chorus:develop etc. |
$develop, $yolo (sans namespace) |
/develop etc. |
| Noms des outils | chorus_<tool> |
chorus_<tool> |
chorus__<tool> (préfixe underscore double depuis l'enregistrement du serveur MCP) |
| Config MCP | .mcp.json |
~/.codex/config.toml avec [mcp_servers.chorus.http_headers] |
Config du plugin (chorusUrl + apiKey via configSchema) ; le runtime TS enregistre MCP lui-même |
| Cycle de vie de session | Auto-géré via hooks SubagentStart/Stop | Stateless — l'agent principal gère les sessions manuellement | Manuel — pas de hook SubagentStart ; l'agent principal gère les sessions |
| Reviewers | agents/*.md + spawnés via outil Task |
Skills montés dans agent_type="default" via spawn_agent + items |
Skills proposal-reviewer/ & task-reviewer/, spawnés via sessions_spawn (fallback self-review read-only) |
| Interaction utilisateur | AskUserQuestion (DOIT être utilisée) |
Invite en texte brut | Invite en texte brut — pas de primitive AskUserQuestion |
| Détection OpenSpec | CHORUS_OPENSPEC_ACTIVE précalculé par hook SessionStart |
Précalculé par hook SessionStart | Inline — exécute toi-même les trois-check du §1 à chaque fois (pas de hook SessionStart) |
| « Hooks » | bin/*.sh (bash, stateful) |
hooks/*.sh (bash, stateless) |
Pas de hooks bash — le comportement temps réel est un runtime SSE TypeScript dans src/ (sse-listener.ts, event-router.ts, wake.ts) |
| Exécution de tâche (yolo) | Wave-based Agent Teams (TeamCreate) |
Séquentiel / spawn_agent |
Vagues séquentielles d'agent principal (pas de primitive Agent Teams) |
Lors du portage d'une modification entre plugins, préserve ces différences intentionnelles. N'ajoute pas de fichiers d'état aux plugins Codex/OpenClaw, n'utilise pas le préfixe $ dans les docs Claude Code/OpenClaw, et dans les docs OpenClaw garde la note sur le nom d'outil chorus__ et la formulation « les sessions sont manuelles / la détection est inline / les invites sont en texte brut ».
Quand mettre à jour quoi
« Les trois plugins chorus/SKILL.md » = Claude Code + Codex + OpenClaw. « Les quatre surfaces » incluent en outre le skill autonome public/skill/.
| Change | Fichiers à mettre à jour |
|---|---|
| Nouvel outil MCP ajouté | src/mcp/tools/*.ts (implémentation) + docs/MCP_TOOLS.md + tous les trois fichiers plugin chorus/SKILL.md + skill autonome public/skill/chorus/SKILL.md |
| Description d'outil MCP changée | src/mcp/tools/*.ts uniquement (la doc des skills référence les noms d'outils, pas les descriptions) |
| Contenu/formulation du skill (ex. AC maintenant requis) | Le skill de stage correspondant sur les quatre surfaces (voir Skill Content Changes — Four Surfaces) |
| Nouvelle étape du workflow | Tous les trois plugins stage-specific SKILL.md (ex. develop/, proposal/) + équivalent autonome |
| Nouveau statut Idea/Task | Tous les trois diagrammes du cycle de vie chorus/SKILL.md des plugins + SKILL.md autonome + messages/en.json + messages/zh.json |
| Nouvelle règle d'exécution | Tous les trois chorus/SKILL.md des plugins + règles d'exécution + SKILL.md autonome (formulation plus douce) |
| Changement du modèle de permission | Tous les trois chorus/SKILL.md des plugins + tableaux de permissions + vérification prérequis yolo/SKILL.md + vérification admin-verify quick-dev/SKILL.md + vérifications basées sur les rôles dans les scripts hook Claude Code (les hooks Codex stateless ; OpenClaw n'a pas de hooks bash) |
| Changement de script hook (Claude Code) | public/chorus-plugin/bin/*.sh + hooks.json si nouveau hook. Ne copie jamais aveuglément les changements de hook dans plugins/chorus/hooks/ — les hooks Codex sont intentionnellement stateless et manquent d'événements subagent. OpenClaw n'a pas du tout de hooks bash. |
| Changement de script hook (Codex) | plugins/chorus/hooks/*.sh — rarement nécessaire ; session-start, post-submit-proposal, post-submit-for-verify sont les trois seuls. Si tu bumpes la version du plugin, mets aussi à jour la clientInfo.version en dur dans chorus-mcp-call.sh. |
| Changement du runtime OpenClaw | packages/openclaw-plugin/src/*.ts (runtime SSE/MCP TS) + npm run typecheck + npm run test. Pas de hooks bash — c'est une extension TypeScript compilée. |
| N'importe quel changement de plugin | Bump la version dans chaque fichier pour ce package (voir Version Bump Checklist) |
Checklist Version Bump
Chaque fois que n'importe quel package de plugin change, bump la version dans tous les emplacements de ce package. Il y a deux séquences de version en jeu :
- Séquence frontmatter du skill (actuellement
0.9.x) — partagée par les fichiersSKILL.mddu skill sur les trois plugins. Quand le même contenu du skill est livré à plusieurs plugins, bump-les ensemble. - Séquences du plugin par package — Claude Code + Codex partagent une (
marketplace.json/ les deuxplugin.json, actuellement0.9.x) ; lepackage.jsond'OpenClaw a sa propre séquence (actuellement0.5.x). Ce sont des fichiers indépendants — édite chacun.
Plugin Claude Code — bump ensemble
.claude-plugin/marketplace.json—"version": "X.Y.Z"public/chorus-plugin/.claude-plugin/plugin.json—"version": "X.Y.Z"- Chaque skill sous
public/chorus-plugin/skills/*/SKILL.md—metadata.version: "X.Y.Z"(tous les skills, y comprisquick-dev/, utilisent maintenant le blocmetadata:imbriqué standard)
Plugin Codex — bump ensemble
plugins/chorus/.codex-plugin/plugin.json—"version": "X.Y.Z"- Chaque skill sous
plugins/chorus/skills/*/SKILL.md—metadata.version: "X.Y.Z"(tous les skills, y comprisquick-dev/, utilisent maintenant le blocmetadata:imbriqué standard). N'oublie pas les deux reviewer skills :chorus-proposal-reviewer/SKILL.mdetchorus-task-reviewer/SKILL.md. plugins/chorus/hooks/chorus-mcp-call.sh— chaîneclientInfo.versionen dur dans la payload JSON-RPCinitialize
Plugin OpenClaw — bump ensemble
packages/openclaw-plugin/package.json—"version": "X.Y.Z"utilisant la propre séquence d'OpenClaw (0.5.x), PAS la séquence du skill.openclaw.plugin.jsonn'a pas de champ version — rien à éditer là.- Chaque skill sous
packages/openclaw-plugin/skills/*/SKILL.md—metadata.version: "X.Y.Z"sur la séquence du skill (0.9.x, correspondant aux skills des autres plugins). Inclut les deux reviewer skillsproposal-reviewer/SKILL.mdettask-reviewer/SKILL.md.- Ne touche PAS à la
clientInfo.version(0.1.0) danssrc/mcp-client.ts— c'est un identifiant client MCP statique, pas la version du plugin.
- Ne touche PAS à la
Skills autonomes — versioning indépendant
public/skill/*/SKILL.md— bump uniquement les skills autonomes qui ont changé, utilisant leur propre séquence de version (0.3.x; ne synchronise PAS avec la version du plugin)
Manière rapide de vérifier toutes les versions :
grep -rn '"version"\|^ version:\|^version:' \
.claude-plugin/marketplace.json \
public/chorus-plugin/.claude-plugin/plugin.json \
public/chorus-plugin/skills/*/SKILL.md \
plugins/chorus/.codex-plugin/plugin.json \
plugins/chorus/skills/*/SKILL.md \
plugins/chorus/hooks/chorus-mcp-call.sh \
packages/openclaw-plugin/package.json \
packages/openclaw-plugin/skills/*/SKILL.md \
public/skill/*/SKILL.md
Les utilisateurs font la mise à jour via :
/plugin update chorus@chorus-plugins # Claude Code
codex plugin update chorus@chorus-plugins # Codex
# OpenClaw : réinstalle/met à jour via le plugin manager OpenClaw (spec npm @chorus-aidlc/chorus-openclaw-plugin)
Skill Content Changes — Four Surfaces
Le contenu du skill Chorus (étapes du workflow, guidance des outils, formulation comme « AC est requis ») vit sur quatre surfaces parallèles. Un changement de contenu doit balayer les quatre — en manquer une livre des docs incohérentes, et le skill proposal Codex/OpenClaw a historiquement porté un exemple legacy qu'un changement de comportement peut casser silencieusement (ex. l'ancien exemple de draft Markdown acceptanceCriteria, qui échoue maintenant la vérification AC obligatoire et DOIT devenir un array structuré acceptanceCriteriaItems).
public/chorus-plugin/skills/<skill>/SKILL.md— Claude Codeplugins/chorus/skills/<skill>/SKILL.md— Codexpackages/openclaw-plugin/skills/<skill>/SKILL.md— OpenClawpublic/skill/<skill>-chorus/SKILL.md— autonome (note le suffixe-choruset l'ensemble plus plat)
Commande de balayage — trouve chaque occurrence avant d'éditer pour que rien ne soit oublié :
grep -rniE "<your-search-term>" \
public/chorus-plugin/skills/ plugins/chorus/skills/ \
packages/openclaw-plugin/skills/ public/skill/
Puis bump les séquences de version pertinentes (frontmatter du skill 0.9.x sur plugins 1–3 ; 0.3.x autonome pour #4 ; versions du plugin par package au besoin).
Porter des changements entre les plugins
Chaque fois que tu changes du contenu dans un plugin, miroir-le dans les deux autres sauf si la différence est intentionnelle (voir le tableau des différences ci-dessus). Workflow typique :
- Fais le changement dans
public/chorus-plugin/skills/<skill>/SKILL.md - Diff-check les contreparties :
diff public/chorus-plugin/skills/<skill>/SKILL.md plugins/chorus/skills/<skill>/SKILL.mddiff public/chorus-plugin/skills/<skill>/SKILL.md packages/openclaw-plugin/skills/<skill>/SKILL.md
- Applique le même changement de contenu aux copies Codex et OpenClaw, mais préserve leur formulation intentionnelle :
- Codex :
.mcp.json→~/.codex/config.toml,Task tool→spawn_agent,/chorus:X→$X, « sessions auto-managed » → « sessions optionnelles / port stateless » - OpenClaw : noms d'outils
chorus_<tool>→chorus__<tool>,AskUserQuestion→ invite en texte brut, reviewers viasessions_spawn, détection OpenSpec inline (pas de hook SessionStart), sessions manuelles
- Codex :
- Bump les versions de tous les plugins affectés (tous les fichiers du Version Bump Checklist)
- Pour le plugin Codex, vérifie aussi que
clientInfo.versiondanschorus-mcp-call.shcorrespond
Différences de ton : Plugin vs Skill autonome
Le skill du plugin cible Claude Code spécifiquement. Le skill autonome cible tout agent compatible MCP (Cursor, Kiro, etc.).
| Aspect | Plugin (public/chorus-plugin/skills/) |
Autonome (public/skill/) |
|---|---|---|
| AskUserQuestion | « TOUJOURS utiliser... NE JAMAIS afficher comme texte » | « préfère l'invite interactive de ton IDE si disponible » |
| Gestion de session | « Ne CRÉE PAS les sessions — le plugin s'en charge » | « Crée ou rouvre une session avant de commencer le travail » |
| Skip elaboration | « tu DOIS demander la permission à l'utilisateur d'abord » | « confirme avec l'utilisateur d'abord » |
| Références de hooks | Références des hooks spécifiques (SubagentStart, etc.) | Pas de références de hooks |
Règle de base : La version plugin utilise MUST/NEVER/ALWAYS. La version autonome utilise « prefer », « confirm », « consider ».
Ajouter un nouvel outil MCP — Checklist complète
- Implémente dans
src/mcp/tools/*.ts(pm.ts, public.ts, etc.) - Ajoute à
docs/MCP_TOOLS.md - Mets à jour les tableaux de permissions et listes d'outils dans tous les quatre
chorus/SKILL.md:public/chorus-plugin/skills/chorus/SKILL.mdplugins/chorus/skills/chorus/SKILL.mdpackages/openclaw-plugin/skills/chorus/SKILL.md(utilise la forme namespacedchorus__<tool>)public/skill/chorus/SKILL.md
- S'il change un workflow de stage, mets à jour le skill de stage correspondant sur les quatre emplacements (
develop/,idea/,proposal/,quick-dev/,review/,yolo/) - Bump les versions de tous les plugins affectés (voir Version Bump Checklist)
- Lance
npx tsc --noEmitpour vérifier
Modifier les scripts hook
Hooks du plugin Claude Code (public/chorus-plugin/bin/)
on-session-start.sh— Hook SessionStart (met en cacheagent_permissionsvia"$API" state-set)on-user-prompt.sh— Hook UserPromptSubmiton-subagent-start.sh— Hook SubagentStarton-subagent-stop.sh— Hook SubagentStop (litagent_permissionsviastate-get)on-teammate-idle.sh— Hook TeammateIdleon-pre-enter-plan.sh,on-pre-exit-plan.sh— Hooks du mode Planon-task-completed.sh— Hook TaskCompletedon-post-submit-proposal.sh,on-post-submit-for-verify.sh— Rappels reviewer PostToolUse
Hooks du plugin Codex (plugins/chorus/hooks/)
on-session-start.sh— Hook SessionStart (stateless ; pas de mise en cache)on-post-submit-proposal.sh— PostToolUse pourchorus_pm_submit_proposalon-post-submit-for-verify.sh— PostToolUse pourchorus_submit_for_verifychorus-mcp-call.sh— Helper MCP-over-HTTP partagé (bumpclientInfo.versionau release)hook-output.sh— Helper de formatage stdout
Codex n'a pas d'événements SubagentStart/Stop — n'essaie pas de porter les hooks du cycle de vie du plugin Claude Code. À la place, la gestion de session est documentée comme une responsabilité de l'agent principal dans plugins/chorus/skills/develop/SKILL.md et $yolo.
Plugin OpenClaw — Runtime TypeScript, pas de hooks bash (packages/openclaw-plugin/src/)
OpenClaw n'a pas du tout de hooks bash. Son comportement temps réel est une extension TypeScript compilée déclarée dans le bloc openclaw du package.json (extensions: ["./src/index.ts"], runtimeExtensions: ["./dist/index.js"]) :
index.ts— point d'entrée / activation (activation.onStartupdansopenclaw.plugin.json)mcp-client.ts,mcp-registration.ts— enregistre les outils Chorus MCP (namespacedchorus__<tool>)sse-listener.ts,event-router.ts,wake.ts— flux d'événements SSE → wake agent (l'analogue OpenClaw des hooks de notification des autres plugins)config.ts,commands.ts— gestion du schéma de config et slash commands
Après modification du runtime : cd packages/openclaw-plugin && npm run typecheck && npm run test. Une install linked charge src/ directement via jiti ; une install npm requiert la compilation dist/ (npm run build). Les règles Bash 3.2 ne s'appliquent pas ici (c'est TypeScript, pas du shell). Deux gotchas runtime connus : une install linked charge le TS via jiti (pas de dist) tandis qu'une install npm a besoin de dist compilé + runtimeExtensions ; et SSE→agent wake requiert activation.onStartup + runEmbeddedAgent avec un provider/model explicite.
CRITIQUE : Tous les scripts hook DOIVENT être compatibles avec Bash 3.2. macOS embarque /bin/bash 3.2 (à cause du licensing GPL) et Claude Code + Codex l'utilisent tous les deux pour exécuter les hooks. N'UTILISE PAS les features Bash 4+ :
| Bash 4+ (INTERDIT) | Alternative Bash 3.2 |
|---|---|
${VAR,,} (minuscule) |
$(printf '%s' "$VAR" \| tr '[:upper:]' '[:lower:]') |
${VAR^^} (majuscule) |
$(printf '%s' "$VAR" \| tr '[:lower:]' '[:upper:]') |
declare -A (tableaux associatifs) |
Utilise des variables séparées ou jq |
readarray / mapfile |
Boucle while IFS= read -r line |
\|& (pipe stderr) |
2>&1 \| |
&>> (append both) |
>> file 2>&1 |
Après modification :
- Lance
/bin/bash public/chorus-plugin/bin/test-syntax.shsur macOS pour vérifier la compatibilité Bash 3.2 (hooks Claude Code + Codex uniquement — OpenClaw n'a pas de hooks bash) - Teste localement :
claude --plugin-dir public/chorus-plugin(Claude Code) ou installe le plugin viacodex plugin installet recharge (Codex) - Bump la version du plugin pour les packages qui ont changé (tous les packages affectés)
- Les utilisateurs doivent redémarrer Claude Code / Codex et lancer la commande de mise à jour du plugin
Tester les changements du plugin
# Claude Code — charge le plugin localement (pas d'install nécessaire)
claude --plugin-dir public/chorus-plugin
# Ou mets à jour le plugin installé
/plugin update chorus@chorus-plugins
# Vérifie que le plugin est chargé
/plugin list
# OpenClaw — typecheck + teste le runtime TypeScript
cd packages/openclaw-plugin && npm run typecheck && npm run test