Plan Canvas
Boucle de révision pour les plans et artefacts visuels : vous écrivez l'artefact, l'humain le révise dans le navigateur — annotant l'élément exact qu'il vise, discutant et rendant un verdict Approuver le plan / Demander des modifications — pendant que vous vous bloquez sur un seul appel CLI qui renvoie leur feedback sous forme de JSON.
Inspiré par lavish-axi ; reconstruit nativement pour ECC autour de la porte de confirmation /plan, avec zéro dépendance.
Quand l'utiliser
- Vous venez d'écrire un artefact de plan (
.claude/plans/*.plan.mddepuis/plan) et avez besoin de la décision CONFIRMER/approuver — le verdict du canvas remplace un « oui/continuer » tapé. - L'utilisateur doit pointer ce qui doit changer : révision de designs, comparaisons, rapports, ou tout artefact
.md/.htmllocal. - L'utilisateur demande
/plan-canvas, une révision visuelle, ou « ouvre-le dans le navigateur ».
À NE PAS utiliser pour : la révision de code de diffs (/code-review), les applications web en cours d'exécution, ou les URL distantes. Le canvas ne sert que les fichiers d'artefacts locaux.
Comment ça fonctionne
Invoquez le CLI sous ecc-plan-canvas — le binaire fourni par le package ecc-universal (sur le PATH après une installation globale/plugin ; node "$CLAUDE_PLUGIN_ROOT/scripts/plan-canvas.js" fonctionne aussi pour les installations plugin). Exécutez-le depuis le projet que vous révisez ; il fonctionne depuis n'importe quel répertoire de travail. Il gère un serveur loopback détaché (127.0.0.1:4517) partagé par toutes les sessions, indexé par chemin d'artefact — pas d'ID de session à suivre.
Le flux de travail est une simple boucle CLI-plus-JSON, donc il est agnostique du modèle et du harnais : tout agent capable d'exécuter une commande shell et de lire stdout l'utilise de la même manière (Claude Code, Codex, Cursor, Gemini, OpenCode, Copilot). Déclenchez-le selon la manière dont votre harnais expose les compétences — par ex. /plan-canvas dans Claude Code, $plan-canvas dans Codex — ou exécutez directement les commandes ecc-plan-canvas.
# 1. Ouvrir l'artefact dans le navigateur de l'utilisateur (retourne immédiatement)
ecc-plan-canvas open .claude/plans/feature.plan.md
# 2. Bloquer jusqu'à ce que l'humain réponde. Laissez-le tourner ; réexécutez s'il est interrompu :
# le feedback en file d'attente n'est jamais perdu.
ecc-plan-canvas await .claude/plans/feature.plan.md
Restez à l'écoute, ou l'humain parle à une chaise vide
Le feedback ne vous parvient que tant qu'un await est effectivement en écoute sur la session. Si votre tour se termine sans rien en écoute, le message reste dans la file et, du côté de l'humain, l'envoi semble ne rien faire.
Exécutez donc await comme une tâche d'arrière-plan lorsque votre harnais le supporte (dans Claude Code, un appel Bash avec run_in_background: true). Il se termine dès que le feedback arrive et le harnais vous remet le JSON, ce qui maintient la boucle active entre les tours au lieu de mourir avec l'appel au premier plan. Un await au premier plan fonctionne aussi, mais seulement jusqu'à ce que le harnais le limite dans le temps.
Deux filets de sécurité existent, et aucun n'est une excuse pour ignorer ce qui précède :
ecc-plan-canvas pendingliste le feedback en file d'attente sans écouteur. Vérifiez-le chaque fois que vous n'êtes pas sûr d'avoir manqué quelque chose.- Le crochet
stop:plan-canvas-pendingbloque la fin de votre tour tant que le feedback du canvas n'est pas livré, et vous remet les messages. Si vous lisez le feedback depuis ce crochet, c'est que vous avez arrêté d'écouter trop tôt.
await imprime du JSON lorsque l'humain agit :
{
"status": "feedback",
"items": [
{ "kind": "annotation", "text": "Divise ceci en deux phases",
"anchor": { "selector": "h2:nth-of-type(3)", "tag": "h2", "snippet": "Phase 2 : Migration" } },
{ "kind": "verdict", "verdict": "request-changes" }
]
}
kind: "chat"— message libre ; répondez dans le canvas, pas dans le terminal.kind: "annotation"— feedback ancré à un élément (anchor.selector,anchor.snippetmontre ce qu'ils ont pointé ;anchor.textRange.textlorsqu'ils ont surligné un passage).kind: "verdict"—approvesignifie que le plan est CONFIRMÉ : arrêtez de scruter, mettez fin à la session et commencez l'implémentation.request-changessignifie révisez l'artefact (le canvas le recharge en direct) et continuez la boucle.
3. Répondez toujours dans le canvas, puis continuez à écouter. Une commande fait les deux :
ecc-plan-canvas await <file> --reply "Phase 2 divisée comme demandé. Jetez un œil."
Chaque message humain reçoit une réponse dans le canvas, même un simple comme « J'y travaille, je réécris le tableau des risques maintenant. » Le silence dans le panneau de chat est impossible à distinguer d'un canvas cassé, ce qui est exactement l'échec que cette boucle existe pour prévenir. Répondez là, pas seulement dans le terminal.
Pendant que vous travaillez, maintenez l'honnêteté du chat avec l'indicateur d'activité :
# bulle animée "l'agent réfléchit..." ; rafraîchissez-la pendant un long travail
ecc-plan-canvas typing <file> --state thinking
# passez à "l'agent tape..." juste avant qu'une réponse n'arrive
ecc-plan-canvas typing <file> --state typing
await définit thinking pour vous au moment où il vous remet un lot, et --reply l'efface. Les deux états s'auto-expirent, donc un agent crashé se dégrade en un honnête « en file d'attente » au lieu de laisser l'humain regarder des points indéfiniment. Rafraîchissez thinking si une révision prend plus d'une minute.
4. Terminez lorsque la révision est conclue : ecc-plan-canvas end <file>.
Diagrammes (Mermaid)
Lorsqu'une partie du plan est un flux, une architecture, une séquence, une machine d'état, un modèle ER ou un graphe de dépendances, rédigez-la comme un bloc ```mermaid au lieu d'art ASCII ou d'un mur de prose — le canvas la rend comme un diagramme thématique que l'humain peut pointer. Utilisez-le quand une image se lit plus vite qu'un paragraphe ; évitez-le pour les listes ou tableaux simples.
```mermaid
flowchart LR
A[Marché se résout] --> B{Observateurs ?}
B -->|oui| C[File d'attente des travaux] --> D[Worker en étoile]
```
Les diagrammes sont rendus dans le thème sombre ECC avec la palette d'accentuation. Mermaid se charge dans le navigateur depuis un CDN épinglé ; s'il est indisponible (hors ligne), le bloc se dégrade en affichant son code source, donc la révision n'est jamais bloquée. Pointez un miroir local vers ECC_PLAN_CANVAS_MERMAID_URL pour une utilisation hors réseau.
Règles
- Les artefacts Markdown sont rendus dans le modèle de plan ECC (y compris les blocs Mermaid) ; les artefacts
.htmlsont rendus tels quels avec la couche d'annotation injectée. Pour les conseils de création HTML, utilisez les compétencesfrontend-design-directionetartifact-design. - Modifiez le fichier d'artefact pour réviser — le canvas se recharge en direct lors de la sauvegarde. Ne réexécutez jamais
openpour rafraîchir. {"status": "ended", "endedBy": "user"}(ousessionEnded: truesur un lot de feedback) signifie que l'utilisateur a fermé la révision : arrêtez de scruter, délivrez les mises à jour restantes dans le chat et ne rouvrez pas. Un simpleopensur cette session est refusé ; passez--reopenuniquement lorsque l'utilisateur demande de reprendre.- Les ressources associées (images, CSS) doivent se trouver à côté de l'artefact et être référencées par chemin relatif.
- Le serveur est en boucle locale uniquement et se termine après 30 minutes d'inactivité (
ECC_PLAN_CANVAS_IDLE_MS) ;stopl'arrête explicitement. L'état réside dans~/.claude/plan-canvas/(ECC_PLAN_CANVAS_STATE_DIR).
Exemples
Flux d'approbation de plan — /plan écrit .claude/plans/notifications.plan.md et doit ATTENDRE la confirmation :
ecc-plan-canvas open .claude/plans/notifications.plan.md
ecc-plan-canvas await .claude/plans/notifications.plan.md
# → {"status":"feedback","items":[{"kind":"verdict","verdict":"approve"}]}
ecc-plan-canvas end .claude/plans/notifications.plan.md
# plan confirmé — commencer l'implémentation
Boucle de révision — le feedback arrive, vous modifiez le fichier, répondez, continuez à écouter :
# await a renvoyé des annotations → modifier le .plan.md (le canvas se recharge en direct)
ecc-plan-canvas await <file> --reply "Tableau des risques retravaillé."
# → se bloque à nouveau jusqu'à la prochaine réponse
Anti-patrons
- Scruter avec
--timeout-msdans une boucle. Cela existe pour les tests. Laissez plutôt leawaitsimple tourner. - Terminer votre tour sans qu'aucun
awaitn'écoute alors que la révision est encore ouverte. C'est le seul échec que l'humain vit comme « j'ai envoyé un message et rien ne s'est passé ». - Lire le feedback mais répondre uniquement dans le terminal. L'humain regarde le canvas.
- Rouvrir après une fin initiée par l'utilisateur « juste pour montrer » quelque chose.
- Coller tout le plan dans le chat et ouvrir un canvas — choisissez le canvas et limitez le résumé du terminal à une ligne.
- Analyser le chat du canvas depuis les fichiers d'état — tout ce dont vous avez besoin arrive via
await.
Notes de conception et origine : docs/design/plan-canvas.md.