option

plan-orchestrate

affaan-m/ECC affaan-m/ECC

Lit un document de plan, le décompose en étapes, conçoit une chaîne d'agents pour chaque étape à partir du catalogue ECC, puis génère des invites personnalisées prêtes à être collées ou orchestrées, sans les exécuter.

...Développer tout
9
Heure mise à jour 4 octobre 2026

Planifier et orchestrer

Reliez un document de plan à /orchestrate custom en générant une instruction prête à coller par étape. Cette compétence est uniquement générative : elle n’exécute jamais /orchestrate. L’utilisateur colle chaque ligne lorsqu’il est prêt.

Quand l’activer

  • L’utilisateur dispose d’un document de plan en plusieurs étapes (PRD, RFC, plan de mise en œuvre) et souhaite le faire passer par /orchestrate.
  • L’utilisateur dit « orchestre ce plan », « donne-moi des invites d’orchestration pour chaque étape », « compose des chaînes pour ce plan ».
  • Un plan étape par étape existe, mais l’utilisateur ne souhaite pas sélectionner manuellement les agents pour chaque étape.

À ignorer lorsque :

  • La tâche se résume à une seule étape ponctuelle → appeler directement /orchestrate custom.
  • Le plan est illisible ou vide. L’absence de numérotation explicite ne constitue pas à elle seule une condition d’exclusion — voir le cas particulier « Pas d’étapes claires » ci-dessous.

Entrées

 [--lang=python|typescript|go|rust|cpp|java|kotlin|flutter|auto] [--scope=all|step:|range:-] [--dry-run]
  • — obligatoire ; chemin relatif ou absolu (@docs/... accepté).
  • --lang — variante de langue du réviseur ; valeur par défaut : auto (détectée à partir du projet).
  • --scope — limite les étapes générées ; valeur par défaut : all.
  • --dry-run — affiche uniquement la décomposition et la justification de la chaîne ; n'affiche pas les invites finales.

Forme standard /orchestrate (ne pas s'en écarter)

{ORCH_CMD} custom ",,...," ""

Où {ORCH_CMD} est déterminé lors de la phase 0 (voir ci-dessous). La chaîne de commande dans la sortie émise utilise toujours une forme concrète — jamais les deux, jamais un espace réservé.

  • « custom » est une chaîne séquentielle ; le HANDOFF de chaque agent alimente le suivant.
  • Liste d’agents séparés par des virgules. De préférence sans espaces ; un seul espace est toléré.
  • Il n’existe aucun indicateur --mode / --gate / --agents=... — ne les inventez jamais.
  • Les noms d’agents proviennent du catalogue de cette compétence. Les guillemets doubles intégrés dans la description de la tâche sont échappés sous la forme \".

Formulaire d’installation ECC et espacement des noms

Deux formes d’installation déterminent le préfixe à la fois de la commande « / » et de chaque nom d’agent. Les deux DOIVENT rester synchronisées — une forme par sortie, jamais mélangées :

Soit désigne le répertoire personnel de Claude Code : ~/.claude sous macOS/Linux, %USERPROFILE%\.claude sous Windows. Résolvez-le de la manière dont la plateforme hôte résout le répertoire personnel de l’utilisateur (ne codez pas en dur ~).

Formulaire Détection {ORCH_CMD} Format du nom de l'agent
Installation du plugin (1.9.0+) /plugins/marketplaces/everything-claude-code/ existe /everything-claude-code:orchestrate everything-claude-code:
Installation de base héritée Éléments ci-dessus absents ; fichiers de l'agent sous /agents/ /orchestrate

Pourquoi est-ce important ? : avec l’installation via le plugin, les agents s’enregistrent sous le nom « everything-claude-code:tdd-guide ». Les noms « nus » forcent une correspondance approximative, ce qui échoue de manière intermittente lors d’appels parallèles. Avec l’installation héritée, les formes préfixées ne sont pas enregistrées et échouent purement et simplement.

Catalogue d'agents disponibles (vous devez choisir parmi ceux-ci)

Général :

  • planner — reformulation des exigences, décomposition des risques, planification des étapes
  • architect — architecture, conception du système, propositions de refactorisation
  • tdd-guide — rédaction de tests → implémentation → couverture ≥ 80 %
  • code-reviewer — revue de code générique
  • réviseur de sécurité — audit de sécurité, OWASP, fuites de données confidentielles
  • nettoyeur de refactorisation — code mort, doublons, nettoyage des classes Knip
  • mise-à-jour de la documentation — documentation, carte de code, README
  • docs-lookup — recherche d’API de bibliothèques tierces (Context7)
  • e2e-runner — orchestration des tests de bout en bout
  • database-reviewer — schéma PostgreSQL, migration, performances
  • harness-optimizer — configuration du harnais d’agents locaux
  • loop-operator — boucles autonomes de longue durée
  • chief-of-staff — triage multicanal (rarement adapté aux étapes d’un plan)

Résolution des erreurs de compilation :

  • build-error-resolver (générique) / cpp-build-resolver / go-build-resolver / java-build-resolver / kotlin-build-resolver / rust-build-resolver / pytorch-build-resolver

Réviseurs de code :

  • python-reviewer / typescript-reviewer / go-reviewer / rust-reviewer / cpp-reviewer / java-reviewer / kotlin-reviewer / flutter-reviewer

Un nom d’agent mal orthographié entraîne l’échec de /orchestrate. Vérifiez cette liste avant de l’envoyer.

Fonctionnement

Phase 0 — Détection du mode ECC et du langage

  1. Lire . Si elle est manquante ou vide, signalez-le et arrêtez-vous.

  2. Détecter une seule fois le formulaire d’installation ECC et le figer dans ECC_MODE. Algorithme (à exécuter dans l’ordre, s’arrêter à la première correspondance) :

    1. Si /plugins/marketplaces/everything-claude-code/ existe → ECC_MODE = plugin.
    2. Sinon, si /agents/ existe et contient au moins un fichier d’agent ECC (par ex. tdd-guide.md, code-reviewer.md) → ECC_MODE=legacy.
    3. Sinon → valeur par défaut ECC_MODE=legacy et affichage d’un avertissement d’une ligne en haut de la sortie : > Avertissement : impossible de détecter l’installation ECC ; passage par défaut au mode legacy. Si vous utilisez l’installation par plugin, modifiez les préfixes manuellement.
    4. Si les deux marqueurs existent (installation mixte), le plugin prévaut : l’espace de noms du plugin est le seul à résoudre les noms d’agents sans correspondance approximative.

    À partir de ce moment, chaque ligne générée utilise le préfixe correspondant à la fois pour la commande « / » et pour chaque nom d’agent. Ne générez jamais les deux formes dans la même sortie.

  3. Résolution de --lang. En mode « auto », effectuez une détection tenant compte du polyglottisme :

    • Marqueurs de détection : pyproject.toml / uv.lock / requirements.txt → python ; package.json → typescript ; go.mod → go ; Cargo.toml → rust ; CMakeLists.txt ou *.cpp de niveau supérieur → cpp ; pom.xml / build.gradle (Java) → java ; build.gradle.kts ou Kotlin de niveau supérieur → kotlin ; pubspec.yaml → flutter.
    • Critère de départage en cas de polyglottisme: si plusieurs marqueurs correspondent, choisissez le langage dont les fichiers source sont les plus nombreux (comptez-les via `git ls-files`, en excluant les répertoires `vendor/`, `node_modules/`, `dist/`, `build/`, `.venv/`, les fichiers générés et les fixtures de test évidentes). En cas d’égalité ou si aucun langage ne représente plus de 60 % des fichiers source, définissez lang=unknown.
    • Aucun marqueur ne correspond → définissez lang=unknown.
    • lang=unknown est une sentinelle — ce n’ est pas un nom d’agent. Les règles 4 et 5 de la phase 2 le transforment en « code-reviewer » / « build-error-resolver » au moment de la composition de la chaîne.
  4. Détecter un sous-profil PyTorch: lorsque lang=python et que l’un des fichiers pyproject.toml / requirements.txt / uv.lock déclare une dépendance à torch, définissez pytorch=true. Cela n’affecte que la sélection de la chaîne de construction (règle de la phase 2 ci-dessous) ; le réviseur reste python-reviewer.

  5. Normaliser tous les noms d’agents déclarés dans le plan: si le texte du plan fait référence à des agents sous leur forme préfixée par le plugin (par exemple everything-claude-code:tdd-guide), supprimer le préfixe pour obtenir le nom de catalogue nu avant de valider ou de composer les chaînes. La ré-ajout du préfixe n’a lieu qu’au moment de la sortie, selon ECC_MODE (phase 4). Ne laissez jamais un nom pré-préfixé entrer dans la composition de la chaîne — cela entraînerait un double préfixe en mode plugin.

Phase 1 — Décomposer les étapes

Identifiez les « unités d’étape » par ordre de priorité :

  1. Numérotation explicite : ## Étape N / ### Phase N / ## N. … / liste ordonnée de niveau supérieur.
  2. Une colonne « Étape » dans un tableau.
  3. ----blocs séparés par des en-têtes commençant par un verbe.
  4. Sinon, considérer chaque H2 comme une étape.

Pour chaque étape, extraire l’identifiant (à partir de 1), le titre (≤ 80 caractères), l’intention (1 à 3 phrases) et les balises.

Phase 2 — Chaîne de balisage et de sélection

Baliser par intention (balises multiples autorisées ; chaîne constituée d’une balise principale + de balises secondaires empilées) :

Les mots-clés ci-dessous sont mis en correspondance sans distinction de majuscules/minuscules. Les plans multilingues sont pris en charge en faisant correspondre les racines des mots dans n’importe quelle langue, à condition que le sens corresponde aux mots-clés anglais répertoriés.

Balise Mots-clés Chaîne par défaut
conception architecture, conception, choisir, évaluer, RFC planificateur, architecte
plan plan, ventilation, jalon planificateur
impl mettre en œuvre, développer, ajouter, créer, porter guide TDD,-réviseur
test test, couverture, e2e, intégration tdd-guide, e2e-runner
refactoriser refactorisation, nettoyage, déduplication, fractionnement architecte, refactor-cleaner,-reviewer
migration migration, mise à niveau, réécriture, portage architecte, guide TDD,- réviseur
base de données schéma, migration, index, SQL, Postgres, Alembic, SQLModel réviseur de bases de données,-réviseur
sécurité chiffrement, authentification, secret, OWASP, données à caractère personnel évaluateur de sécurité,-évaluateur
construction construction, compilation, échec de lint, CI -résolveur-de-construction (replie sur le résolveur-d'erreurs-de-construction)
docs documentation, fichier README, carte de code, journal des modifications mise à jour de la documentation
recherche recherche, référence, utilisation de l'API recherche-dans-la-documentation
révision révision, audit, vérification -réviseur, réviseur de code
boucle boucle, autonome, chien de garde opérateur de boucle

Règles de composition des chaînes :

  1. Sélection de la balise principale: lorsqu’une étape correspond à plusieurs balises, la première dans l’ordre du tableau (en haut du tableau = priorité la plus élevée) est la balise principale ; les autres sont secondaires. Les règles de composition 2 et 3 ci-dessous traitent explicitement certaines combinaisons spécifiques de balises ; sinon, ajoutez les chaînes secondaires dans l’ordre du tableau des balises.
  2. impl + security → tdd-guide,-reviewer,security-reviewer.
  3. impl + db → tdd-guide,database-reviewer,-reviewer.
  4. Dédupliquez la chaîne résultante (en conservant la première occurrence). Par exemple, « review + lang=unknown » donnerait « code-reviewer,code-reviewer » après application de la règle 5 ; la déduplication ramène le résultat à « code-reviewer ».
  5. -reviewer se résout en code-reviewer lorsque lang=unknown.
  6. -build-resolver se résout en build-error-resolver lorsque lang=unknown. Cas particulier: si la phase 0 a défini pytorch=true, utilisez pytorch-build-resolver pour les chaînes de compilation, quel que soit . Il n’existe pas de python-build-resolver; --lang=python sans pytorch=true est résolu en build-error-resolver.
  7. Étapes sans balise: si aucun mot déclencheur ne correspond, définir la chaîne sur « code-reviewer » et indiquer « aucune balise correspond » ; chaîne par défaut « review-only » sous « Justification de la chaîne ».
  8. Longueur de la chaîne ≤ 4 après déduplication. En cas de dépassement, supprimer le tag le plus faible (recherche et documentation en premier).
  9. Ne pas associer « planner » et « architect » dans une chaîne « impl » (gaspillage de jetons). Ne les associer que lors des étapes de conception.
  10. Les étapes marquées « impl », « refactor » ou « migration » se terminent par un agent de classe « reviewer » — l’un des suivants : « -reviewer », « code-reviewer », « security-reviewer » ou « database-reviewer ». Le réviseur le plus spécialisé dans le domaine occupe la dernière position (par exemple, la combinaison « impl+security » de la règle 2 se termine par « security-reviewer »; la combinaison « impl+db » de la règle 3 se termine par « -reviewer » car « database-reviewer » contrôle déjà la migration plus tôt dans la chaîne). Les étapes de test et de compilation sont contrôlées par leurs propres validateurs (respectivement «e2e-runner » et le « build resolver ») et ne nécessitent pas de réviseur supplémentaire.

Phase 3 — Compression de la description de la tâche

Chaque doit :

  • Être autonome (le premier agent n’a pas besoin que le document de plan soit ouvert).
  • Commencer par [Plan : #step-].
  • inclure 1 à 3 critères d’acceptation vérifiables.
  • Inclure une clause de délimitation du champ d’application (Hors champ d’application : ...) uniquement si le plan en déclare une pour cette étape. La reprendre mot pour mot. Si le plan ne comporte aucune déclaration de hors champ d’application, omettre entièrement la clause — n’en inventer aucune.
  • Longueur : 200 à 600 caractères ; une seule ligne ; les caractères « » doivent être échappés par « \ »; pas de sauts de ligne littéraux.

Phase 4 — Sortie

Générer du Markdown en utilisant le format déterminé par ECC_MODE. La sortie utilise un seul format tout au long du texte : chaque {ORCH_CMD} et chaque nom d’agent est rendu avec le préfixe correspondant de la phase 0. Ne générez pas les deux formats ; n’incluez pas d’instructions du type « ceci est le format du plugin » / « supprimer le préfixe » dans la sortie rendue.

Règles de rendu concrètes :

  • {ORCH_CMD} = /everything-claude-code:orchestrate sous « plugin », /orchestrate sous « legacy ».
  • {AGENT(nom)} = everything-claude-code: sous « plugin », sous « legacy ».
  • La colonne « Chain » du tableau récapitulatif utilise le même rendu {AGENT(name)}.
  • Les blocs bash par étape ne contiennent que la commande exécutable. Pas de commentaires de type # plugin form ou # legacy form — la forme est implicite et uniforme sur l'ensemble de la sortie.

Structure de la sortie :

# Résultat de Plan-Orchestrate 
**Plan** : ``
**Lang** : ``
**Mode ECC** : ``
**Étapes** : 
**Portée** : 

## Aperçu des étapes

| # | Titre | Balises | Chaîne |
|---|---|---|---|
| 1 | ... | impl, db | `{AGENT(tdd-guide)},{AGENT(database-reviewer)},{AGENT(python-reviewer)}` |
| ... | | | |

---

## Étape 1 — 

**Objectif** : <1–3 sentences>
**Balises** : <a, b>
**Justification de la chaîne** : <why this chain; which agent closes the loop>

```bash
{ORCH_CMD} custom "{AGENT(tdd-guide)},{AGENT(database-reviewer)},{AGENT(python-reviewer)}" "[Plan : docs/foo.md#step-1] <compressed task description>; Acceptation : <1–3 items>; Hors périmètre : <…>"
```
</code></pre>
<blockquote>
<p>Les notations <code>{ORCH_CMD}</code> et <code>{AGENT(...)}</code> ci-dessus décrivent la substitution effectuée par cette compétence lors de l’exécution. Le code Markdown effectivement généré contient les chaînes de caractères résolues, jamais les espaces réservés.</p>
</blockquote>
<p>Ajoutez un bloc final « Exécution par lots » regroupant les commandes de chaque étape dans l’ordre afin que l’utilisateur puisse les coller toutes en une seule fois. <strong>Ignorez le bloc « Exécution par lots » en mode « aperçu uniquement »</strong> (voir le cas limite « Plan volumineux ») : lorsque seul le tableau d’aperçu est généré, il n’y a pas de commandes par étape à regrouper.</p>
<h3>Phase 5 — Auto-vérification (à exécuter avant l’émission)</h3>
<ul>
<li><input disabled="" type="checkbox"> Chaque agent de chaque chaîne provient du catalogue (après suppression de tout préfixe « <code>everything-claude-code: »</code> apparu dans le plan ; voir la phase 0, étape 5).</li>
<li><input disabled="" type="checkbox"> Les <code>{ORCH_CMD}</code> résolus et tous <code> les {AGENT(...)}</code> résolus utilisent le <strong>même</strong> format (<code>plugin</code> ou <code>hérité</code>) — ils ne sont jamais mélangés dans une même sortie.</li>
<li><input disabled="" type="checkbox"> Aucune annotation <code> de type # forme plugin</code> / <code># forme héritée</code> et aucune instruction de « suppression du préfixe » ne subsiste dans la sortie générée.</li>
<li><input disabled="" type="checkbox"> Aucun champ inventé de type <code>--mode</code> / <code>--gate</code> / <code>--agents=...</code> n’apparaît.</li>
<li><input disabled="" type="checkbox"> Chaque description de tâche tient sur une seule ligne, est placée entre guillemets doubles et comporte des caractères <code> « »</code> échappés.</li>
<li><input disabled="" type="checkbox"> Chaque description de tâche commence par <code>[Plan : <path>#étape-<id>]</code> et inclut la section « Acceptation » (1 à 3 éléments). La clause <code>« Hors champ d’application : »</code> n’est présente que si elle est héritée du plan.</li>
<li><input disabled="" type="checkbox"> Aucun agent ne doit être dupliqué dans une chaîne après la déduplication de la phase 2.</li>
<li><input disabled="" type="checkbox"> Longueur de la chaîne ≤ 4.</li>
<li><input disabled="" type="checkbox"> Les étapes marquées<code>impl/refactor/migration</code> se terminent par un agent de type « réviseur » (<code><lang>-reviewer</code>, <code>code-reviewer</code>, <code>security-reviewer</code> ou <code>database-reviewer</code>). <code>Les étapes « test »</code> et <code>« build »</code> sont exemptées — voir la règle n° 10 de la phase 2.</li>
<li><input disabled="" type="checkbox"> Les étapes sans balise génèrent <code>un « code-reviewer</code> » avec la justification « <code>aucune balise correspondante » ; chaîne par défaut « review-only</code> ».</li>
<li><input disabled="" type="checkbox"> Le tableau récapitulatif répertorie toutes les étapes du plan, quel que soit le paramètre <code>--scope</code>.</li>
<li><input disabled="" type="checkbox"> Le nombre de blocs de détails par étape correspond à la valeur <code> de --scope</code> définie (plan complet lorsque <code>--scope=all</code>; un bloc pour <code>l’étape n ;</code> taille de la plage pour <code>la plage a-b</code>). En mode « aperçu uniquement », aucun bloc par étape ni aucun bloc « Batch » n’est généré.</li>
</ul>
<h2>Cas limites</h2>
<ul>
<li><strong>Pas d’étapes claires</strong>: privilégier le fractionnement H2/H3 ; si l’ambiguïté persiste, signaler « aucune étape structurée détectée » avec le plan du document et demander à l’utilisateur de confirmer l’exécution selon ce plan.</li>
<li><strong>Plan volumineux (>1 500 lignes)</strong>: passer <strong>en mode « aperçu uniquement »</strong> — ne générer que le tableau d’aperçu et demander à l’utilisateur de restreindre la portée avec <code> l’option --scope</code> avant de relancer l’exécution pour obtenir les détails. Dans ce mode, ignorer les blocs de détails par étape et le bloc d’exécution « Batch ».</li>
<li><strong>Étape trop vague</strong> (par ex. « terminer tout le travail en arrière-plan ») : ne pas forcer une chaîne unique. Suggérer un fractionnement en N.a et N.b et proposer ce fractionnement.</li>
<li><strong>Le plan déclare des agents</strong> (rare) : commencez par <strong>supprimer tout préfixe <code>« everything-claude-code: »</code></strong> pour obtenir le nom nu du catalogue (phase 0, étape 5), puis validez par rapport au catalogue. Remplacez les agents non valides et expliquez pourquoi dans la section « Justification de la chaîne ». Le nom nu est préfixé à nouveau au moment de la sortie selon <code>ECC_MODE</code>.</li>
<li><strong>Projet polyglotte où <code> l’option --lang=auto</code> ne parvient pas à choisir un projet gagnant</strong>: définir <code>lang=unknown</code>; le réviseur est converti en « <code>code-reviewer</code> » et le résolveur de compilation en « <code>build-error-resolver</code> ». Mentionner la solution de repli sous « Justification de la chaîne ».</li>
</ul>
<h2>Exemples</h2>
<h3>Exemple 1 — Mode plugin, plan Python</h3>
<p>Entrée :</p>
<pre><code>plan-orchestrate @docs/plan/example-feature.md --lang=python
</code></pre>
<p>Extrait de la sortie attendue :</p>
<pre><code class="language-markdown">## Étape 2 — Chiffrage des champs sensibles de UserProfile

**Objectif** : Introduire un type SQLAlchemy `EncryptedString` et chiffrer `birth_datetime` / `location` à l’aide de l’algorithme AES-GCM avant la persistance ; charger la clé à partir d’une variable d’environnement.
**Mots-clés** : impl, sécurité, base de données
**Justification de la chaîne** : Parcours d’écriture sensible en matière de sécurité, donc `security-reviewer` clôt la chaîne ; `database-reviewer` valide la migration Alembic ; `python-reviewer` vérifie le typage et le respect de la PEP 8.

```bash
/everything-claude-code:orchestrate custom "everything-claude-code:tdd-guide,everything-claude-code:database-reviewer,everything-claude-code:python-reviewer,everything-claude-code:security-reviewer" « [Plan : docs/plan/example-feature.md#step-2] Implémenter le type EncryptedString de SQLAlchemy et migrer les colonnes UserProfile.birth_datetime/location ; clé provenant de l’environnement APP_DB_KEY ; Acceptation : réussite des tests de chiffrement/déchiffrement aller-retour ; mise à niveau/rétrogradation d’Alembic sans problème sur une base de données vide ; absence de texte en clair dans la base de données après la migration ; Hors périmètre : logique de partage de profil entre locataires"
```
</code></pre>
<h3>Exemple 2 — Mode hérité, même étape</h3>
<p>Si <code>ECC_MODE=legacy</code> était détecté, la même étape serait émise sous la forme d’une seule commande uniforme (aucune forme préfixée par un plugin n’apparaîtrait dans la sortie) :</p>
<pre><code class="language-bash">/orchestrate custom "tdd-guide,database-reviewer,python-reviewer,security-reviewer" "[Plan : docs/plan/example-feature.md#step-2] ..."
</code></pre>
<p>Les deux exemples ci-dessus illustrent <strong>les deux sorties possibles</strong> pour deux environnements différents. Une seule invocation de compétence ne produit qu’une seule de ces sorties, de bout en bout.</p>
<h2>Remarques</h2>
<ul>
<li>Génération uniquement. N’invoquez jamais <code>/orchestrate</code> depuis l’intérieur de cette compétence.</li>
<li>Adaptez la langue du document de plan aux descriptions des tâches (les noms des agents restent toujours en anglais).</li>
<li>N’insérez pas de lignes « Co-Authored-By » ni d’émojis dans la sortie, sauf si l’utilisateur le demande explicitement.</li>
</ul>                                </div>
                                <div class="skilldetailsL1_skillmd">
                                    <a href="https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate" title="Voir sur GitHub" target="_blank" rel="nofollow"
                                        aria-label="Voir sur GitHub" class="skilldetails_toGitHub">
                                        <span>Voir sur GitHub</span>
                                        <b></b>
                                    </a>
                                    <pre><code>---
name: plan-orchestrate
description: Reads a plan document, decomposes it into steps, designs a per-step agent chain from the ECC catalogue, and emits ready-to-paste /orchestrate custom prompts without executing them.
---

# Plan Orchestrate

Bridge a plan document to `/orchestrate custom` by emitting one ready-to-paste invocation per step. The skill is generative only — it never executes `/orchestrate`. The user pastes each line when ready.

## When to Activate

- User has a multi-step plan document (PRD, RFC, implementation plan) and wants to drive it through `/orchestrate`.
- User says "orchestrate this plan", "give me orchestrate prompts for each step", "compose chains for this plan".
- A step-by-step plan exists but the user does not want to manually pick agents per step.

Skip when:
- The work is one ad-hoc step → call `/orchestrate custom` directly.
- The plan is unreadable or empty. Lack of explicit numbering alone is not a skip condition — see the "No clear steps" edge case below.

## Inputs

```
<plan-doc-path> [--lang=python|typescript|go|rust|cpp|java|kotlin|flutter|auto] [--scope=all|step:<n>|range:<a>-<b>] [--dry-run]
```

- `<plan-doc-path>` — required; relative or absolute path (`@docs/...` accepted).
- `--lang` — reviewer language variant; defaults to `auto` (detected from project).
- `--scope` — limits emitted steps; defaults to `all`.
- `--dry-run` — print decomposition + chain rationale only; do not emit final prompts.

## Authoritative `/orchestrate` shape (do not deviate)

```
{ORCH_CMD} custom "<agent1>,<agent2>,...,<agentN>" "<task description>"
```

Where `{ORCH_CMD}` is determined in Phase 0 (see below). The command string in the emitted output **always uses one concrete form** — never both, never a placeholder.

- `custom` is a sequential chain; each agent's HANDOFF feeds the next.
- Comma-separated agent list. No spaces preferred; one space tolerated.
- No `--mode` / `--gate` / `--agents=...` flags exist — never invent them.
- Agent names come from the catalogue in this skill. Embedded double quotes in the task description are escaped as `\"`.

## ECC install form and namespacing

Two install forms determine the prefix on **both** the slash command and every agent name. The two MUST stay in sync — one form per output, never mixed:

Let `<claude-home>` denote the Claude Code home directory: `~/.claude` on macOS/Linux, `%USERPROFILE%\.claude` on Windows. Resolve it the way the host platform resolves the user home directory (do not hardcode `~`).

| Form | Detection | `{ORCH_CMD}` | Agent name format |
|---|---|---|---|
| Plugin install (1.9.0+) | `<claude-home>/plugins/marketplaces/everything-claude-code/` exists | `/everything-claude-code:orchestrate` | `everything-claude-code:<name>` |
| Legacy bare install | Above absent; agent files under `<claude-home>/agents/` | `/orchestrate` | `<name>` |

Why this matters: under the plugin install, agents register as `everything-claude-code:tdd-guide`. Bare names force fuzzy matching, which fails intermittently under parallel calls. Under legacy, the prefixed forms are not registered and fail outright.

## Available agent catalogue (must pick from these)

General:
- `planner` — requirement restatement, risk decomposition, step planning
- `architect` — architecture, system design, refactor proposals
- `tdd-guide` — write tests → implement → 80%+ coverage
- `code-reviewer` — generic code review
- `security-reviewer` — security audit, OWASP, secret leakage
- `refactor-cleaner` — dead code, duplicates, knip-class cleanup
- `doc-updater` — documentation, codemap, README
- `docs-lookup` — third-party library API lookups (Context7)
- `e2e-runner` — end-to-end test orchestration
- `database-reviewer` — PostgreSQL schema, migration, performance
- `harness-optimizer` — local agent harness configuration
- `loop-operator` — long-running autonomous loops
- `chief-of-staff` — multi-channel triage (rarely a fit for plan steps)

Build error resolvers:
- `build-error-resolver` (generic) / `cpp-build-resolver` / `go-build-resolver` / `java-build-resolver` / `kotlin-build-resolver` / `rust-build-resolver` / `pytorch-build-resolver`

Code reviewers:
- `python-reviewer` / `typescript-reviewer` / `go-reviewer` / `rust-reviewer` / `cpp-reviewer` / `java-reviewer` / `kotlin-reviewer` / `flutter-reviewer`

A misspelled agent name fails `/orchestrate`. Cross-check against this list before emitting.

## How It Works

### Phase 0 — Detect ECC mode + language

1. Read `<plan-doc-path>`. If missing or empty, report and stop.
2. Detect ECC install form once and freeze it into `ECC_MODE`. Algorithm (run in order, stop at the first match):
   1. If `<claude-home>/plugins/marketplaces/everything-claude-code/` exists → `ECC_MODE=plugin`.
   2. Else if `<claude-home>/agents/` exists and contains at least one ECC agent file (e.g. `tdd-guide.md`, `code-reviewer.md`) → `ECC_MODE=legacy`.
   3. Else → default to `ECC_MODE=legacy` and emit a one-line warning at the top of the output: `> Warning: could not detect ECC install; defaulting to legacy form. If you use the plugin install, edit the prefixes manually.`
   4. If both markers exist (mixed install), `plugin` wins — the plugin namespace is the only one that resolves agent names without fuzzy matching.

   From this point on, every emitted line uses the matching prefix on **both** the slash command and every agent name. **Never emit both forms in the same output.**
3. Resolve `--lang`. When `auto`, run a polyglot-aware detection:
   - Probe markers: `pyproject.toml` / `uv.lock` / `requirements.txt` → python; `package.json` → typescript; `go.mod` → go; `Cargo.toml` → rust; `CMakeLists.txt` or top-level `*.cpp` → cpp; `pom.xml` / `build.gradle` (Java) → java; `build.gradle.kts` or top-level Kotlin → kotlin; `pubspec.yaml` → flutter.
   - **Polyglot tie-break**: if more than one marker matches, pick the language whose source files outnumber the others (count via `git ls-files`, excluding `vendor/`, `node_modules/`, `dist/`, `build/`, `.venv/`, generated files, and obvious test fixtures). On a tie or when no language exceeds 60% of source files, set `lang=unknown`.
   - No marker matched → set `lang=unknown`.
   - `lang=unknown` is a sentinel — it is **not** an agent name. Phase 2 rules 4 and 5 turn it into `code-reviewer` / `build-error-resolver` at chain composition time.
4. Detect a **PyTorch sub-profile**: when `lang=python` and any of `pyproject.toml` / `requirements.txt` / `uv.lock` declares a dependency on `torch`, set `pytorch=true`. This only affects `build` chain selection (Phase 2 rule below); the reviewer remains `python-reviewer`.
5. **Normalize any agent names declared in the plan**: if the plan text references agents by their plugin-prefixed form (e.g. `everything-claude-code:tdd-guide`), strip the prefix to get the bare catalogue name before validating or composing chains. Re-prefixing happens only at output time per `ECC_MODE` (Phase 4). Never let a pre-prefixed name flow into chain composition — it would double-prefix in plugin mode.

### Phase 1 — Decompose steps

Identify "step units" in priority order:

1. Explicit numbering: `## Step N` / `### Phase N` / `## N. ...` / top-level ordered list.
2. A "Step" column in a table.
3. `---`-separated blocks with verb-led headings.
4. Otherwise treat each H2 as one step.

Per step extract `id` (1-based), `title` (≤ 80 chars), `intent` (1–3 sentences), `tags`.

### Phase 2 — Tag and pick chain

Tag by intent (multi-tag allowed; chain built from primary + stacked secondaries):

Trigger words below are matched case-insensitively. Multilingual plans are supported by matching the word stems in any language as long as the meaning aligns with the listed English trigger words.

| Tag | Trigger words | Default chain |
|---|---|---|
| `design` | architecture, design, choose, evaluate, RFC | `planner,architect` |
| `plan` | plan, breakdown, milestone | `planner` |
| `impl` | implement, build, add, create, port | `tdd-guide,<lang>-reviewer` |
| `test` | test, coverage, e2e, integration | `tdd-guide,e2e-runner` |
| `refactor` | refactor, cleanup, dedupe, split | `architect,refactor-cleaner,<lang>-reviewer` |
| `migration` | migrate, upgrade, rewrite, port | `architect,tdd-guide,<lang>-reviewer` |
| `db` | schema, migration, index, SQL, Postgres, alembic, sqlmodel | `database-reviewer,<lang>-reviewer` |
| `security` | encrypt, auth, secret, OWASP, PII | `security-reviewer,<lang>-reviewer` |
| `build` | build, compile, lint failure, CI | `<lang>-build-resolver` (falls back to `build-error-resolver`) |
| `docs` | docs, readme, codemap, changelog | `doc-updater` |
| `lookup` | lookup, reference, API usage | `docs-lookup` |
| `review` | review, audit, verify | `<lang>-reviewer,code-reviewer` |
| `loop` | loop, autonomous, watchdog | `loop-operator` |

Chain composition rules:
1. **Primary tag selection**: when a step matches multiple tags, the **first one in table order** (top of the table = highest priority) is the primary; the rest are secondaries. Composition rules 2 and 3 below handle specific multi-tag combinations explicitly; otherwise, append secondary chains in tag table order.
2. `impl` + `security` → `tdd-guide,<lang>-reviewer,security-reviewer`.
3. `impl` + `db` → `tdd-guide,database-reviewer,<lang>-reviewer`.
4. **Deduplicate** the resulting chain (preserve first occurrence). E.g. `review` + `lang=unknown` would yield `code-reviewer,code-reviewer` after rule 5; deduplication collapses it to `code-reviewer`.
5. `<lang>-reviewer` resolves to `code-reviewer` when `lang=unknown`.
6. `<lang>-build-resolver` resolves to `build-error-resolver` when `lang=unknown`. **Special case**: if Phase 0 set `pytorch=true`, use `pytorch-build-resolver` for `build` chains regardless of `<lang>`. There is no `python-build-resolver`; `--lang=python` without `pytorch=true` resolves to `build-error-resolver`.
7. **Zero-tag steps**: if no trigger word matches, set chain to `code-reviewer` and write `no tag matched; default review-only chain` under "Chain rationale".
8. Chain length ≤ 4 after deduplication. If exceeded, drop weakest tag (`lookup` and `docs` first).
9. Do not pair `planner` and `architect` in an `impl` chain (token waste). Pair them only on `design` steps.
10. Steps tagged `impl`, `refactor`, or `migration` end with a **reviewer-class** agent — any of `<lang>-reviewer`, `code-reviewer`, `security-reviewer`, or `database-reviewer`. The most domain-specific reviewer wins the tail position (e.g. rule 2's `impl+security` ends with `security-reviewer`; rule 3's `impl+db` ends with `<lang>-reviewer` because `database-reviewer` already gates the migration earlier in the chain). `test` and `build` steps are gated by their own validators (`e2e-runner` and the build resolver respectively) and do not require an additional reviewer.

### Phase 3 — Compress task description

Each emitted `<task description>` must:
- Be self-contained (the first agent does not need the plan document open).
- Start with `[Plan: <path>#step-<id>]`.
- Include 1–3 verifiable Acceptance criteria.
- Include a Scope guard (`Out of scope: ...`) **only if the plan declares one for this step**. Inherit verbatim. If the plan has no out-of-scope statement, omit the clause entirely — do not invent one.
- Be 200–600 characters; one line; embedded `"` escaped as `\"`; no literal newlines.

### Phase 4 — Output

Emit Markdown using **the form determined by `ECC_MODE`**. The output uses one form throughout — every `{ORCH_CMD}` and every agent name is rendered with the matching prefix from Phase 0. **Do not emit both forms; do not include "this is plugin form" / "strip the prefix" instructions in the rendered output.**

Concrete rendering rules:

- `{ORCH_CMD}` = `/everything-claude-code:orchestrate` under `plugin`, `/orchestrate` under `legacy`.
- `{AGENT(name)}` = `everything-claude-code:<name>` under `plugin`, `<name>` under `legacy`.
- The overview-table "Chain" column uses the same `{AGENT(name)}` rendering.
- Per-step bash blocks contain only the runnable command. **No `# plugin form` or `# legacy form` comments** — the form is implicit and uniform across the whole output.

Output structure:

````markdown
# Plan-Orchestrate Result

**Plan**: `<path>`
**Lang**: `<detected-or-given>`
**ECC mode**: `<plugin | legacy>`
**Steps**: <N>
**Scope**: <all | step:n | range:a-b>

## Steps overview

| # | Title | Tags | Chain |
|---|---|---|---|
| 1 | ... | impl, db | `{AGENT(tdd-guide)},{AGENT(database-reviewer)},{AGENT(python-reviewer)}` |
| ... | | | |

---

## Step 1 — <title>

**Intent**: <1–3 sentences>
**Tags**: <a, b>
**Chain rationale**: <why this chain; which agent closes the loop>

```bash
{ORCH_CMD} custom "{AGENT(tdd-guide)},{AGENT(database-reviewer)},{AGENT(python-reviewer)}" "[Plan: docs/foo.md#step-1] <compressed task description>; Acceptance: <1–3 items>; Out of scope: <…>"
```
````

> The `{ORCH_CMD}` and `{AGENT(...)}` notation above describes the substitution this skill performs at runtime. The actual emitted Markdown contains the resolved strings, never the placeholders.

Append a final "Batch execution" block aggregating every step's command in order so the user can paste them all at once. **Skip the Batch block in overview-only mode** (see "Large plan" edge case): when only the overview table is being emitted, there are no per-step commands to aggregate.

### Phase 5 — Self-check (run before emitting)

- [ ] Every agent in every chain comes from the catalogue (after stripping any `everything-claude-code:` prefix that appeared in the plan; see Phase 0 step 5).
- [ ] Resolved `{ORCH_CMD}` and every resolved `{AGENT(...)}` use the **same** form (`plugin` or `legacy`) — never mixed in one output.
- [ ] No `# plugin form` / `# legacy form` annotations and no "strip the prefix" instructions remain in the rendered output.
- [ ] No invented `--mode` / `--gate` / `--agents=...` fields.
- [ ] Each task description is single-line, double-quoted, with embedded `"` escaped.
- [ ] Each task description begins with `[Plan: <path>#step-<id>]` and includes Acceptance (1–3 items). The `Out of scope:` clause is present only when inherited from the plan.
- [ ] No duplicate agent in any chain after Phase 2 dedup.
- [ ] Chain length ≤ 4.
- [ ] Steps tagged `impl`/`refactor`/`migration` end with a reviewer-class agent (`<lang>-reviewer`, `code-reviewer`, `security-reviewer`, or `database-reviewer`). `test` and `build` are exempt — see Phase 2 rule 10.
- [ ] Zero-tag steps emit `code-reviewer` with the rationale `no tag matched; default review-only chain`.
- [ ] Overview table lists every step in the plan, regardless of `--scope`.
- [ ] Per-step detail block count matches the resolved `--scope` (full plan when `--scope=all`; one block for `step:n`; range size for `range:a-b`). In overview-only mode, no per-step blocks and no Batch block are emitted.

## Edge cases

- **No clear steps**: prefer H2/H3 splitting; if still ambiguous, report "no structured steps detected" with the document outline and ask the user to confirm running by outline.
- **Large plan (>1500 lines)**: enter **overview-only mode** — emit only the overview table and ask the user to narrow with `--scope` before re-running for details. In this mode, skip per-step detail blocks and skip the Batch execution block.
- **Step too broad** (e.g. "complete all backend work"): do not force a single chain. Suggest splitting into N.a and N.b and propose a split.
- **Plan declares agents** (rare): first **strip any `everything-claude-code:` prefix** to get the bare catalogue name (Phase 0 step 5), then validate against the catalogue. Replace invalid agents and explain under "Chain rationale". The bare name is re-prefixed at output time per `ECC_MODE`.
- **Polyglot project where `--lang=auto` cannot pick a winner**: set `lang=unknown`; reviewer resolves to `code-reviewer` and build resolver to `build-error-resolver`. Mention the fallback under "Chain rationale".

## Examples

### Example 1 — Plugin mode, Python plan

Input:
```
plan-orchestrate @docs/plan/example-feature.md --lang=python
```

Excerpt of expected output:
````markdown
## Step 2 — Encrypt sensitive UserProfile fields

**Intent**: Introduce an `EncryptedString` SQLAlchemy type and AES-GCM encrypt `birth_datetime` / `location` before persistence; load the key from an environment variable.
**Tags**: impl, security, db
**Chain rationale**: Security-sensitive write path, so `security-reviewer` closes the chain; `database-reviewer` validates the alembic migration; `python-reviewer` covers typing and PEP 8.

```bash
/everything-claude-code:orchestrate custom "everything-claude-code:tdd-guide,everything-claude-code:database-reviewer,everything-claude-code:python-reviewer,everything-claude-code:security-reviewer" "[Plan: docs/plan/example-feature.md#step-2] Implement EncryptedString SQLAlchemy type and migrate UserProfile.birth_datetime/location columns; key from ENV APP_DB_KEY; Acceptance: encrypt/decrypt roundtrip tests pass; alembic upgrade/downgrade clean on empty DB; no plaintext in DB after migrate; Out of scope: cross-tenant profile sharing logic"
```
````

### Example 2 — Legacy mode, same step

If `ECC_MODE=legacy` were detected, the same step would be emitted as a single uniform command (no plugin-prefixed forms anywhere in the output):

```bash
/orchestrate custom "tdd-guide,database-reviewer,python-reviewer,security-reviewer" "[Plan: docs/plan/example-feature.md#step-2] ..."
```

The two examples above illustrate **the two possible outputs** for two different environments. A single skill invocation produces only one of them, end to end.

## Notes

- Generative only. Never invoke `/orchestrate` from inside this skill.
- Match the language of the plan document for task descriptions (agent names always remain English).
- Do not insert "Co-Authored-By" lines or emoji in the output unless the user explicitly asks.
</code></pre>                                </div>
                            </div>

                        </div>
                        <script>
                            layui.use(function () {
                                var element = layui.element;
                                element.tab({
                                    headerElem: "#skilldetailsL1_header>button",
                                    bodyElem: "#skilldetailsL1_body>div",
                                });
                            });
                        </script>
                        <div class="skilldetailsL2">
                            <div class="skilldetailsL2_title">
                                <h2>Tous les fichiers</h2>
                                <span>1 fichiers</span>
                            </div>
                                                        <div class="skillFiles">
                                <div class="skillFilesL">
                                    <b></b>
                                    <a href="https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate" title="plan-orchestrate.md" target="_blank"
                                        aria-label="plan-orchestrate.md"
                                        rel="nofollow">plan-orchestrate.md</a>
                                    <span>17.5k</span>
                                </div>
                                <a href="https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate" title="Voir" target="_blank" aria-label="Voir"
                                    rel="nofollow">Voir</a>
                            </div>
                                                    </div>
                    </div>
                    <div class="skilldetailsR">
                        <div class="skilldetailsR1">
                            <div class="skilldetailsR1s">
                                <h2>Installer plan-orchestrate</h2>
                                <div class="skilldetailsR1s_header" id="skilldetailsR1s_header">
                                    <button class="layui-this">
                                        <b></b>
                                        <span>Télécharger le ZIP</span>
                                    </button>
                                    <button class="">
                                        <b></b>
                                        <span>Git Clone</span>
                                    </button>
                                </div>
                                <div class="skilldetailsR1s_body" id="skilldetailsR1s_body">
                                    <div class="skilldetailsR1s_body1 layui-show">
                                        <p>Téléchargez et décompressez les fichiers de compétences dans votre répertoire .claude/skills/.</p>
                                        <a href="javascript:;" title="Télécharger le ZIP" data-source="TeeN26C1ni2ZDZRkOJVh9w"
                                            aria-label="Télécharger le ZIP" role="button" class="skill_downloadzip">
                                            <b></b>
                                            <span>Télécharger le ZIP</span>
                                        </a>
                                    </div>
                                    <div class="skilldetailsR1s_body2">
                                        <p>Clonez le dépôt et copiez les fichiers de compétence dans votre projet.</p>
                                        <div class="skill_clone">
                                            <p>
                                                git clone https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate
# Copy SKILL.md to your .claude/skills/ directory                                            </p>
                                            <a href="javascript:;" title="Copier" role="button" aria-label="Copier"
                                                class="skill_clone_copy">
                                                <img src="/assets/images/prompt_word2RMs_p_btn.png"
                                                    alt="Copier" />
                                                <span>Copier</span>
                                            </a>
                                        </div>
                                    </div>
                                </div>
                                <div class="skilldetailsR1s_info">
                                    <span>Configuration rapide: </span>
                                    Copiez le dossier de la compétence dans .claude/skills/
Claude détectera automatiquement la compétence et l'utilisera                                </div>
                                <div class="skilldetailsR1s_repository">
                                    <span>Dépôt</span>
                                    <a href="https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate" title="affaan-m/ECC" target="_blank"
                                        aria-label="Dépôt" rel="nofollow">affaan-m/ECC</a>
                                </div>
                            </div>
                        </div>
                        <div class="skilldetailsR2">
                            <h2>Compétences similaires</h2>
                            <div>
                                                                <div class="skilldetailsR2s">
                                    <a href="/fr/skill/detail/airtableautomation.html" title="airtable-automation" aria-label="airtable-automation">airtable-automation</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Heure mise à jour                                                29 juin 2026</span>
                                        </div>
                                        <button class="xix_star skill_datas"
                                            data-source="P_PqrAzxvKSebU4gaXatSw">
                                            <b></b>
                                            <span
                                                class="collectNums_P_PqrAzxvKSebU4gaXatSw">0</span>
                                        </button>
                                    </div>
                                </div>
                                                                <div class="skilldetailsR2s">
                                    <a href="/fr/skill/detail/notionautomation.html" title="notion-automation" aria-label="notion-automation">notion-automation</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Heure mise à jour                                                29 juin 2026</span>
                                        </div>
                                        <button class="xix_star skill_datas"
                                            data-source="yLOF7em0zgx36kG9EQmIAQ">
                                            <b></b>
                                            <span
                                                class="collectNums_yLOF7em0zgx36kG9EQmIAQ">0</span>
                                        </button>
                                    </div>
                                </div>
                                                                <div class="skilldetailsR2s">
                                    <a href="/fr/skill/detail/seoprogrammatic.html" title="seo-programmatic" aria-label="seo-programmatic">seo-programmatic</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Heure mise à jour                                                29 juin 2026</span>
                                        </div>
                                        <button class="xix_star skill_datas"
                                            data-source="qrlDZwmv4vNLPwqrODKcOQ">
                                            <b></b>
                                            <span
                                                class="collectNums_qrlDZwmv4vNLPwqrODKcOQ">0</span>
                                        </button>
                                    </div>
                                </div>
                                                                <div class="skilldetailsR2s">
                                    <a href="/fr/skill/detail/revops.html" title="revops" aria-label="revops">revops</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Heure mise à jour                                                29 juin 2026</span>
                                        </div>
                                        <button class="xix_star skill_datas"
                                            data-source="ZDIT-veTOzkFQQ0eUEoT-g">
                                            <b></b>
                                            <span
                                                class="collectNums_ZDIT-veTOzkFQQ0eUEoT-g">0</span>
                                        </button>
                                    </div>
                                </div>
                                
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </main>
        <footer>
  <div class="footer">
    <div class="footer1">
      <div class="footer11">
        <span class="footer11_title">Outils d'IA chauds</span>
        <div class="footer11info">
                    <a href="/fr/tool/ai-clothes-remover.html" aria-label="AI Clothes Remover" class="footer11s">AI Clothes Remover</a>
                    <a href="/fr/tool/deepnude-generator.html" aria-label="DeepNude generator" class="footer11s">DeepNude generator</a>
                    <a href="/fr/tool/purechat.html" aria-label="PureChat" class="footer11s">PureChat</a>
                  </div>
      </div>
      <div class="footer12">
        <span class="footer11_title">Outils d'IA avec potentiel</span>
        <div class="footer11info">
                    <a href="/fr/tool/idea-box-ai-tool.html" aria-label="Name Idea Box" class="footer11s">Name Idea Box</a>
                    <a href="/fr/tool/qi-jing-ai-ai-tool.html" aria-label="奇境 AI" class="footer11s">奇境 AI</a>
                    <a href="/fr/tool/ezaudio-ai-tool.html" aria-label="EZAudio" class="footer11s">EZAudio</a>
                  </div>
      </div>
      <div class="footer13">
        <span class="footer11_title">EN SAVOIR PLUS</span>
        <div class="footer11info">
                    <a href="/fr/ainews/ai-hosts-notebooklm-podcast-interviews.html" aria-label="Podcast Hosts Of NoteBookLM maintenant disponible pour les interviews" class="footer11s">Podcast Hosts Of NoteBookLM maintenant disponible pour les interviews</a>
                    <a href="/fr/ainews/corporate-ai-adoption-leveling-ramp-data.html" aria-label="L'adoption de l'IA par les entreprises plafonne, selon les données de Ramp" class="footer11s">L'adoption de l'IA par les entreprises plafonne, selon les données de Ramp</a>
                    <a href="/fr/ainews/microsoft-unveils-businessfocused-copilot-surface-devices-powered-intel.html" aria-label="Microsoft dévoile des dispositifs de surface axés sur les entreprises alimentés par Intel" class="footer11s">Microsoft dévoile des dispositifs de surface axés sur les entreprises alimentés par Intel</a>
                  </div>
      </div>
      <div class="footer4">
        <span class="footer11_title">Suivre</span>
        <div class="footer11info">
          <a href="javascript:;" class="footer11s">Contactez-nous</a>
          <a href="mailto:admin@xix.ai" role="button" aria-label="Contactez-nous" class="footer11s">admin@xix.ai</a>
          <a href="/sitemap.xml" class="footer11s" aria-label="SiteMap">SiteMap</a>
        </div>
      </div>
    </div>
    <span class="footer2"></span>
    <div class="footer3">Copyright ©2025 xix.ai All Rights Reserved.</div>
  </div>
</footer>
<div class="ai_cookie" style="display: none">
      <div class="ai_cookie_b">
        <div class="icon_f ai_cookie_close">
          <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-guanbi1"></use>
          </svg>
        </div>
        <p>
          En cliquant sur "Accepter tous les cookies", vous consentez au stockage de cookies sur votre appareil afin d’améliorer la navigation sur le site, d’analyser l’utilisation du site et de soutenir nos efforts marketing.<span>Politique de confidentialité</span> Avis        </p>
        <div class="cokiesetRight">
          <a href="javascript:;" class="cokieA ai_cookie_open"  role="button" aria-label="Paramètres des cookies">Paramètres des cookies</a>
          <a href="javascript:;" class="cokieA RefuseCookies" role="button" aria-label="Tout refuser">Tout refuser</a>
          <a href="javascript:;" class="cokieA cokieAall" role="button" aria-label="Accepter tous les cookies">Accepter tous les cookies</a>
        </div>
      </div>
    </div>
    <div class="ai_cookieSettings" style="display: none">
      <div class="layuiDivcokie layui-layer-wrap" id="layuiDivcokie" style="display: block">
        <div class="cokielayTop dlyflx">
          <img src="/assets/images/logo.png" alt="" />
          <div class="icon_f ai_cookie_close1">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-guanbi"></use>
            </svg>
          </div>
        </div>
        <hr />
        <div class="cokielayDown dlyflx">
          <p class="cokielaydTop">Préférences de confidentialité</p>
          <p class="cokielaydDesc">
            Lorsque vous visitez un site web, il peut stocker ou récupérer des informations sur votre navigateur, principalement sous forme de cookies. Ces informations peuvent concerner vous, vos préférences ou votre appareil et sont principalement utilisées pour faire fonctionner le site comme vous vous y attendez. Ces informations n’identifient généralement pas directement vous-même, mais elles peuvent vous offrir une expérience web plus personnalisée. Parce que nous respectons votre droit à la vie privée, vous pouvez choisir de ne pas autoriser certains types de cookies. Cliquez sur les différents titres de catégorie pour en savoir plus et modifier nos paramètres par défaut. Cependant, bloquer certains types de cookies peut affecter votre expérience sur le site et les services que nous sommes en mesure de proposer. <a href="#" title="Politique de confidentialité" aria-label="Politique de confidentialité"><span>Politique de confidentialité</span></a> <b>Déclaration</b>          </p>

          <div class="cokielayDivdown">
            <p class="coklaydownP">Gérer les préférences</p>
            <ul class="cokidownUl">
              <li class="cokidownli dlyflx" style="padding: 25px 0px 25px">
                <div class="ckdTops">
                  <div class="ckdLeft">
                    <div class="icon_f">
                      <svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-add"></use>
                      </svg>
                      <svg class="icon icon_active" aria-hidden="true">
                        <use xlink:href="#icon-add1"></use>
                      </svg>
                    </div>
                    <p class="ckdlipmid">Cookie strictement nécessaire</p>
                  </div>
                  <p class="ckdlipr">Toujours actif</p>
                </div>
                <p class="ckdDowns">
                  Ces cookies sont nécessaires au fonctionnement du site web et ne peuvent pas être désactivés dans nos systèmes. Ils ne sont généralement définis qu’en réponse à des actions que vous effectuez qui équivalent à une demande de services, telles que la configuration de vos préférences de confidentialité, la connexion ou le remplissage de formulaires. Vous pouvez configurer votre navigateur pour bloquer ces cookies ou vous alerter à leur sujet, mais certaines parties du site ne fonctionneront alors plus. Ces cookies ne stockent aucune information permettant d’identifier personnellement.                </p>
              </li>
            </ul>
          </div>
        </div>
        <div class="cklyBtn">
          <a href="javascript:;" role="button" aria-label="Accepter tous les cookies" class="active cokieAall">Accepter tous les cookies</a>
        </div>
      </div>
      <script>
        $(document).on("click", ".ai_cookie_close", function () {
          $(".ai_cookie").hide();
        });
        $(document).on("click", ".ai_cookie_close1", function () {
          $(".ai_cookieSettings").hide();
        });
        $(document).on("click", ".ai_cookie_open", function () {
          $(".ai_cookieSettings").show();
        });
        $(document).on("click", ".ckdLeft", function () {
          var $li = $(this).closest("li"); 
          var $downs = $li.find(".ckdDowns"); 
          var $iconBox = $(this).find(".icon_f"); 

         
          $downs.slideToggle(200, function () {
            if ($downs.is(":visible")) {
              $iconBox.find(".icon").hide();
              $iconBox.find(".icon_active").show();
            } else {
              $iconBox.find(".icon").hide();
              $iconBox.find(".icon").first().show(); 
            }
          });
        });     
      </script>
    </div>
<link rel="stylesheet" type="text/css" href="https://accounts.google.com/gsi/style">
<div class="login_tab">
  <div class="login_mainC">
    <div class="login_tab_top">
      <div class="login_tab_top1">
        <a href="javascript:;" role="tab" aria-label="Se connecter" aria-selected="true" class="login_tab_top1a ">Se connecter</a>
        <a href="javascript:;" role="tab" aria-label="S'inscrire" aria-selected="false" class="login_tab_top2a">S'inscrire</a>
      </div>
      <div class="login_tab_top2">
        <a href="javascript:;"><img src="/assets/images/login_mainC_top_m_img.png" alt=""></a>
      </div>

    </div>
    <div class="forms_google">
      <div id="g_id_signin"></div>
    </div>
    <div class="forms_or">
      <div class="forms_line"></div>
      <span>OR</span>
      <div class="forms_line"></div>
    </div>
    <div class="login_tab_bottom">
      <div class="login_tab_top1a_bottom">

        <div class="login_form ">
          <div class="login_forms">
            <img src="/assets/images/login_email.png" alt="E-mail">
            <input type="text" placeholder="Veuillez remplir votre adresse e-mail" class="login_forms_email">
            <span></span>
          </div>
          <div class="login_forms">
            <img src="/assets/images/login_password.png" alt="Mot de passe">
            <input type="password" placeholder="Veuillez saisir votre mot de passe" class="login_forms_password">
            <i style="cursor: pointer;" class="layui-icon layui-icon-eye-invisible toggle-password"
              id="toggleLoginPassword"></i>
            <span></span>
          </div>
          <div class="login_forms forms_code1">
            <input type="text" placeholder="Veuillez saisir le code de vérification graphique"
              class="login_forms_captcha">
            <img src="" alt="Veuillez saisir le code de vérification graphique" class="login-js-refresh-captcha">
            <span></span>
          </div>
          <div class="login_forms_bottom">
            <label class="login_remember">
              <input type="checkbox" aria-label="Souviens-toi de moi">
              <span>Souviens-toi de moi</span>
            </label>
            <a href="/fr/account/forgetPassword.html" aria-label="Changer le mot de passe" class="login_forget">Mot de passe oublié</a>
          </div>
          <a href="javascript:;" type="button" role="button" aria-label="Se connecter" id="login_button" class="login_button">Se connecter</a>

        </div>
      </div>
      <div class="login_tab_top2a_bottom">
        <div class="login_form">
          <div class="login_forms">
            <img src="/assets/images/login_email.png" alt="E-mail">
            <input type="text" placeholder="Veuillez remplir votre adresse e-mail" class="register_forms_email">
            <span></span>
          </div>
          <div class="login_forms">
            <img src="/assets/images/login_password.png" alt="Mot de passe">
            <input type="password" placeholder="Veuillez saisir votre mot de passe" class="register_forms_password">
            <i style="cursor: pointer;" class="layui-icon layui-icon-eye-invisible toggle-password"
              id="toggleRegisterPassword"></i>
            <span></span>
          </div>
          <div class="login_forms forms_code1">
            <input type="text" placeholder="Veuillez saisir le code de vérification graphique"
              class="register_forms_captcha">
            <img src="" alt="Veuillez saisir le code de vérification graphique" class="register-js-refresh-captcha" id="register_captcha">
            <span></span>
          </div>
          <div class="login_forms">
            <input type="text" class="verify-code-input" placeholder="Veuillez saisir le code de vérification">
            <button id="verifyCodeBtn" class="verify-code-btn" data-text="Obtenir le code de vérification">Obtenir le code de vérification</button>
            <span></span>
          </div>
          <a href="javascript:;" role="button" aria-label="S'inscrire" class="login_button" id="register_button">S'inscrire</a>
        </div>
      </div>

    </div>
  </div>
</div>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script>
  $(document).ready(function () {
    LoginRegister.init({
      selectors: {
        email: {
          login: '.login_forms_email',
          register: '.register_forms_email'
        },
        password: {
          login: '.login_forms_password',
          register: '.register_forms_password'
        },
        captcha: {
          login: '.login_forms_captcha',
          register: '.register_forms_captcha',
          verify: '.verify-code-input'
        },
        buttons: {
          login: '#login_button',
          register: '#register_button',
          verifyCode: '#verifyCodeBtn'
        },
        tabs: {
          login: '.login_tab_top1a',
          register: '.login_tab_top2a',
          close: '.login_tab_top2 a'
        }
      },
      messages: {
        email: "Le format de messagerie est incorrect",
        password: {
          empty: "Veuillez saisir votre mot de passe",
          invalid: "Le mot de passe doit être de 6 à 18 caractères et contenir à la fois des lettres et des numéros"
        },
        captcha: "Veuillez saisir le code de vérification graphique",
        verifyCode: "Veuillez saisir le code de vérification",
        operationInProgress: "Opération en cours, veuillez attendre",
        unexpectedError: "Une erreur inattendue s'est produite"
      },
      urls: {
        login: "/fr/account/dologin.html",
        register: "/fr/account/register.html",
        getMailSign: "/fr/account/getMailSign",
        sendMail: "/fr/account/registerSendMail.html",
        redirctUrl:'pc'
      }
    });
  });
  function initializeGoogleSignIn() {
    if (typeof google === 'undefined' || !google.accounts) {
      setTimeout(initializeGoogleSignIn, 100);
     
      return;
    }

    google.accounts.id.initialize({
      client_id: "294584378011-s53466qiuig7d30tcqrpjv1ue3ni2gun.apps.googleusercontent.com",
      callback: handlePCCredentialResponse,
      auto_select: false,
      locale: 'fr',
      
    });
    
    google.accounts.id.renderButton(
      document.getElementById("g_id_signin"),
      {
        theme: "outline",
        size: "large",
        type: "standard",
        shape: "rectangular",
        logo_alignment: "left",
        text: "signin_with",
        width: 400,
        locale: 'fr',
      }
    );
    
  }
  document.addEventListener('DOMContentLoaded', initializeGoogleSignIn);
</script>
  <!-- Google tag (gtag.js) -->
  <script  async src="https://www.googletagmanager.com/gtag/js?id=G-LN407DS0B4"></script>
  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
  
    gtag('config', 'G-LN407DS0B4');
  </script>
  <script src="/kukukuwl.js"   type="text/javascript"></script>
 <a href="javascript:void(0);" class="totop" role="button" aria-label="Retour en haut"><img src="/assets/images/totop.png" alt="" /></a>
        <script>
            layui.use(function () {
                var element = layui.element;
                element.tab({
                    headerElem: "#skilldetailsR1s_header>button",
                    bodyElem: "#skilldetailsR1s_body>div",
                });
            });
            function initSkillCloneCopy() {
                $(document)
                    .off("click.skillCloneCopy")
                    .on("click.skillCloneCopy", ".skill_clone .skill_clone_copy", function (e) {
                        e.preventDefault();

                        var $btn = $(this);
                        var $img = $btn.find("img");

                        var text = $.trim($btn.siblings("p").text());

                        var $temp = $("<textarea>");
                        $("body").append($temp);
                        $temp.val(text).select();

                        try {
                            document.execCommand("copy");

                            // 切换成功图标
                            $img.attr("src", "/assets/images/prompt_word2RMs_p_btn_ok.png");
                            $btn.addClass("active");
                            // 清除上一次定时器
                            clearTimeout($btn.data("copyTimer"));

                            // 3秒后恢复原图
                            var timer = setTimeout(function () {
                                $img.attr("src", "/assets/images/prompt_word2RMs_p_btn.png");
                                $btn.removeClass("active");
                            }, 3000);

                            $btn.data("copyTimer", timer);
                        } catch (err) {
                            alert("复制失败");
                        }

                        $temp.remove();
                    });
            }

            function initSkilldetailsFixed() {
                var $box = $(".skilldetailsR1");
                if (!$box.length) {
                    return;
                }
                var fixedTop = 20;
                var topOffset = $box.offset().top;
                var boxHeight = $box.outerHeight();
                var $placeholder = $("<div></div>").height(boxHeight).hide();
                $box.before($placeholder);
                function handleFixed() {
                    if ($(window).width() <= 1024) {
                        $placeholder.hide();
                        $box.css({
                            position: "",
                            top: "",
                            width: "",
                            zIndex: "",
                        });
                        return;
                    }
                    var scrollTop = $(window).scrollTop();
                    if (scrollTop >= topOffset - fixedTop) {
                        $placeholder.show();
                        $box.css({
                            position: "fixed",
                            top: fixedTop + "px",
                            width: $placeholder.width() + "px",
                            zIndex: 100,
                        });
                    } else {
                        $placeholder.hide();
                        $box.css({
                            position: "",
                            top: "",
                            width: "",
                            zIndex: "",
                        });
                    }
                }
                $(window).on("scroll.skilldetailsFixed resize.skilldetailsFixed", handleFixed);
                handleFixed();
            }
            function initSkilldetailsExpand() {
                $(".skilldetailsL_p").each(function () {
                    var $item = $(this);

                    $item.find(".skilldetailsL_p_expand").text($item.hasClass("active") ? "...Développer tout" : "Caché");
                });

                $(document)
                    .off("click.skilldetailsExpand")
                    .on("click.skilldetailsExpand", ".skilldetailsL_p_expand", function (e) {
                        e.preventDefault();

                        var $parent = $(this).closest(".skilldetailsL_p");

                        if ($parent.hasClass("active")) {
                            $parent.removeClass("active");
                            $(this).text("Caché");
                        } else {
                            $parent.addClass("active");
                            $(this).text("...Développer tout");
                        }
                    });
            }

            function checkFollow() {
                let dataSources = [];
                $('button.skill_datas').each(function () {
                    let source = $(this).data('source');
                    if (source) {
                        dataSources.push(String(source).trim());
                    }
                });
                dataSources = [...new Set(dataSources)];
                if (dataSources.length === 0) {
                    return;
                }
                $.post('/api/user/FindSkillFollow', {
                    source: dataSources
                }, function (res) {
                    if (res.code == 1 && res.data.length > 0) {
                        res.data.forEach(function (id) {
                            $('button.skill_datas[data-source="' + id + '"]').addClass('active');
                        });
                    }
                }, 'json');
            }
            $(function () {
                checkFollow();
                initSkillCloneCopy();
                initSkilldetailsFixed();
                initSkilldetailsExpand();
            });
            $(document).on('click', 'button.skill_datas', function (e) {
                e.preventDefault();
                const that = $(this);
                let source = that.data('source');
                if (!source || source === undefined || !CommonUtils.checkLogin()) return false;
                layer.load(2, {
                    shade: [0.3, "#000"],
                    time: 0,
                });
                var path = "/user/followSkill";
                var realPath = CommonUtils.getRealPath(path);
                $.post(realPath, { source: source }, function (result) {
                    layer.closeAll();
                    CommonUtils.showMsg(result.msg, result.code);
                    if (result.code == 1) {
                        var values = result.data.data_source;
                        var count = result.data.count;
                        var collected = result.data.collected;
                        var elements = $(".collectNums_" + values);
                        if (elements.length > 0) {
                            elements.each(function () {
                                $(this).parents('button').toggleClass('active', collected);
                                $(this).text(count);
                            });
                        }
                    }
                })
            })

            $(document).on('click', '.skill_downloadzip', function (e) {
                e.preventDefault();
                const url = $(this).data("source");
                if (!url) return;
                window.open("/api/index/download_zip?source=" + encodeURIComponent(url), "_blank");
            })

        </script>
    </body>

</html>