I publish articles on two static sites — proofofboredom.com and vargaskeo.com. Both are bilingual. Both have different HTML templates. Both live in separate GitHub repos. Writing one article used to mean: research, draft in English, translate to French, format for site A, reformat for site B, update the JSON registry, update the sitemap, commit. That's a two-hour job if I'm focused. I'm not always focused. Je publie des articles sur deux sites statiques — proofofboredom.com et vargaskeo.com. Les deux sont bilingues. Les deux ont des gabarits HTML différents. Les deux vivent dans des dépôts GitHub séparés. Écrire un article signifiait : recherche, rédaction en anglais, traduction en français, mise en forme pour le site A, reformatage pour le site B, mise à jour du registre JSON, mise à jour du sitemap, commit. C'est un travail de deux heures quand je suis concentré. Je ne le suis pas toujours.

So I built a pipeline. One slash command: /write-article <topic> <pob|vk|both>. It lives as a single markdown file in .claude/commands/write-article.md. Claude Code reads it, spawns subagents, runs some stages in parallel, stops twice for my input, then commits. No SaaS, no webhooks, no extra API keys. Just Claude Code doing what it was built to do. Alors j'ai construit un pipeline. Une seule commande : /write-article <sujet> <pob|vk|les deux>. Elle vit dans un seul fichier markdown dans .claude/commands/write-article.md. Claude Code le lit, génère des sous-agents, exécute certaines étapes en parallèle, s'arrête deux fois pour ma validation, puis fait le commit. Aucun SaaS, aucun webhook, aucune clé API supplémentaire. Juste Claude Code qui fait ce pour quoi il a été conçu.

The Full Pipeline at a GlanceLe pipeline complet en un coup d'œil

Eight stages. Two human checkpoints. One output: a committed, bilingual, production-ready HTML file. Huit étapes. Deux points de contrôle humains. Un résultat : un fichier HTML bilingue, prêt pour la production, et commité.

Click to zoomCliquer pour zoomer

Stage 1 — Research AgentÉtape 1 — Agent de recherche

The pipeline starts with a subagent that uses WebSearch to scan competitor content and keyword demand for the topic I gave it. It's not doing anything fancy — it reads a few top results, identifies what angles already exist, and figures out what's missing or underdifferentiated. Le pipeline commence par un sous-agent qui utilise WebSearch pour analyser le contenu concurrent et la demande de mots-clés pour le sujet que je lui ai donné. Ce n'est pas sorcier : il lit quelques premiers résultats, identifie les angles déjà couverts, et repère ce qui manque ou ce qui n'est pas suffisamment différencié.

The output is three differentiated article angles. Each one has a title in EN and FR, a summary in EN and FR, a slug, tags for both languages, a provider category (used for the logo system on the sites), and an estimated reading time. The agent writes these as a structured JSON block in the terminal. La sortie est constituée de trois angles d'article différenciés. Chacun possède un titre en anglais et en français, un résumé dans les deux langues, un slug, des tags pour les deux langues, une catégorie de fournisseur (utilisée pour le système de logos sur les sites) et un temps de lecture estimé. L'agent écrit tout ça sous forme de bloc JSON structuré dans le terminal.

Then the pipeline stops. I read the three options and pick one. This is the first human checkpoint — creative control stays with me. The pipeline doesn't continue until I paste my choice back in. Ensuite le pipeline s'arrête. Je lis les trois options et j'en choisis une. C'est le premier point de contrôle humain — le contrôle créatif reste de mon côté. Le pipeline ne continue pas tant que je n'ai pas collé mon choix en retour.

Stages 2 and 3 — Writer and Diagrams, Running in ParallelÉtapes 2 et 3 — Rédacteur et diagrammes, en parallèle

Once I've picked an angle, the pipeline fires two subagents in the same response. Not sequentially — simultaneously. Claude Code's Agent tool supports multiple concurrent calls in a single turn, so I use that. Une fois l'angle choisi, le pipeline lance deux sous-agents dans la même réponse. Pas séquentiellement — simultanément. L'outil Agent de Claude Code supporte plusieurs appels concurrents dans un même tour, alors je l'utilise.

Click to zoomCliquer pour zoomer

The Writer Agent takes the chosen angle — title, summary, tags, provider, reading time — and writes the full bilingual article as a structured content JSON. Not HTML. A sections array where each section has a type (p, h2, h3, ul, ol, callout, code, divider) and both en and fr values. This separation of content from presentation is deliberate — it's what makes the Assembly stage work for two different site templates. L'Agent Rédacteur prend l'angle choisi — titre, résumé, tags, fournisseur, temps de lecture — et écrit l'article bilingue complet sous forme de JSON de contenu structuré. Pas du HTML. Un tableau de sections où chaque section a un type (p, h2, h3, ul, ol, callout, code, divider) et les valeurs en et fr. Cette séparation du contenu et de la présentation est délibérée — c'est ce qui permet à l'étape d'assemblage de fonctionner avec deux gabarits de sites différents.

The Diagram Agent works in parallel on the same angle. It creates two or three inline SVG diagrams. These are not static images — they use CSS variable theming (var(--fg-1), var(--bg-elevated), var(--border), with #22C55E as the named green accent) so they respond to dark and light mode automatically. The output is a diagram JSON array, each entry keyed by a diagram_id that the Writer Agent has already placed as a placeholder in the sections array. L'Agent Diagrammes travaille en parallèle sur le même angle. Il crée deux ou trois diagrammes SVG inline. Ce ne sont pas des images statiques — ils utilisent le thème par variables CSS (var(--fg-1), var(--bg-elevated), var(--border), avec #22C55E comme accent vert nommé) pour répondre automatiquement au mode sombre et clair. La sortie est un tableau JSON de diagrammes, chaque entrée étant identifiée par un diagram_id que l'Agent Rédacteur a déjà placé comme espace réservé dans le tableau de sections.

Running these two agents in parallel cuts roughly 50% of the time compared to running them sequentially. The writer doesn't need the diagrams to write the content. The diagram agent doesn't need the finished prose to build the SVGs. There's no dependency, so there's no reason to wait. Exécuter ces deux agents en parallèle réduit d'environ 50% le temps par rapport à une exécution séquentielle. Le rédacteur n'a pas besoin des diagrammes pour écrire le contenu. L'agent diagrammes n'a pas besoin de la prose terminée pour construire les SVG. Il n'y a aucune dépendance, donc aucune raison d'attendre.

Stage 4 — Assembly AgentÉtape 4 — Agent d'assemblage

The Assembly Agent takes the content JSON from the Writer and the diagram JSON from the Diagrams agent and builds the final HTML file. This is where the target flag (pob, vk, or both) matters. L'Agent d'assemblage prend le JSON de contenu du Rédacteur et le JSON de diagrammes de l'agent Diagrammes et construit le fichier HTML final. C'est ici que le flag cible (pob, vk, ou les deux) est important.

The two sites use different bilingual patterns. On proofofboredom.com, bilingual content uses en-only and fr-only CSS classes on sibling spans. On vargaskeo.com, it uses .en and .fr classes controlled by a root attribute. The Assembly Agent knows both templates and generates the correct HTML structure for whichever target was specified. If the target is both, it writes two files. Les deux sites utilisent des patrons bilingues différents. Sur proofofboredom.com, le contenu bilingue utilise les classes CSS en-only et fr-only sur des éléments frères. Sur vargaskeo.com, il utilise les classes .en et .fr contrôlées par un attribut racine. L'Agent d'assemblage connaît les deux gabarits et génère la structure HTML correcte pour la cible spécifiée. Si la cible est les deux, il écrit deux fichiers.

Diagram placeholders in the sections array get replaced with the actual inline SVG at their designated positions. Lightbox CSS and JS are injected automatically so any diagram can be clicked to zoom. The agent writes the completed file directly to the repository. Les espaces réservés de diagrammes dans le tableau de sections sont remplacés par le SVG inline réel à leurs positions désignées. Le CSS et le JS de la lightbox sont injectés automatiquement pour que tout diagramme puisse être zoomé au clic. L'agent écrit le fichier complété directement dans le dépôt.

Stage 5 — Proofreader AgentÉtape 5 — Agent de relecture

The Proofreader Agent reads the assembled HTML and runs a structured checklist. It's not a style pass — it's a quality gate. The checklist covers: L'Agent de relecture lit le HTML assemblé et exécute une liste de vérification structurée. Ce n'est pas une passe stylistique — c'est une barrière de qualité. La liste couvre :

The agent outputs one of three verdicts: pass, pass_with_notes, or needs_revision. If it's needs_revision, the specific issues are listed and the Assembly Agent reruns with corrections before the pipeline advances. L'agent produit l'un des trois verdicts : pass, pass_with_notes, ou needs_revision. Si c'est needs_revision, les problèmes spécifiques sont listés et l'Agent d'assemblage relance avec des corrections avant que le pipeline n'avance.

Stage 6 — Second Human CheckpointÉtape 6 — Deuxième point de contrôle humain

The pipeline pauses and tells me the file path. I open it in the browser, read it, check the diagrams in both dark and light mode, toggle languages. If something's wrong — tone, structure, a diagram that doesn't look right — I say so and the relevant agent reruns. If it looks good, I type approve and the pipeline moves to commit. Le pipeline s'arrête et m'indique le chemin du fichier. Je l'ouvre dans le navigateur, je le lis, je vérifie les diagrammes en mode sombre et clair, je bascule les langues. Si quelque chose ne va pas — le ton, la structure, un diagramme qui n'a pas l'air correct — je le dis et l'agent concerné relance. Si ça semble bon, je tape approuver et le pipeline passe au commit.

This checkpoint exists because the pipeline can get things technically right and still produce something I don't want to publish. I'm the last quality gate. The automation handles everything up to the point of publication — it doesn't decide what goes live. Ce point de contrôle existe parce que le pipeline peut tout faire correctement sur le plan technique et produire quand même quelque chose que je ne veux pas publier. Je suis la dernière barrière de qualité. L'automatisation gère tout jusqu'au moment de la publication — elle ne décide pas ce qui est mis en ligne.

Stage 7 — Commit AgentÉtape 7 — Agent de commit

Once I approve, the Commit Agent takes over. It knows which site was targeted and handles the bookkeeping accordingly. Une fois que j'approuve, l'Agent de commit prend le relais. Il sait quel site était ciblé et gère les mises à jour nécessaires en conséquence.

For proofofboredom.com: it prepends the new article entry to articles/index.json (newest first is a hard rule on that site), then runs the sitemap generator script before staging files. For vargaskeo.com: it prepends to articles.json at the root. For both: it stages only the relevant files by name — never git add . — writes the commit message with co-authorship attribution, and commits. It does not push. Pushing is always manual. Pour proofofboredom.com : il ajoute la nouvelle entrée d'article en tête de articles/index.json (le plus récent en premier est une règle stricte), puis exécute le script générateur de sitemap avant de stager les fichiers. Pour vargaskeo.com : il ajoute en tête de articles.json à la racine. Pour les deux : il stage uniquement les fichiers pertinents par nom — jamais git add . — écrit le message de commit avec attribution de co-auteur, et commite. Il ne pousse pas. Le push est toujours manuel.

The File That Makes It WorkLe fichier qui fait tout fonctionner

The entire pipeline is one markdown file: .claude/commands/write-article.md. Claude Code custom slash commands are just markdown files in that directory. When you type /write-article, Claude Code reads the file and follows the instructions. The Agent tool calls in the file are what spawn the subagents. Tout le pipeline est un seul fichier markdown : .claude/commands/write-article.md. Les slash commands personnalisées de Claude Code ne sont que des fichiers markdown dans ce répertoire. Quand vous tapez /write-article, Claude Code lit le fichier et suit les instructions. Les appels à l'outil Agent dans le fichier sont ce qui génère les sous-agents.

There's no orchestration server. No Airflow, no n8n, no Make. No webhook infrastructure. No extra billing beyond whatever Claude API calls the session uses. The parallelism is native to Claude Code's multi-agent execution — two Agent tool calls in the same response turn run concurrently. Il n'y a pas de serveur d'orchestration. Pas d'Airflow, pas de n8n, pas de Make. Pas d'infrastructure webhook. Aucune facturation supplémentaire au-delà des appels API Claude que la session utilise. Le parallélisme est natif à l'exécution multi-agents de Claude Code — deux appels à l'outil Agent dans le même tour de réponse s'exécutent simultanément.

The slash command file format is straightforward: markdown with instructions, code blocks for examples, and Agent tool invocations written as instructions to Claude. Claude Code handles the rest — reading the file, parsing the instructions, and executing the pipeline. Le format de fichier de la slash command est simple : du markdown avec des instructions, des blocs de code pour les exemples, et des invocations de l'outil Agent rédigées comme des instructions à Claude. Claude Code gère le reste — lire le fichier, analyser les instructions et exécuter le pipeline.

What I Actually Learned Building ThisCe que j'ai vraiment appris en construisant ça

The parallel execution was the biggest win and also the first thing I got wrong. My initial version ran the Writer and Diagram agents sequentially because I wrote the instructions that way. Once I understood that two Agent tool calls in the same response turn run concurrently, I restructured Stage 2+3 and cut the generation time roughly in half. L'exécution parallèle a été la plus grande victoire et aussi la première chose que j'ai mal faite. Ma version initiale exécutait les agents Rédacteur et Diagrammes séquentiellement parce que j'avais rédigé les instructions ainsi. Une fois que j'ai compris que deux appels à l'outil Agent dans le même tour de réponse s'exécutent simultanément, j'ai restructuré les étapes 2+3 et réduit le temps de génération d'environ la moitié.

The content-first JSON approach (write structured content, then assemble into HTML) solved the dual-site problem cleanly. Before this, I had tried writing HTML directly in the Writer Agent and then transforming it for the second site. That was a mess. Separating content from template eliminated that entirely. L'approche JSON-contenu-d'abord (écrire du contenu structuré, puis assembler en HTML) a résolu proprement le problème dual-site. Avant ça, j'avais essayé d'écrire directement du HTML dans l'Agent Rédacteur puis de le transformer pour le deuxième site. C'était un désastre. Séparer le contenu du gabarit a complètement éliminé ça.

The two human checkpoints felt like overhead at first. They're not. The angle selection checkpoint is where I redirect the pipeline away from angles that are technically valid but not what I want to say. The commit approval checkpoint has caught formatting issues and diagram problems that the Proofreader missed. Both checkpoints pay for themselves. Les deux points de contrôle humains semblaient être une surcharge au départ. Ce n'est pas le cas. Le point de contrôle de sélection d'angle est l'endroit où je redirige le pipeline loin des angles valides mais pas ce que je veux dire. Le point de contrôle d'approbation du commit a attrapé des problèmes de formatage que l'Agent de relecture avait manqués. Les deux points de contrôle se justifient d'eux-mêmes.

What This Doesn't DoCe que ça ne fait pas

It doesn't push to production. That's intentional. The pipeline ends at a committed, unpushed state. I review the diff in GitHub, then push. The CI/CD pipeline handles the rest. Ça ne pousse pas en production. C'est intentionnel. Le pipeline se termine dans un état commité non poussé. Je révise le diff dans GitHub, puis je pousse. Le pipeline CI/CD gère le reste.

It doesn't generate OG images or handle media embeds. Those are manual steps I'll eventually automate. Ça ne génère pas les images OG et ne gère pas les embeds multimédias. Ce sont des étapes manuelles que j'automatiserai éventuellement.

The PointL'essentiel

The pipeline didn't make me a faster writer. It made writing less of a reason to not publish. The friction before was real: two sites, two templates, two languages, two JSON registries, sitemap updates, commit hygiene. Now the overhead is two approval steps and a git push. The rest is automated. Le pipeline ne m'a pas rendu plus rapide en tant que rédacteur. Il a fait de la rédaction une raison de moins de ne pas publier. La friction d'avant était réelle : deux sites, deux gabarits, deux langues, deux registres JSON, mises à jour du sitemap, hygiène des commits. Maintenant la charge se résume à deux étapes d'approbation et un git push. Le reste est automatisé.


← Back to articles ← Retour aux articles