Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Extract To Extension

ASecurity

Перенос уже существующей доработки из типового объекта основной конфигурации в расширение с возвратом типового объекта к коду поставщика. Используй, когда просят «вынести доработки в расширение», «перенести правку из типового модуля в расширение», «вернуть модуль к состоянию поставщика», «убрать доработки из основной конфигурации», «разобрать дифф с эталоном поставщика и вынести найденное». Не применяй для оформления новой доработки — как писать директивы, маркеры и перехватчики, знает config...

12 stars
0 votes
0 copies
0 views
Added 9/28/2026
ai-agentspythonbashcode-reviewgit

Works with

mcp

Security Analysis

A100/100

Scanned 9/28/2026

Install to Claude Code

$npx -y skills add mr-ske1r/1c-ai-devstart --skill extract-to-extension --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Extract To Extension?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Extract To Extension
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mr-ske1r-extract-to-extension/badge)](https://www.skillsdirectory.com/skills/mr-ske1r-extract-to-extension)

More formats (shields.io, HTML) on the badges page.

Files
SKILL.md
---
name: extract-to-extension
description: "Перенос уже существующей доработки из типового объекта основной конфигурации в расширение с возвратом типового объекта к коду поставщика. Используй, когда просят «вынести доработки в расширение», «перенести правку из типового модуля в расширение», «вернуть модуль к состоянию поставщика», «убрать доработки из основной конфигурации», «разобрать дифф с эталоном поставщика и вынести найденное». Не применяй для оформления новой доработки — как писать директивы, маркеры и перехватчики, знает config-modification."
argument-hint: <путь или имя объекта> [чем считать эталон, куда выносить, как выносить]
---

# Вынос доработки в расширение

> Нормы кода — в `.claude/rules/1c-rules.md`. Как оформлять директивы, маркеры и перехватчики —
> в скилле `config-modification`. Здесь — порядок самой операции переноса.

Задача: доработка уже живёт в типовом объекте. Надо понять, зачем она нужна, выразить её
в расширении — там же, где она лежала, или в более устойчивой точке — и вернуть типовой объект
к коду поставщика.

## Что пришло на вход

Первое — объект: путь к файлу или папке либо имя объекта словами. Остальное — свободный текст:
путь к эталону поставщика, целевое расширение, готовый diff, указание способа выноса, формат
старых маркеров.

- **Свободный текст сильнее умолчаний скилла.** Сказано «через `&Вместо`» — делай так,
  а несогласие выскажи в плане, а не молча по-своему.
- **Объект не назван вообще** — спроси, какой объект разбираем, и не начинай работу до ответа.
  Не выбирай кандидата сам и не разбирай конфигурацию целиком в поисках доработок.

## Железные правила

1. **Границы доработки определяет скрипт, а не чтение модуля.** Типовой модуль может быть на
   тысячи строк; читать его целиком ради трёх изменённых строк — не делать работу, а жечь контекст.
2. **Сначала план, потом файлы.** Ни одного изменения до одобрения пользователем.
3. **Каждый хирург объяснён до переноса.** Одно-два предложения о том, что должно происходить
   и при каком условии, а не пересказ изменённых строк. Не понял — не переносишь, а спрашиваешь.
4. **Догадка не становится фактом молча.** Номер задачи, автор, дата, назначение удалённого
   кода — если этого нет в явном виде, спроси.

## Шаг 1. Границы доработки

```bash
python .claude/skills/extract-to-extension/scripts/extract-diff.py <путь> [--vendor-root <эталон>] [--work-root <рабочая>] [--no-body]
```

На входе — **папка объекта** (документа, справочника, отчёта) или отдельный файл. Эталон
находится по зеркальному пути `src/cf` → `src/cf_vendor`; если корни называются иначе, задай
`--vendor-root` и `--work-root`, для одиночного файла — `--vendor`.

Пользователь называет объект по-человечески («форма документа ЗаказПоставщику»), а скрипту
нужен путь. Найди папку сам (`Glob` по имени объекта) и бери **папку объекта целиком**, а не
папку одной формы: так в разбор попадут и модули объекта, и все формы, и описания. Если объектов
с похожим именем несколько, покажи найденное и уточни.

Что печатает:

- **BSL** — правки с типом (вставка / замена / чистое удаление / новый метод) и охватывающей
  процедурой. Одинаковая замена в нескольких местах сворачивается в **одну правку**:
  переименование реквизита в восьми процедурах — это одна правка, а не восемь. Доработка это
  или порча типового — решаешь ты на шаге 2, скрипт такого вывода не делает.
  Правки, где изменилось только форматирование, помечены отдельно — переносить их нечего.
- **XML** — смысловая сводка: добавленные, удалённые, переименованные и перемещённые элементы,
  изменённые свойства. Длинные значения (запрос динамического списка, схема СКД) показываются
  текстовым диффом. Сырой XML читать не нужно.

- **Файлы без пары** — два отдельных раздела. «Есть только в рабочей» — новый файл или неполный
  эталон. «Есть у эталона и нет в рабочей» — файл удалён из основной конфигурации. И то и другое —
  полноценные расхождения: пока они не разобраны, объект совпавшим с эталоном не считается.
- **Имя и версия конфигурации** с обеих сторон. Не совпали — скрипт предупреждает, и это стоп:
  в дифф попали ещё и изменения поставщика между релизами, а выглядят они как локальные правки.
  Границы доработки по такому диффу недостоверны — выясни у пользователя, тот ли эталон,
  прежде чем разбирать.

Коды возврата: `0` — объект совпадает с эталоном, `1` — расхождения есть, `2` — скрипт **отказался
работать** (эталон не найден, объект не найден, откат невозможен). Двойка не значит «расхождения
остались», она значит «работа не сделана» — не пересказывай её пользователю как результат разбора.

Скрипт заканчивает сводку по каждому XML-файлу строкой «Учтено расхождений: N». Если он не смог
что-то классифицировать, он печатает это явно — молча ничего не теряет. Строка с нулём при видимых
правках означает ошибку скрипта, а не отсутствие доработок.

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

**Модуль целиком читай только тогда, когда без окружающего кода правку не понять** — и тогда
читай нужную процедуру, а не файл.

Скрипту нужен Python 3. Если его нет, скажи об этом пользователю: без него границы придётся
получать вручную через `diff`, и разбор XML станет недоступен.

## Шаг 2. Отделить доработки от шума, затем осмыслить

Скрипт даёт расхождения, но не решает за тебя, что из них доработка. Раздели на четыре кучи:

- **Шум** — скрипт помечает его сам четырьмя классами: «только форматирование», «только
  комментарии», «код не изменён, обёртка маркерами» (кто-то отметил маркерами код вендора,
  ничего не поменяв) и перестановки. В расширение не переносится, при возврате к эталону
  исчезает сам. Если у смысловой правки указано «строк только с переотступом: N» — эти строки
  тоже шум внутри настоящей правки, в перехватчик их не тащи.
- **Следствие** — узлы, появившиеся из-за другой правки. Пример: изменили запрос динамического
  списка — платформа дописала десятки полей в схему набора данных. Переносится вместе с
  причиной и отдельной доработкой не считается.
- **Невоспроизводимо в расширении** — правка, которой в расширении нет средства выразить:
  переименование или удаление типового реквизита формы, изменение имени типового объекта.
  Это не доработка и не шум, а порча типового. Переносить нечего — только возврат к вендору.
  Обязательно скажи пользователю, что правку откатываешь, и спроси, была ли она осознанной:
  если за ней стояла цель, её придётся формулировать заново и решать другим способом.
- **Доработка** — то, что меняет поведение и воспроизводимо в расширении. Только это идёт в план.

«Хирургов N» и «смысловых правок M» — разные числа, и это нормально.

**Итог разбора может быть «переносить нечего».** Это нормальный исход, а не признак того, что
ты плохо искал: бывает, что все расхождения оказались шумом и порчей типового. Тогда план
состоит из возврата к вендору и списка вопросов, шаги 2а, 3 и 3а по директивам пропускаются,
а пункты чек-листа про директивы и области отмечаются как неприменимые.

Отдельно проверяй добавленные реквизиты. Скрипт печатает «ссылок в других файлах объекта» —
это ссылки **только внутри папки объекта**. Общие модули, запросы, СКД, подписки, обмены, роли
и другие расширения в счёт не входят, динамическое обращение по имени не найдётся вообще.
Поэтому ноль там означает «локальных ссылок не нашлось», а не «реквизит мёртвый». Полный обход
зависимостей — норма «до правки перечисли, что ещё она затрагивает» в `1c-rules.md`
(### Архитектура).

**Реквизит может хранить данные — это отдельный стоп-вопрос, а не деталь.** Реквизит, заведённый
в расширении заново, — другая сущность хранения: накопленные значения в него не переезжают.
А удаление реквизита из основной конфигурации удаляет и его данные. Поэтому до переноса и до
возврата к вендору спроси пользователя, заполнен ли реквизит и нужны ли эти значения, и вынеси
ответ в план отдельным пунктом. Заполненность проверяется запросом к базе по протоколу `mcp.md`,
а не чтением исходников. Пока ответа нет — реквизит не переносится и не удаляется.

Дальше по каждой доработке восстанови намерение. Намерение — проверяемое утверждение о поведении
и об условии, при котором оно нужно («не проводить документ, если у контрагента просрочен
договор»), а не пересказ строк («добавлена строка `Отказ = Истина`»). Пересказ намерением
не является: по нему нельзя решить, годится ли другая точка встраивания.

Где искать, пока утверждение не стало проверяемым: маркеры доработки и номер задачи рядом
с правкой; данные и имена, к которым правка обращается, — реквизит, регистр, константа часто
называют цель; вызываемые методы (поиск по имени по приоритету источников из `.claude/rules/mcp.md`), а не весь модуль.

**Намерение не восстановилось — это открытый вопрос, а не догадка.** Спроси пользователя,
а до ответа переноси правку как есть: без намерения точку встраивания менять нельзя — нечем
проверить, что поведение осталось прежним.

Отдельно проверь, не переносишь ли лишнее: доработка могла вызывать метод, который в расширении
уже есть. Перед тем как копировать логику, поищи готовое в модулях расширения.

## Шаг 2а. Можно ли не копировать тело вендора

Доработка лежит там, где её когда-то было проще всего вписать. Это не значит, что в расширении
её надо воспроизводить в том же месте.

Шаг выполняется, только если сработал хотя бы один признак:

- правка сидит в середине типового метода;
- одна и та же доработка размазана по нескольким местам или методам;
- по таблице шага 3 напрашивается `&ИзменениеИКонтроль` или `&Вместо` без `ПродолжитьВызов()`.

Ни один не сработал — скажи это одной строкой и иди на шаг 3. Вставка в начало или конец метода
копию тела и так не тащит, искать лучше нечего.

Сработал — ищи точку по разделу «Паттерн: выбор точки встраивания» в `config-modification`.
Дальше развилка, и она жёсткая:

- **Момент исполнения сохраняется** — правка переезжает в вызывающий метод или в переопределяемый
  метод, который вендор вызывает из того же места. Решаешь сам; в плане показываешь строкой,
  что перехватываешь вместо чего и почему это дешевле.
- **Момент исполнения меняется** — другое событие, другая транзакция, другой порядок вызова.
  Сам не решаешь: вариант идёт в открытые вопросы шага 4 вместе с ценой обоих путей. Пока ответа
  нет, в плане стоит перенос как есть.

Причина развилки не в осторожности. Доказать, что поведение не изменилось, можно только разбором
доступных данных, состояния объекта, границ транзакции и порядка вызова; вывод «эквивалентно»
без такого разбора — правдоподобная догадка, а её цена — тихо изменившаяся логика в бою.

Сменил точку — два действия, которые легко забыть:

- **Перехватчики других расширений ищутся по новой точке.** Проверка шага 3а, сделанная
  по исходному методу, для нового метода ничего не значит.
- **Новый метод может лежать в другом объекте или модуле**, не заимствованном в расширение.
  Это шаг 8 и таблица полномочий `CLAUDE.md`, а не деталь реализации.

## Шаг 3. Выбор механизма и типа вызова под тип хирурга

Сначала механизм, потом тип вызова — это два разных решения.

**Механизм.** Правка сидит в обработчике события формы или её элемента — берёшь привязку
к событию, а не директиву. Правка в обычном методе (модуль объекта, общий модуль, служебный
метод модуля формы) — директиву. Норма выбора и устройство обеих записей — в `1c-rules.md`
(### Архитектура) и `config-modification` («Паттерн: перехват события формы»).

Понять, что перед тобой обработчик события формы, можно по `Form.xml` типового объекта: имя
процедуры стоит в секции `<Events>`. Если стоит — механизм событийный, даже когда правка
выглядит как обычная вставка в тело.

**Тип вызова.** Норма выбора — в `1c-rules.md`: правка выражается обёрткой — берётся обёртка
(`&Перед`/`&После` для процедуры, `&Вместо` с `ПродолжитьВызов()` для функции); копия типового тела
через `&ИзменениеИКонтроль` берётся только когда хирург сидит в середине метода. Внутри этого
бери **первый вариант, который честно выражает хирург**. «Перед», «После» и «Вместо» есть в обоих
механизмах, `&ИзменениеИКонтроль` — только у директив.

| Тип хирурга | Обычно | Почему не вариант выше |
|---|---|---|
| Вставка в начало или конец метода (процедура) | `&Перед` / `&После` | — |
| Вставка в начало/конец функции, включая перед `Возврат` | `&Вместо` + `ПродолжитьВызов()` | `&Перед`/`&После` к функциям неприменимы — платформа не даёт доступа к результату через них (`1c-rules.md`, ### Архитектура); `&ИзменениеИКонтроль` здесь дороже — потащит копию тела ради обёртки |
| Вставка в середину, между типовыми операторами | `&ИзменениеИКонтроль` + `#Вставка` | `&Перед`/`&После` не выражают позицию |
| Замена типового фрагмента | `&ИзменениеИКонтроль` + `#Удаление` и `#Вставка` | пересчёт в `&После` молча перетирает результат вендора и не даёт контроля при обновлении |
| Чистое удаление типового кода | `&ИзменениеИКонтроль` + `#Удаление` | подавить фрагмент иначе нельзя |
| Новый метод | обычный метод расширения | не перехват |
| Метод заменён целиком, типовой выполняться не должен | `&Вместо` без `ПродолжитьВызов()` | крайний случай, обоснуй отдельно; если тело копируется и правится — это не замещение, а `&ИзменениеИКонтроль`, см. `config-modification` |
| Правка в обработчике события формы или элемента | привязка к событию, тип по норме выбора | директива к назначаемому обработчику не цепляется |
| Вставка в середину типового обработчика события | `&ИзменениеИКонтроль` | событие даёт только «до», «после» и «вместо целиком» — середины у него нет |

Проверка для «замены»: если типовое значение читается дальше по методу, `&После` даст другой
результат, чем оригинал. Тогда обёртка задачу не выражает — правка сидит в середине, и берётся
`&ИзменениеИКонтроль`. `&Вместо` с `ПродолжитьВызов()` здесь не помощник: он оборачивает метод
снаружи и до середины не достаёт.

Взвешивай цену: `&ИзменениеИКонтроль` тянет в расширение копию всего метода. Для правки одной
строки в методе на две сотни строк это дорого — копия живёт своей жизнью и требует перепроверки
при каждом обновлении. Если типовое значение дальше по методу не читается и условия входа
воспроизводимы, `&После` может оказаться дешевле. Решение обоснуй в плане, а не выбирай молча:
у `&После` своя цена — платформа не предупредит, когда вендор изменит перекрытую логику.

У функции `&После` недоступен независимо от цены, и сравнение идёт иначе: обёртку выражает
`&Вместо` с `ПродолжитьВызов()`, копию тела — `&ИзменениеИКонтроль`. Хирург в начале или конце
функции — обёртка дешевле, берётся она; `&ИзменениеИКонтроль` остаётся для середины.

## Шаг 3а. Ревизия приёмника — обязательна до возврата к вендору

```bash
python .claude/skills/extract-to-extension/scripts/extract-diff.py --review-extension <каталог расширения> --vendor-root <эталон> --work-root <рабочая>
```

Форма расширения хранит две части: собственную версию и `BaseForm` — состояние, поверх которого
эта версия построена. Ревизия отвечает на два вопроса по каждой форме.

**Что расширение добавляет от себя** — разница «собственная часть минус `BaseForm`». Это его
реальные правки: добавленные реквизиты, элементы, обработчики.

**Не испорчена ли база** — есть ли в `BaseForm` элементы, которых нет у вендора. Если есть,
форму заимствовали, когда основная конфигурация уже была доработана, и снимок вобрал чужие
правки. Тогда после возврата основной конфигурации к вендору платформа предложит обновить
заимствованную форму.

**Проверено на живой базе: при таком обновлении собственные реквизиты формы расширения
теряются.** Поэтому порядок жёсткий:

1. Сначала ревизия — снять список собственных изменений расширения.
2. Записать этот список в план как то, что придётся восстановить.
3. Только потом возврат основной конфигурации к вендору и обновление формы в Конфигураторе.
4. После обновления — повторная ревизия: сверить, что из списка уцелело, а что восстанавливать.

Если у формы нет собственных изменений (её версия совпадает с `BaseForm`), её проще убрать
из расширения, чем чинить.

Ревизия читает только формы. Перехватчики в модулях расширения ищи сам — норма «до правки
перечисли перехватчики расширений над тем же методом» в `1c-rules.md` (### Архитектура)
и пункт общего чек-листа. Практически это один поиск по каталогам расширений — по приоритету
источников из `.claude/rules/mcp.md`: строки вида `&Перед("ИмяМетода")`, `&После("ИмяМетода")`,
`&Вместо("ИмяМетода")`, `&ИзменениеИКонтроль("ИмяМетода")`, пробел перед скобкой возможен.

Каталоги подставь из таблицы «Каталоги исходников проекта» в `CLAUDE.md`, а не пиши `src/cfe_*`
наугад: на проекте они могут называться иначе, и тогда поиск молча вернёт пустоту — а пустой
результат ты прочитаешь как «перехватчиков нет».

Нашёл — второй перехватчик не заводи: логика удвоится, а при совпадении имени процедуры
будет ещё и ошибка компиляции. Дополни существующий или обоснуй в плане, почему нужен отдельный.

Последствия зависят от типа вызова, и для двух из них они тяжёлые:

| Что уже есть в другом расширении | Что будет |
|---|---|
| `&Перед` / `&После` | выполнятся оба, вложенно по порядку применения расширений — конфликта нет |
| `&Вместо` где-то выше по порядку | твой перехватчик **молча не выполнится** вместе с типовым методом |
| `&ИзменениеИКонтроль` | второй такой на метод запрещён платформой: попадёт в ошибки применения расширения |

Механика и источники — в `config-modification` («Паттерн: несколько расширений над одним методом»).
Практический вывод: если над методом уже висит `&Вместо` или `&ИзменениеИКонтроль`, выбор директивы
для переноса перестаёт быть свободным — это пункт плана, а не деталь реализации.

Это же правило действует и на перехватчики, которые ты создаёшь **сам за один заход**: поиск
их не найдёт, потому что их ещё нет. Норма — «один перехватываемый метод — один перехватчик
на тип вызова» (`1c-rules.md`, ### Архитектура). Проверяй по итогу переноса, а не по результату
поиска: сколько методов заимствовано — столько перехватчиков, независимо от того, сколько правок
в каждый из них легло.

Обработчики событий **форм и их элементов** так не найти: директивы у них нет, перехват описан
секцией `Events` в `Form.xml` расширения. Их показывает ревизия — по каждой привязке она печатает
событие, имя обработчика и тип вызова («Перед», «После», «Вместо»). Это второй механизм перехвата,
не экзотика: устройство — в `config-modification` («Паттерн: перехват события формы»).

## Шаг 4. Стоп-правила — что нельзя решить молча

Эти пункты идут в план **открытыми вопросами**, даже если хирург выглядит очевидным.

- **Чистое удаление типового кода.** Двусмысленно по построению: осознанное подавление или
  случайная потеря кода прошлым разработчиком. Покажи удалённый блок, скажи, что он делал
  у вендора, и спроси: подавляем через `#Удаление` или восстанавливаем как код вендора.
  Восстановление — не доработка, в расширение оно не переносится.
- **Маркеры не того формата.** Скрипт помечает похожие комментарии как догадку. Автор, дата
  и номер задачи из них — не факт. Подтверди, прежде чем переносить их в новые маркеры.
- **Номер задачи и разработчик.** Порядок поиска `TASK` и источник `DEVELOPER` — норма
  в `1c-rules.md`. Не найден — спроси. Не преобразуй прозу («заявка 445») в номер формата
  проекта самостоятельно.
- **Расширение-приёмник, если их несколько.** Правило выбора — в `CLAUDE.md` проекта.
- **Точка встраивания, меняющая момент исполнения** (шаг 2а). Назови обе цены: копия тела
  вендора против сдвига момента выполнения. Молчаливое «поведение то же» здесь запрещено —
  выбор делает пользователь.

## Шаг 5. Тир работы

Определяется сигналами, а не ощущением. Не поднимай тир «на всякий случай».

| Тир | Сигнал | Как работаешь |
|---|---|---|
| Лёгкий (по умолчанию) | один объект, 1–3 хирурга, смысл виден из diff | сам, без субагентов; план 2–4 строки |
| Средний | много хирургов, смысл неочевиден, задеты соседние объекты | точечно один `1c-code-explorer` или `1c-code-reviewer` |
| Тяжёлый | «весь объект», «все доработки документа X», кросс-модульные зависимости, неясное намерение | **не разворачивай сам** — предложи пользователю `1c-feature-dev`, переформулировав задачу как перенос |

## Шаг 6. План и гейт

План короткий и пропорционален тиру. На каждый хирург — строка вида:

```
Хирург 2 (ЗАМЕНА, ПередЗаписью, строки 22-31): сумма считается за вычетом скидок.
→ Расш1, &ИзменениеИКонтроль: #Удаление типовой строки + #Вставка новой, маркеры внутри #Вставка.
```

**Строка плана на хирург — не значит перехватчик на хирург.** Перехватчик заводится на
**метод**: норма «один перехватываемый метод — один перехватчик на тип вызова» в `1c-rules.md`
(### Архитектура). Две правки в одном методе — две строки плана и **один** перехватчик,
внутри которого обе, каждая со своими маркерами. Разные задачи и разные даты в маркерах поводом
развести перехватчики не являются: это история правок, а не архитектура.

Если по одному методу набралось несколько строк плана, скажи прямо, в какой один перехватчик
они сходятся, — иначе на шаге 7 легко сделать по перехватчику на строку.

Перед планом дай **сводку находок**: сколько файлов объекта разошлось с эталоном из скольких,
что переносимо, что нет. Сводка обязана покрывать **все** расхождения — ни одно не исчезает
молча. Шум и следствия сворачивай по классам с числом («ещё 2 расхождения — форматирование
и комментарий, переносить нечего»), а не перечисляй построчно: пользователь увидит детали
в выводе скрипта или спросит.

Дальше план делится на два блока — **что делаешь ты** и **что делает пользователь**.
Каждый пункт называет конкретный файл и конкретное действие с его результатом. Не пиши
телеграфом и не ссылайся на ключи скрипта: «вернуть модуль через `--restore`» не говорит,
что физически произойдёт, а «`Ext/Form/Module.bsl` вернётся к коду вендора, уйдут 8 замен
имени реквизита» — говорит.

Если порядок действий важен, скажи это отдельной строкой и объясни, что сломается при
нарушении.

Открытые вопросы из шага 4 — отдельным блоком в конце, чтобы их было видно и они не тонули
среди пунктов плана.

Покажи план и дождись одобрения. Правки пользователя вносишь в план, а не в файлы.

Если в плане есть пункты «ждёт пользователя», сохрани его в `.tasks/extract-<объект>/plan.md` —
работа продолжится в другой сессии по этому файлу.

## Шаг 7. Перенос и возврат к коду вендора

**Перенос и возврат — один неделимый комплект.** Между ними одна и та же логика лежит в двух
местах: правка ещё в типовом объекте, перехватчик уже в расширении. Загруженное в базу такое
состояние отработает **дважды** — задвоит движения, суммы или запись. Поэтому пока возврат
не закончен, ни конфигурация, ни расширение в базу не загружаются. Если часть возврата делает
пользователь в Конфигураторе, скажи это первым пунктом его инструкции.

1. Код в расширение — по паттернам `config-modification`, маркеры по нормам `1c-rules.md`.
   Область для перехватчика бери по роли заимствованного метода: посмотри, в какой области он
   лежит в типовом модуле, и положи перехватчик в такую же. Первая существующая область в модуле
   расширения критерием не является.

   **Перехват через событие — это ещё и правка XML.** Процедуру ты кладёшь в модуль, но сам
   перехват описан секцией `<Events>` в `Form.xml` расширения, и на неё распространяется строка
   «XML: метаданные объектов расширений» таблицы полномочий `CLAUDE.md`.

   Модуль расширения в таблице полномочий не значится — это собственный код, его ты правишь
   сам в любом режиме: пишешь новый обработчик или дополняешь существующий. Ограничение
   касается только привязки. Поэтому при режиме не `изменять` работа делится так:

   - код обработчика ты пишешь и кладёшь в модуль сразу, готовым;
   - привязку выдаёшь инструкцией: форма, событие, тип вызова («Перед», «После» или «Вместо»),
     имя обработчика — и что делается это в свойствах формы в Конфигураторе;
   - если привязка к этому событию уже стоит и нужного типа — инструкция не нужна вовсе, скажи
     это явно, чтобы пользователь не искал несуществующую работу.

   Без привязки код в модуле мёртв и не выполнится. Скажи это прямо и поставь пункт плана
   в ожидание — иначе выглядит, что работа закончена.
2. Типовой объект возвращается к состоянию эталона — тем же скриптом:

   ```bash
   python .claude/skills/extract-to-extension/scripts/extract-diff.py <путь> --restore
   ```

   Он копирует файлы эталона побайтно, сохраняя кодировку и переводы строк. Руками не переписывай:
   в выгрузке 1С встречаются BOM и CRLF, и правка «по тексту» их портит. Удалённые файлы эталона
   скрипт воссоздаёт. Новые файлы рабочей конфигурации он **не удаляет** — удаление решает
   пользователь, вынеси его отдельным пунктом плана.

   Ключ применяй **только после** того, как доработки перенесены и план одобрен, — он затирает
   рабочие файлы. Список затираемых файлов скрипт печатает в том же прогоне, в котором затирает:
   читать его поздно.

   **Одобрения плана для запуска недостаточно — спроси отдельно.** Между гейтом шага 6 и этим
   моментом прошла вся работа по переносу, а откат ограничен тем, что успело попасть в коммит:
   git вернёт прежнее содержимое файла, но не решит за пользователя, что затирать. Возьми
   поимённый список
   из прогона **без** `--restore` («ИТОГ: расхождений — N»), покажи его пользователю
   и дождись подтверждения именно этой операции. Молчание, «продолжай» из другого контекста
   и одобренный ранее план подтверждением не считаются.

   **Скрипт откажется затирать файл, чьи изменения не сохранены в git** — выйдет с кодом 2
   и не тронет ничего. Причина простая: после записи прежнее содержимое взять неоткуда.
   Штатное решение — закоммитить эти файлы и повторить прогон, тогда возврат обратим через git.
   Флаг `--no-undo-confirmed` отказ снимает, но ставится **только** после того, как ты сказал
   пользователю, что отката не будет, и получил разрешение именно на это. Дописать флаг самому,
   чтобы прогон прошёл, — грубая ошибка: ты снимешь единственную защиту, которая тут есть.

   По умолчанию возвращаются только модули BSL. XML пропускается: в большинстве проектов он
   в режиме «только чтение», и его возврат — работа для Конфигуратора. Если таблица полномочий
   разрешает, добавь `--include-xml`. Файлы прочих типов — макеты `.bin`, картинки — скрипт
   не возвращает никогда и выносит в раздел «не возвращается автоматически».

   **Ловушка: правка формы живёт и в BSL, и в XML.** Вернув только модуль, ты получишь
   несогласованное дерево — код ссылается на вендорское имя, а `Form.xml` объявляет
   доработанное, и форма не скомпилируется. Если XML возвращает пользователь в Конфигураторе,
   прямо предупреди: **загружать конфигурацию до его правки нельзя**, и поставь это первым
   пунктом инструкции.
3. Сверься повторным прогоном без `--restore`. Код 0 — объект совпал с эталоном. Код 1 —
   расхождения остались. Код 2 — скрипт отказался работать, результата нет вообще.

   **Единица после возврата — не всегда провал.** Если XML возвращает пользователь
   в Конфигураторе или остались новые файлы, ждущие его решения, нуля тут и не будет.
   Скрипт печатает остаток поимённо — перенеси этот список в отчёт с указанием, чьё это
   действие, и не выдавай единицу за ошибку переноса.

**Правка типового объекта подчиняется таблице «Полномочия по изменению исходников» из
`CLAUDE.md` проекта** — это правка основной конфигурации, а не техническая мелочь. Режим не
`изменять` — не правишь сам, а выдаёшь инструкцию для Конфигуратора и ставишь пункт плана
в ожидание.

## Шаг 8. Когда в расширении не хватает объекта

Сначала определи, какой из двух случаев перед тобой. Это разные операции, и путать их дорого.

**Типовой объект ещё не заимствован.** Обычный случай при переносе перехватчика: объекта
в расширении нет просто потому, что его туда не втянули. Заимствование — не копия: имя остаётся
**типовым**, префикс расширения к нему не добавляется. Префикс нужен тому, что расширение заводит
от себя, — своим реквизитам и своим объектам. Что можно и чего нельзя с заимствованным объектом —
паттерн «заимствованные (adopted) объекты» в `config-modification`.

**Доработке нужен собственный новый объект** — справочник, регистр, общий модуль, которых
у вендора нет вообще. Здесь имя идёт с префиксом расширения по норме именования из `1c-rules.md`.
При переносе существующей доработки случай редкий: если он возник, скажи вслух, почему
перехватчиком не обойтись.

Дальше — по полномочиям. Решают две настройки `CLAUDE.md` проекта: «Новые объекты метаданных»
и строка «XML: метаданные объектов расширений» таблицы полномочий.

- **Разрешено и есть инструмент с проверкой результата** — заведи объект и модуль сам,
  затем предложи загрузить расширение в базу и выгрузить обратно для сверки (скрипты `1c-batch`).
- **Иначе** — не создавай файл объекта. Выдай инструкцию: заимствование типового или новый
  объект, точное имя, какие модули завести, — и **приложи готовый текст кода**, чтобы
  пользователю осталось вставить его в созданный модуль, а не писать по описанию.
- **Режим «по явному запросу»** — создание идёт в план открытым пунктом.

## Шаг 9. Живая база

Изменённый файл на диске ещё не действует в базе: нужна загрузка (`load-config`,
`load-extension` из `1c-batch`; вариант `.ps1` предпочтителен, `.bat` — запасной).
Выгрузка и загрузка требуют **закрытого Конфигуратора** —
командный запуск конфликтует с интерактивным сеансом. Перед запуском спроси, закрыт ли он.

Смоук-тест на базе агент не выполняет. В итоге перечисли, что именно проверить руками.

## Чек-лист

- [ ] Границы получены скриптом, модуль целиком не читался без необходимости
- [ ] По каждой правке восстановлено намерение — что должно происходить и при каком условии,
      а не пересказ строк — либо оно вынесено в открытый вопрос; невоспроизводимое в расширении
      отмечено как порча типового и вынесено в вопрос, а не в план переноса
- [ ] Там, где сработал признак шага 2а, точка встраивания пересмотрена: сохраняющая момент
      исполнения решена в плане, меняющая — вынесена в открытые вопросы; после смены точки поиск
      чужих перехватчиков повторён по новой (неприменимо, если признаков не было)
- [ ] Эталон подтверждён: имя и версия конфигурации сошлись либо расхождение разобрано
      с пользователем
- [ ] Добавленные реквизиты проверены за пределами папки объекта; по хранящимся данным задан
      вопрос, а не сделан вывод «мёртвый»
- [ ] Механизм выбран до типа вызова: правка в обработчике события формы или элемента — привязка
      к событию, а не директива; тип вызова выбран по норме, а не по привычке — копия типового
      тела взята только там, где хирург сидит в середине метода (неприменимо,
      если переносить нечего)
- [ ] Если перехват сделан привязкой к событию — сказано, что без правки `Form.xml` расширения
      код обработчика не выполнится, и полномочия по XML соблюдены
- [ ] Перехватчик лежит в области роли заимствованного метода, а не в первой существующей
- [ ] На один метод заведён один перехватчик на тип вызова: правки из разных задач сведены
      в него вместе со своими маркерами, если те применяются, а не разнесены по отдельным
      перехватчикам
- [ ] Ревизия расширения прогнана ДО возврата к вендору; список собственных изменений
      расширения записан в план, испорченная база отмечена
- [ ] Чистые удаления и маркеры чужого формата вынесены в открытые вопросы, не решены молча
- [ ] Номер задачи и разработчик взяты из источника или запрошены, не придуманы (неприменимо,
      если маркеры в проекте не используются)
- [ ] План одобрен пользователем до изменения файлов
- [ ] Список затираемых файлов показан пользователю и подтверждён отдельно, до запуска `--restore`
- [ ] Отказ по незакоммиченным файлам не обойдён флагом `--no-undo-confirmed` без разрешения
      пользователя именно на работу без отката
- [ ] Между переносом и возвратом в базу ничего не загружалось: двойной логики не осталось
- [ ] Типовой объект возвращён; остаток (XML, новые файлы, прочие типы) назван поимённо
      с указанием, чьё это действие
- [ ] Если объекта в расширении не хватало — различены заимствование типового и создание нового
- [ ] Если XML возвращает пользователь — сказано, что до его правки конфигурацию не загружать
- [ ] Полномочия по таблице `CLAUDE.md` соблюдены; что нельзя менять — выдано инструкцией
- [ ] Названо, что проверить на живой базе

Attribution

mr-ske1rmr-ske1r
View sourceMore from mr-ske1r →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

695601 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →