вариант

plan-orchestrate

affaan-m/ECC affaan-m/ECC

Считывает документ с планом, разбивает его на этапы, формирует цепочку агентов для каждого этапа на основе каталога ECC и генерирует готовые к вставке / оркестрации настраиваемые подсказки, не запуская их.

...Расширить все
9
Обновлено время 4 октября 2026 г.

Планирование и координация

Связывает документ с планом с пользовательской командой /orchestrate, выдавая по одному готовому к вставке вызову на каждый шаг. Этот навык является исключительно генеративным — он никогда не выполняет команду /orchestrate. Пользователь вставляет каждую строку, когда будет готов.

Когда активировать

  • У пользователя есть многоэтапный документ с планом (PRD, RFC, план реализации), и он хочет реализовать его с помощью /orchestrate.
  • Пользователь говорит: «оркестрируй этот план», «дай мне подсказки для /orchestrate по каждому шагу», «составь цепочки для этого плана».
  • Пошаговый план существует, но пользователь не хочет вручную выбирать агентов для каждого шага.

Пропустить, если:

  • Работа представляет собой один разовый шаг → вызовите /orchestrate custom напрямую.
  • План нечитаем или пуст. Отсутствие явной нумерации само по себе не является условием пропуска — см. крайний случай «Отсутствие четких шагов» ниже.

Входные данные

 [--lang=python|typescript|go|rust|cpp|java|kotlin|flutter|auto] [--scope=all|step:|range:-] [--dry-run]
  • — обязательный параметр; относительный или абсолютный путь (допускается формат@docs/... ).
  • --lang — вариант языка рецензента; по умолчанию — auto (определяется по проекту).
  • --scope — ограничивает выводимые шаги; по умолчанию — all.
  • --dry-run — выводить только разбивку на этапы и обоснование цепочки; не выводить итоговые запросы.

Авторитетная форма /orchestrate (не отклоняться)

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

Где {ORCH_CMD} определяется на Фазе 0 (см. ниже). Строка команды в генерируемом выводе всегда использует одну конкретную форму — никогда обе, никогда заменяющий символ.

  • custom представляет собой последовательную цепочку; HANDOFF каждого агента передаёт данные следующему.
  • Список агентов, разделенный запятыми. Предпочтительно без пробелов; допускается один пробел.
  • Флагов --mode / --gate / --agents=... не существует — никогда их не придумывайте.
  • Имена агентов берутся из каталога данного навыка. Встроенные двойные кавычки в описании задачи экранируются как \".

Формат установки ECC и пространство имён

Две формы установки определяют префикс как для команды со слэшем, так и для каждого имени агента. Эти две формы ДОЛЖНЫ оставаться синхронизированными — по одной форме на каждый вывод, смешивать их нельзя:

Пусть обозначим домашний каталог Claude Code: ~/.claude в macOS/Linux, %USERPROFILE%\.claude в Windows. Определяйте его так, как хост-платформа определяет домашний каталог пользователя (не используйте жесткую кодировку ~).

Форма Обнаружение {ORCH_CMD} Формат имени агента
Установка плагина (версия 1.9.0 и выше) Существуеткаталог /plugins/marketplaces/everything-claude-code/ /everything-claude-code:orchestrate everything-claude-code:
Устаревшая базовая установка Вышеуказанное отсутствует; файлы агента находятся в /agents/ /orchestrate

Почему это важно: при установке через плагин агенты регистрируются как everything-claude-code:tdd-guide. Имена без префикса вынуждают систему использовать неточное сопоставление, что при параллельных вызовах периодически приводит к сбоям. В устаревшей версии формы с префиксом не регистрируются и сразу же завершаются сбоем.

Доступный каталог агентов (необходимо выбрать из перечисленных)

Общие:

  • планировщик — переформулировка требований, декомпозиция рисков, планирование этапов
  • architect — архитектура, проектирование системы, предложения по рефакторингу
  • tdd-guide — написание тестов → реализация → покрытие 80%+
  • рецензент кода — общий рецензирование кода
  • рецензент по безопасности — аудит безопасности, OWASP, утечка секретной информации
  • рефакторинг-очиститель — мёртвый код, дубликаты, очистка классов Knip
  • doc-updater — документация, карта кода, README
  • docs-lookup — поиск API сторонних библиотек (Context7)
  • e2e-runner — оркестрация сквозных тестов
  • database-reviewer — схема PostgreSQL, миграция, производительность
  • harness-optimizer — настройка локального агента
  • loop-operator — автономные циклы длительного выполнения
  • chief-of-staff — многоканальная сортировка (редко подходит для этапов плана)

Средства устранения ошибок сборки:

  • build-error-resolver (общий) / cpp-build-resolver / go-build-resolver / java-build-resolver / kotlin-build-resolver / rust-build-resolver / pytorch-build-resolver

Рецензенты кода:

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

Неправильно написанное имя агента приводит к сбою /orchestrate. Перед отправкой сверьте с этим списком.

Как это работает

Этап 0 — Определение режима ECC и языка

  1. Считать . Если отсутствует или пусто, сообщить об этом и остановиться.

  2. Определить форму установки ECC один раз и зафиксировать её в ECC_MODE. Алгоритм (выполнять по порядку, остановиться при первом совпадении):

    1. Если существует /plugins/marketplaces/everything-claude-code/ → ECC_MODE=plugin.
    2. В противном случае, если существует каталог/agents/ и он содержит хотя бы один файл агента ECC (например, tdd-guide.md, code-reviewer.md) → ECC_MODE=legacy.
    3. В противном случае → по умолчанию устанавливается ECC_MODE=legacy и в начале вывода выводится однострочное предупреждение: > Предупреждение: не удалось обнаружить установку ECC; используется форма legacy по умолчанию. Если вы используете установку плагина, отредактируйте префиксы вручную.
    4. Если присутствуют оба маркера (смешанная установка), приоритет имеет плагин — только пространство имён плагина разрешает имена агентов без нестрогого сопоставления.

    С этого момента в каждой выводимой строке используется соответствующий префикс как в команде со слешем, так и в каждом имени агента. Никогда не выводите обе формы в одном выводе.

  3. Определите --lang. При значении «auto» выполните определение с учётом поддержки нескольких языков:

    • Проверка маркеров: pyproject.toml / uv.lock / requirements.txt → python; package.json → typescript; go.mod → go; Cargo.toml → rust; CMakeLists.txt или файлы *.cpp верхнего уровня → cpp; pom.xml / build.gradle (Java) → java; build.gradle.kts или Kotlin верхнего уровня → kotlin; pubspec.yaml → flutter.
    • Разрешение ничьей при наличии нескольких языков: если совпадает более одного маркера, выбирается тот язык, исходных файлов которого больше, чем других (подсчёт производится с помощью команды git ls-files, исключая папки vendor/, node_modules/, dist/, build/, .venv/, сгенерированные файлы и очевидные тестовые фикстуры). В случае равенства или если ни один язык не превышает 60 % исходных файлов, установите lang=unknown.
    • Если ни один маркер не совпал → установите lang=unknown.
    • lang=unknown является индикатором — это не имя агента. Правила 4 и 5 фазы 2 преобразуют его в рецензента кода / решателя ошибок сборки во время формирования цепочки.
  4. Обнаружение подпрофиля PyTorch: если lang=python и в любом из файлов pyproject.toml / requirements.txt / uv.lock заявлена зависимость от torch, установите pytorch=true. Это влияет только на выбор цепочки сборки (правило фазы 2 ниже); рецензентом по-прежнему остаётся python-reviewer.

  5. Нормализовать все имена агентов, объявленные в плане: если в тексте плана агенты упоминаются в форме с префиксом плагина (например, everything-claude-code:tdd-guide), удалите префикс, чтобы получить чистое имя из каталога, прежде чем проверять или составлять цепочки. Повторное добавление префикса происходит только на этапе вывода в соответствии с ECC_MODE (фаза 4). Ни в коем случае не допускайте попадания имени с предварительно добавленным префиксом в состав цепочки — в режиме плагина это приведет к двойному префиксу.

Фаза 1 — Разбиение шагов

Определите «единицы шагов» в порядке приоритета:

  1. Явная нумерация: ## Шаг N / ### Фаза N / ## N. ... / упорядоченный список верхнего уровня.
  2. Колонка «Шаг» в таблице.
  3. ----разделенные блоки с заголовками, начинающимися с глагола.
  4. В противном случае каждый заголовок H2 рассматривается как один шаг.

Для каждого шага извлеките идентификатор (начиная с 1), заголовок (≤ 80 символов), цель (1–3 предложения), теги.

Этап 2 — Теги и цепочка выбора

Помечайте тегами по замыслу (допускается использование нескольких тегов; цепочка формируется из основного тега и наборных вторичных тегов):

При сопоставлении приведенных ниже триггерных слов не учитывается регистр. Поддерживаются многоязычные планы путем сопоставления корней слов на любом языке, при условии что их значение соответствует перечисленным английским триггерным словам.

Теги Ключевые слова Цепочка по умолчанию
дизайн архитектура, дизайн, выбрать, оценить, RFC проектировщик, архитектор
план план, разбивка, этап планировщик
impl реализовать, создать, добавить, разработать, портировать tdd-guide,-рецензент
тест тест, покрытие, e2e, интеграция tdd-guide, e2e-runner
рефакторинг рефакторинг, очистка, удаление дубликатов, разделение архитектор, refactor-cleaner,-reviewer
миграция миграция, обновление, переписывание, портирование архитектор, руководство по TDD,-рецензент
база данных схема, миграция, индекс, SQL, Postgres, alembic, sqlmodel рецензент баз данных,-рецензент
безопасность шифрование, аутентификация, секретные данные, OWASP, персональные данные рецензент по безопасности,-reviewer
сборка сборка, компиляция, ошибка lint, CI -решатель-сборки (переключается на решатель-ошибок-сборки)
документация документация, readme, карта кода, журнал изменений обновление документации
поиск поиск, справочник, использование API поиск-в-документации
review обзор, аудит, проверка -рецензент, рецензент кода
цикл цикл, автономный, сторожевой таймер оператор цикла

Правила составления цепочек:

  1. Выбор основного тега: когда шаг соответствует нескольким тегам, основным считается первый в порядке таблицы (верх таблицы = наивысший приоритет); остальные являются второстепенными. Правила компоновки 2 и 3 ниже явно обрабатывают конкретные комбинации нескольких тегов; в противном случае второстепенные цепочки добавляются в порядке таблицы тегов.
  2. impl + security → tdd-guide,-reviewer,security-reviewer.
  3. impl + db → tdd-guide,database-reviewer,-reviewer.
  4. Удалите дубликаты из полученной цепочки (сохраните первое вхождение). Например, review + lang=unknown даст code-reviewer,code-reviewer после применения правила 5; удаление дубликатов сводит результат к code-reviewer.
  5. -reviewer преобразуется в code-reviewer, если lang=unknown.
  6. -build-resolver преобразуется в build-error-resolver, когда lang=unknown. Особый случай: если на этапе 0 установлено pytorch=true, для цепочек сборки следует использовать pytorch-build-resolver независимо от . Python-build-resolver отсутствует; --lang=python без pytorch=true преобразуется в build-error-resolver.
  7. Шаги с нулевым тегом: если ни одно триггерное слово не совпадает, установите цепочку на code-reviewer и запишите «тег не найден»; по умолчанию используется цепочка «только ревью » в соответствии с «Обоснованием цепочки».
  8. Длина цепочки ≤ 4 после удаления дубликатов. Если превышена, удалите самый слабый тег (сначалапоиск и документация ).
  9. Не объединяйте планировщика и архитектора в цепочке impl (растрата токенов). Объединяйте их только на этапах проектирования.
  10. Шаги с тегами «impl», «refactor» или «migration» заканчиваются агентом класса «reviewer » — любым из следующих: «-reviewer», «code-reviewer», «security-reviewer» или «database-reviewer». Рецензент, наиболее специализированный в данной области, занимает конечную позицию (например, «impl+security» по правилу 2 заканчивается на «security-reviewer»; «impl+db» по правилу 3 заканчивается на «-reviewer», поскольку «database-reviewer» уже контролирует этап «migration» ранее в цепочке). Этапы тестирования и сборки контролируются собственными валидаторами (соответственноe2e-runner и build resolver) и не требуют дополнительного рецензента.

Этап 3 — Сжатие описания задачи

Каждое выданное должно:

  • быть самодостаточным (первому агенту не нужно, чтобы документ с планом был открыт).
  • Начинаться со строки [Plan: #step-].
  • Включать 1–3 проверяемых критерия приемки.
  • Содержать ограничение области действия (Вне области действия: ...) только в том случае, если план объявляет его для данного шага. Перенимать дословно. Если в плане отсутствует заявление о выходе за пределы области действия, полностью опустить это предложение — не придумывать его.
  • Объём — 200–600 символов; одна строка; встроенные символы «» экранируются как \; без буквальных символов новой строки.

Этап 4 — Вывод

Выведите Markdown, используя формат, определяемый ECC_MODE. Вывод использует одну форму на протяжении всего текста — каждый {ORCH_CMD} и каждое имя агента отображаются с соответствующим префиксом из этапа 0. Не выводите обе формы; не включайте инструкции «это форма плагина» / «удалить префикс» в отображаемый вывод.

Конкретные правила отображения:

  • {ORCH_CMD} = /everything-claude-code:orchestrate в версии plugin, /orchestrate в версии legacy.
  • {AGENT(name)} = everything-claude-code: в версии с плагином, в legacy.
  • В столбце «Chain» таблицы обзора используется тот же формат отображения {AGENT(name)}.
  • Блоки bash для каждого шага содержат только исполняемую команду. Комментарии в формате # plugin form или # legacy form отсутствуют — формат подразумевается и является единообразным во всём выводе.

Структура вывода:

# Plan-Orchestrate Результат

**План**: ``
**Язык**: ``
**Режим ECC**: ``
**Шаги**: 
**Область действия**: 

## Обзор шагов

| # | Название | Теги | Цепочка |
|---|---|---|---|
| 1 | ... | impl, db | `{AGENT(tdd-guide)},{AGENT(database-reviewer)},{AGENT(python-reviewer)}` |
| ... | | | |

---

## Шаг 1 — 

**Цель**: <1–3 sentences>
**Теги**: <a, b>
**Обоснование цепочки**: <why this chain; which agent closes the loop>

```bash
{ORCH_CMD} custom "{AGENT(tdd-guide)},{AGENT(database-reviewer)},{AGENT(python-reviewer)}" "[План: docs/foo.md#step-1] <compressed task description>; Приемка: <1–3 items>; Вне рамок: <…>"
```
</code></pre>
<blockquote>
<p>Приведённые выше обозначения <code>{ORCH_CMD}</code> и <code>{AGENT(...)}</code> описывают подстановку, которую данный навык выполняет во время выполнения. Фактически выводимый Markdown содержит разрешённые строки, а не заполнители.</p>
</blockquote>
<p>Добавьте заключительный блок «Пакетное выполнение», агрегирующий команды каждого шага в порядке, чтобы пользователь мог вставить их все сразу. <strong>Пропустите блок «Пакетное выполнение» в режиме «Только обзор»</strong> (см. крайний случай «Большой план»): когда выводится только таблица обзора, нет команд по шагам, которые нужно агрегировать.</p>
<h3>Фаза 5 — Самопроверка (запускается перед выводом)</h3>
<ul>
<li><input disabled="" type="checkbox"> Каждый агент в каждой цепочке берется из каталога (после удаления префикса <code>everything-claude-code:</code>, который появился в плане; см. этап 0, шаг 5).</li>
<li><input disabled="" type="checkbox"> Разрешённые <code>{ORCH_CMD}</code> и все разрешённые <code>{AGENT(...)}</code> используют <strong>одну и ту же</strong> форму (<code>плагин</code> или <code>устаревшую</code>) — они никогда не смешиваются в одном выводе.</li>
<li><input disabled="" type="checkbox"> В сгенерированном выводе не остаётся ни аннотаций <code># plugin form</code> / <code># legacy form</code>, ни инструкций по «удалению префикса».</li>
<li><input disabled="" type="checkbox"> Нет вымышленных полей <code>--mode</code> / <code>--gate</code> / <code>--agents=...</code> </li>
<li><input disabled="" type="checkbox"> Описание каждой задачи занимает одну строку, заключено в двойные кавычки, а встроенные символы <code> «»</code> экранированы.</li>
<li><input disabled="" type="checkbox"> Каждое описание задачи начинается с <code>[Plan: <path>#step-<id>]</code> и включает в себя критерии приемки (1–3 пункта). Условие <code>«Вне области применения:»</code> присутствует только в том случае, если оно унаследовано из плана.</li>
<li><input disabled="" type="checkbox"> Отсутствие дубликатов агентов в любой цепочке после дедупликации на этапе 2.</li>
<li><input disabled="" type="checkbox"> Длина цепочки ≤ 4.</li>
<li><input disabled="" type="checkbox"> Шаги с тегами<code>impl/refactor/migration</code> заканчиваются агентом класса рецензента (<code><lang>-reviewer</code>, <code>code-reviewer</code>, <code>security-reviewer</code> или <code>database-reviewer</code>). <code>test</code> и <code>build</code> исключаются — см. правило 10 фазы 2.</li>
<li><input disabled="" type="checkbox"> Шаги с тегом «zero» генерируют <code>агент «code-reviewer»</code> с обоснованием <code>«no tag matched»; по умолчанию используется цепочка «review-only</code>».</li>
<li><input disabled="" type="checkbox"> В таблице обзора перечислены все шаги плана, независимо от <code> параметра --scope</code>.</li>
<li><input disabled="" type="checkbox"> Количество блоков с подробностями для каждого шага соответствует заданному параметру <code>--scope</code> (полный план при <code>--scope=all</code>; один блок для <code>шага:n</code>; размер диапазона для <code>range:a-b</code>). В режиме «только обзор» блоки для отдельных шагов и блок Batch не выдаются.</li>
</ul>
<h2>Крайние случаи</h2>
<ul>
<li><strong>Отсутствие чётких шагов</strong>: отдавайте предпочтение разделению на H2/H3; если неоднозначность сохраняется, выдавайте сообщение «не обнаружено структурированных шагов» вместе с оглавлением документа и просите пользователя подтвердить запуск по оглавлению.</li>
<li><strong>Большой план (>1500 строк)</strong>: перейти <strong>в режим «только обзор»</strong> — вывести только таблицу обзора и попросить пользователя сузить область с помощью <code>--scope</code> перед повторным запуском для получения деталей. В этом режиме пропускаются блоки с подробностями по каждому шагу и блок пакетного выполнения.</li>
<li><strong>Шаг слишком обширен</strong> (например, «завершить всю работу бэкенда»): не навязывать единую цепочку. Предложить разбиение на N.a и N.b и предложить вариант разбиения.</li>
<li><strong>План объявляет агентов</strong> (редко): сначала <strong>удалите любой префикс <code>everything-claude-code:,</code></strong> чтобы получить чистое имя каталога (фаза 0, шаг 5), затем проверьте его соответствие каталогу. Замените недопустимые агенты и объясните причину в разделе «Обоснование цепочки». Чистое имя снова получает префикс при выводе в соответствии с <code>ECC_MODE</code>.</li>
<li><strong>В многоязычном проекте, где <code> параметр `--lang=auto`</code> не может выбрать победителя</strong>: установите <code>`lang=unknown`</code>; рецензент преобразуется в <code>`code-reviewer`</code>, а резолвер сборки — в <code>`build-error-resolver`</code>. Укажите резервный вариант в разделе «Обоснование цепочки».</li>
</ul>
<h2>Примеры</h2>
<h3>Пример 1 — Режим плагина, план на Python</h3>
<p>Входные данные:</p>
<pre><code>plan-orchestrate @docs/plan/example-feature.md --lang=python
</code></pre>
<p>Фрагмент ожидаемого вывода:</p>
<pre><code class="language-markdown">## Шаг 2 — Шифрование конфиденциальных полей UserProfile

**Цель**: Ввести тип `EncryptedString` в SQLAlchemy и зашифровать `birth_datetime` / `location` с помощью AES-GCM перед сохранением в базу данных; загрузить ключ из переменной среды.
**Теги**: impl, security, db
**Обоснование цепочки**: Путь записи, чувствительный к вопросам безопасности, поэтому цепочку закрывает `security-reviewer`; `database-reviewer` проверяет миграцию Alembic; `python-reviewer` проверяет типизацию и соответствие 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" «[План: docs/plan/example-feature.md#step-2] Реализовать тип EncryptedString в SQLAlchemy и выполнить миграцию столбцов UserProfile.birth_datetime/location; ключ из ENV APP_DB_KEY; Приемка: успешное прохождение тестов шифрования/дешифрования в обоих направлениях; чистая работа Alembic при обновлении/понижении версии на пустой БД; отсутствие открытого текста в БД после миграции; Вне рамок: логика совместного использования профилей между арендаторами"
```
</code></pre>
<h3>Пример 2 — Устаревший режим, тот же шаг</h3>
<p>Если бы был обнаружен <code>ECC_MODE=legacy</code>, тот же шаг был бы сгенерирован в виде одной единой команды (без форм с префиксами плагинов в выводе):</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>Два приведенных выше примера иллюстрируют <strong>два возможных варианта вывода</strong> для двух разных сред. Один вызов навыка генерирует только один из них, от начала до конца.</p>
<h2>Примечания</h2>
<ul>
<li>Только для генерации. Никогда не вызывайте <code>/orchestrate</code> изнутри этого навыка.</li>
<li>Используйте тот же язык, что и в документе плана, для описания задач (имена агентов всегда остаются на английском языке).</li>
<li>Не вставляйте в вывод строки «Co-Authored-By» или эмодзи, если пользователь явно не попросит об этом.</li>
</ul>                                </div>
                                <div class="skilldetailsL1_skillmd">
                                    <a href="https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate" title="Посмотреть на GitHub" target="_blank" rel="nofollow"
                                        aria-label="Посмотреть на GitHub" class="skilldetails_toGitHub">
                                        <span>Посмотреть на 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>Все файлы</h2>
                                <span>1 файлов</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="Просмотр" target="_blank" aria-label="Просмотр"
                                    rel="nofollow">Просмотр</a>
                            </div>
                                                    </div>
                    </div>
                    <div class="skilldetailsR">
                        <div class="skilldetailsR1">
                            <div class="skilldetailsR1s">
                                <h2>Установить plan-orchestrate</h2>
                                <div class="skilldetailsR1s_header" id="skilldetailsR1s_header">
                                    <button class="layui-this">
                                        <b></b>
                                        <span>Скачать 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>Скачайте файлы навыков и распакуйте их в каталог .claude/skills/.</p>
                                        <a href="javascript:;" title="Скачать ZIP" data-source="TeeN26C1ni2ZDZRkOJVh9w"
                                            aria-label="Скачать ZIP" role="button" class="skill_downloadzip">
                                            <b></b>
                                            <span>Скачать ZIP</span>
                                        </a>
                                    </div>
                                    <div class="skilldetailsR1s_body2">
                                        <p>Клонируйте репозиторий и скопируйте файлы навыка в свой проект.</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="Копировать" role="button" aria-label="Копировать"
                                                class="skill_clone_copy">
                                                <img src="/assets/images/prompt_word2RMs_p_btn.png"
                                                    alt="Копировать" />
                                                <span>Копировать</span>
                                            </a>
                                        </div>
                                    </div>
                                </div>
                                <div class="skilldetailsR1s_info">
                                    <span>Быстрая настройка: </span>
                                    Скопируйте папку со скиллом в каталог .claude/skills/
Claude автоматически обнаружит и запустит этот скилл                                </div>
                                <div class="skilldetailsR1s_repository">
                                    <span>Репозиторий</span>
                                    <a href="https://github.com/affaan-m/ECC/tree/main/skills/plan-orchestrate" title="affaan-m/ECC" target="_blank"
                                        aria-label="Репозиторий" rel="nofollow">affaan-m/ECC</a>
                                </div>
                            </div>
                        </div>
                        <div class="skilldetailsR2">
                            <h2>Похожие навыки</h2>
                            <div>
                                                                <div class="skilldetailsR2s">
                                    <a href="/ru/skill/detail/airtableautomation.html" title="airtable-automation" aria-label="airtable-automation">airtable-automation</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Обновлено время                                                29 июня 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="/ru/skill/detail/notionautomation.html" title="notion-automation" aria-label="notion-automation">notion-automation</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Обновлено время                                                29 июня 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="/ru/skill/detail/seoprogrammatic.html" title="seo-programmatic" aria-label="seo-programmatic">seo-programmatic</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Обновлено время                                                29 июня 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="/ru/skill/detail/revops.html" title="revops" aria-label="revops">revops</a>
                                    <div>
                                        <div class="skilldetailsR2s_time">
                                            <b></b>
                                            <span>Обновлено время                                                29 июня 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">Горячие инструменты ИИ</span>
        <div class="footer11info">
                    <a href="/ru/tool/ai-clothes-remover.html" aria-label="AI Clothes Remover" class="footer11s">AI Clothes Remover</a>
                    <a href="/ru/tool/deepnude-generator.html" aria-label="DeepNude generator" class="footer11s">DeepNude generator</a>
                    <a href="/ru/tool/purechat.html" aria-label="PureChat" class="footer11s">PureChat</a>
                  </div>
      </div>
      <div class="footer12">
        <span class="footer11_title">ИИ инструменты с потенциалом</span>
        <div class="footer11info">
                    <a href="/ru/tool/idea-box-ai-tool.html" aria-label="Name Idea Box" class="footer11s">Name Idea Box</a>
                    <a href="/ru/tool/qi-jing-ai-ai-tool.html" aria-label="奇境 AI" class="footer11s">奇境 AI</a>
                    <a href="/ru/tool/ezaudio-ai-tool.html" aria-label="EZAudio" class="footer11s">EZAudio</a>
                  </div>
      </div>
      <div class="footer13">
        <span class="footer11_title">ЧИТАТЬ ДАЛЕЕ</span>
        <div class="footer11info">
                    <a href="/ru/ainews/ai-hosts-notebooklm-podcast-interviews.html" aria-label="AI Hosts of Notebooklm подкаста теперь доступны для интервью" class="footer11s">AI Hosts of Notebooklm подкаста теперь доступны для интервью</a>
                    <a href="/ru/ainews/corporate-ai-adoption-leveling-ramp-data.html" aria-label="По данным Ramp, корпоративное внедрение ИИ находится на плаву" class="footer11s">По данным Ramp, корпоративное внедрение ИИ находится на плаву</a>
                    <a href="/ru/ainews/microsoft-unveils-businessfocused-copilot-surface-devices-powered-intel.html" aria-label="Microsoft представляет ориентированные на бизнес Copilot+ Surface Devices, оснащенные Intel" class="footer11s">Microsoft представляет ориентированные на бизнес Copilot+ Surface Devices, оснащенные Intel</a>
                  </div>
      </div>
      <div class="footer4">
        <span class="footer11_title">Следовать</span>
        <div class="footer11info">
          <a href="javascript:;" class="footer11s">Связаться с нами</a>
          <a href="mailto:admin@xix.ai" role="button" aria-label="Связаться с нами" 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>
          При нажатии на «Принять все файлы cookie» вы соглашаетесь на хранение файлов cookie на вашем устройстве для улучшения навигации по сайту, анализа использования сайта и поддержки наших маркетинговых усилий.<span>Политика конфиденциальности</span> Уведомление        </p>
        <div class="cokiesetRight">
          <a href="javascript:;" class="cokieA ai_cookie_open"  role="button" aria-label="Настройки файлов cookie">Настройки файлов cookie</a>
          <a href="javascript:;" class="cokieA RefuseCookies" role="button" aria-label="Отклонить все">Отклонить все</a>
          <a href="javascript:;" class="cokieA cokieAall" role="button" aria-label="Принять все файлы cookie">Принять все файлы cookie</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">Настройки конфиденциальности</p>
          <p class="cokielaydDesc">
            При посещении любого веб-сайта он может хранить или получать информацию в вашем браузере, главным образом в виде файлов cookie. Эта информация может относиться к вам, вашим предпочтениям или вашему устройству и в основном используется для того, чтобы сайт работал так, как вы ожидаете. Эта информация обычно не идентифицирует вас напрямую, но может предоставить вам более персонализированный веб-опыт. Поскольку мы уважаем ваше право на конфиденциальность, вы можете отказаться от разрешения определенных типов файлов cookie. Нажмите на разные заголовки категорий, чтобы узнать больше и изменить наши параметры по умолчанию. Однако блокировка некоторых типов файлов cookie может повлиять на ваше восприятие сайта и предоставляемые нами услуги. <a href="#" title="Политика конфиденциальности" aria-label="Политика конфиденциальности"><span>Политика конфиденциальности</span></a> <b>Заявление</b>          </p>

          <div class="cokielayDivdown">
            <p class="coklaydownP">Управление предпочтениями</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</p>
                  </div>
                  <p class="ckdlipr">Всегда активен</p>
                </div>
                <p class="ckdDowns">
                  Эти файлы cookie необходимы для работы веб-сайта и не могут быть отключены в наших системах. Обычно они устанавливаются только в ответ на ваши действия, которые являются запросом на предоставление услуг, например, настройка предпочтений конфиденциальности, вход в систему или заполнение форм. Вы можете настроить браузер на блокировку этих файлов cookie или оповещение о них, но тогда некоторые части сайта не будут работать. Эти файлы cookie не хранят никакой персональной информации, позволяющей идентифицировать вас.                </p>
              </li>
            </ul>
          </div>
        </div>
        <div class="cklyBtn">
          <a href="javascript:;" role="button" aria-label="Принять все файлы cookie" class="active cokieAall">Принять все файлы cookie</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="Войти" aria-selected="true" class="login_tab_top1a ">Войти</a>
        <a href="javascript:;" role="tab" aria-label="Зарегистрироваться" aria-selected="false" class="login_tab_top2a">Зарегистрироваться</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="Электронная почта">
            <input type="text" placeholder="Пожалуйста, заполните свой адрес электронной почты" class="login_forms_email">
            <span></span>
          </div>
          <div class="login_forms">
            <img src="/assets/images/login_password.png" alt="Пароль">
            <input type="password" placeholder="Пожалуйста, введите свой пароль" 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="Пожалуйста, введите код графической проверки"
              class="login_forms_captcha">
            <img src="" alt="Пожалуйста, введите код графической проверки" class="login-js-refresh-captcha">
            <span></span>
          </div>
          <div class="login_forms_bottom">
            <label class="login_remember">
              <input type="checkbox" aria-label="Запомнить меня">
              <span>Запомнить меня</span>
            </label>
            <a href="/ru/account/forgetPassword.html" aria-label="Изменить пароль" class="login_forget">Забыли пароль</a>
          </div>
          <a href="javascript:;" type="button" role="button" aria-label="Войти" id="login_button" class="login_button">Войти</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="Электронная почта">
            <input type="text" placeholder="Пожалуйста, заполните свой адрес электронной почты" class="register_forms_email">
            <span></span>
          </div>
          <div class="login_forms">
            <img src="/assets/images/login_password.png" alt="Пароль">
            <input type="password" placeholder="Пожалуйста, введите свой пароль" 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="Пожалуйста, введите код графической проверки"
              class="register_forms_captcha">
            <img src="" alt="Пожалуйста, введите код графической проверки" class="register-js-refresh-captcha" id="register_captcha">
            <span></span>
          </div>
          <div class="login_forms">
            <input type="text" class="verify-code-input" placeholder="Пожалуйста, введите код проверки">
            <button id="verifyCodeBtn" class="verify-code-btn" data-text="Получить код проверки">Получить код проверки</button>
            <span></span>
          </div>
          <a href="javascript:;" role="button" aria-label="Зарегистрироваться" class="login_button" id="register_button">Зарегистрироваться</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: "Формат электронной почты неверен",
        password: {
          empty: "Пожалуйста, введите свой пароль",
          invalid: "Пароль должен быть 6-18 символов и содержать как буквы, так и цифры"
        },
        captcha: "Пожалуйста, введите код графической проверки",
        verifyCode: "Пожалуйста, введите код проверки",
        operationInProgress: "Операция в процессе, пожалуйста, подождите",
        unexpectedError: "Произошла неожиданная ошибка"
      },
      urls: {
        login: "/ru/account/dologin.html",
        register: "/ru/account/register.html",
        getMailSign: "/ru/account/getMailSign",
        sendMail: "/ru/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: 'ru',
      
    });
    
    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: 'ru',
      }
    );
    
  }
  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="Вернуться к вершине"><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") ? "...Расширить все" : "Скрытый");
                });

                $(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("Скрытый");
                        } else {
                            $parent.addClass("active");
                            $(this).text("...Расширить все");
                        }
                    });
            }

            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>