feat(db-repo): правила захвата, нулевой шаг цикла и диагностика по отчёту субагента

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

Сообщение «объект не найден» имеет три разные причины: опечатка, отставание
базы от хранилища и попытка захватить то, что объектом не является. Теперь
перечислены все три.

В цикл добавлен нулевой шаг — получение актуального состояния перед началом
работы: правки должны опираться на актуальные версии в том числе тех объектов,
которые не меняются, но используются. Загрузка и обновление БД слиты в один
шаг через -UpdateDB, поэтому цикл не удлинился.

Захват корня конфигурации с -WithChildren отклоняется: это захват всей
конфигурации, а выглядит как захват корня. Для всей конфигурации есть
однозначная форма — вызов без -Objects.

Текстовый отчёт печатается, а не только сохраняется в файл.

Схема repository и extensions[] описана в docs/v8-project-guide.md,
цикл под хранилищем — в docs/db-guide.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-23 12:40:44 +03:00
co-authored by Claude Opus 5
parent 478e7489f9
commit 3e816d3e12
5 changed files with 172 additions and 26 deletions
+33 -18
View File
@@ -31,25 +31,35 @@ allowed-tools:
объектам. Выполняй строго по шагам:
```
0. /db-repo update <база> — начать с актуального состояния
1. /db-repo lock <база> -Objects "Справочник.Номенклатура"
2. если шаг 1 сообщил о полученных из хранилища объектах — выгрузи их заново:
/db-dump-xml <база> <каталог> -Mode Partial -ObjectsFile "<файл из вывода шага 1>"
3. правки в исходниках
4. /db-load-xml <каталог> <база> -Mode Partial -Files "Catalogs/Номенклатура.xml,…"
5. /db-update <база>
6. /db-repo commit <база> -Objects "Справочник.Номенклатура" -Comment "…"
2. если шаг 0 или 1 напечатал «локальная конфигурация изменена: из хранилища получено N» —
выгрузи названные объекты: /db-dump-xml <база> <каталог> -Mode Partial -ObjectsFile "<файл из вывода>"
3. правки в исходниках: /meta-edit, /form-edit, /skd-edit, /meta-compile и т. д.
4. /db-load-xml <каталог> <база> -Mode Partial -Files "Catalogs/Номенклатура.xml,…" -UpdateDB
5. /db-repo commit <база> -Objects "Справочник.Номенклатура" -Comment "…"
```
Шаг 2 пропускать нельзя: захват подтягивает из хранилища свежие версии, и загрузка исходников,
снятых до захвата, откатит чужие изменения — молча, без ошибки.
Шаг 0 стоит делать всегда, когда работа не продолжается сразу после предыдущего цикла: правки
должны опираться на актуальное состояние — в том числе тех объектов, которые ты не меняешь, но
используешь.
**Добавляешь новый объект** — захватывай его вместе с корнем конфигурации:
`-Objects "Конфигурация,Справочник.Склады"`.
Шаг 2 пропускать нельзя: захват и обновление подтягивают из хранилища свежие версии, и загрузка
исходников, снятых раньше, откатит чужие изменения — молча, без ошибки.
**Правишь подчинённый объект** — форму, макет, команду, реквизит — захватывай именно его:
`-Objects "Справочник.Номенклатура.Форма.ФормаЭлемента"`. Захват объекта его подчинённые объекты
не захватывает. Захватывай минимум того, что правишь: чем шире захват, тем больше конфликтов
с коллегами.
**Что вообще захватывается.** Отдельные объекты хранилища — сам объект, а также его **формы,
макеты и команды**. Реквизиты, табличные части, измерения и ресурсы отдельными объектами **не
являются**: они правятся в составе владельца.
| Что правишь | Что захватывать |
|-------------|-----------------|
| Реквизит, табличную часть, измерение, ресурс, модуль объекта | сам объект: `Справочник.Контрагенты` |
| Существующую форму, макет, команду | её саму: `Справочник.Контрагенты.Форма.ФормаЭлемента` |
| Добавляешь новую форму, макет, команду | объект-владельца; при помещении назови и новый объект |
| Добавляешь новый объект конфигурации | объект и корень: `Конфигурация,Справочник.Склады` |
Захватывай минимум того, что правишь: чем шире захват, тем больше конфликтов с коллегами.
Захват объекта его формы и макеты не захватывает — для этого есть `-WithChildren`.
## Параметры подключения
@@ -59,8 +69,9 @@ allowed-tools:
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
4. Если ветка не совпала — используй `default`
Реквизиты хранилища передавать не нужно — они берутся из `repository` записи базы. Задать их явно
можно параметрами `-Repository*`.
Реквизиты хранилища передавать не нужно: запись базы находится по переданным параметрам
соединения (`-InfoBasePath` либо `-InfoBaseServer` + `-InfoBaseRef`), реквизиты берутся из её
`repository`. Задать их явно можно параметрами `-Repository*`.
## Команда
@@ -86,7 +97,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-repo.ps1" <по
| `-InfoBaseRef <имя>` | * | Имя базы на сервере |
| `-UserName <имя>` | нет | Пользователь базы |
| `-Password <пароль>` | нет | Пароль пользователя базы |
| `-Objects <список>` | нет | Объекты через запятую. Без него — вся конфигурация |
| `-Objects <список>` | нет | Объекты через запятую. Без него — вся конфигурация, спроси подтверждение |
| `-ObjectsFile <путь>` | нет | Файл со списком объектов, одно имя на строку |
| `-WithChildren` | нет | Вместе с подчинёнными объектами на полную глубину |
| `-Comment <текст>` | нет | Комментарий к помещению (`commit`). Многострочный — как есть, с переводами строк |
@@ -111,10 +122,14 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-repo.ps1" <по
### Имена объектов
Объект — `Справочник.Номенклатура`. Подчинённый объект — полным путём:
Объект — `Справочник.Номенклатура`. Форма, макет, команда — полным путём:
`Документ.ЗаказПокупателя.Форма.ФормаДокумента`, `Справочник.Номенклатура.Макет.Печать`.
Корень конфигурации — `Конфигурация`.
Если объект «не найден», это не всегда опечатка: он мог появиться в хранилище позже, чем
обновлялась база (`/db-repo update`), либо это вовсе не объект хранилища — реквизит или
табличная часть.
## Результат
Код возврата отражает, достигнуто ли запрошенное состояние, а не факт изменения: «уже захвачено»,
+30 -2
View File
@@ -1,4 +1,4 @@
# db-repo v1.0 — 1C configuration repository operations
# db-repo v1.1 — 1C configuration repository operations
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# NB: движок только 1cv8 — ibcmd работу с хранилищем не поддерживает (нет такого режима).
<#
@@ -771,7 +771,11 @@ function Write-RepoVerdict {
if ($Log.Missing.Count -gt 0) {
Write-Host "Error: objects not found in the configuration:" -ForegroundColor Red
foreach ($n in $Log.Missing) { Write-Host " $n" -ForegroundColor Red }
Write-Host "Проверьте написание. Принимаются обе формы: Справочник.Номенклатура и Catalog.Номенклатура." -ForegroundColor Yellow
Write-Host "Возможные причины:" -ForegroundColor Yellow
Write-Host " - опечатка в имени. Принимаются обе формы: Справочник.Номенклатура и Catalog.Номенклатура" -ForegroundColor Yellow
Write-Host " - база отстала от хранилища, объект появился позже — выполните /db-repo update" -ForegroundColor Yellow
Write-Host " - это не объект хранилища: реквизиты, табличные части, измерения и ресурсы" -ForegroundColor Yellow
Write-Host " отдельно не захватываются — указывайте объект-владельца" -ForegroundColor Yellow
return 1
}
@@ -879,6 +883,18 @@ function Write-RepoVerdict {
return 1
}
Write-Host "Команда '$Cmd' выполнена." -ForegroundColor Green
if ($Cmd -eq 'report' -and $ReportFormat -eq 'txt' -and (Test-Path $OutputFile)) {
$txt = [System.Text.Encoding]::UTF8.GetString([System.IO.File]::ReadAllBytes($OutputFile))
if ($txt.Length -gt 0 -and $txt[0] -eq [char]0xFEFF) { $txt = $txt.Substring(1) }
$lines = @($txt -split "`r?`n")
$limit = 200
Write-Host "--- $OutputFile ---"
Write-Host (($lines | Select-Object -First $limit) -join [Environment]::NewLine)
if ($lines.Count -gt $limit) {
Write-Host "[... показаны первые $limit строк из $($lines.Count); полный отчёт в файле ...]" -ForegroundColor Yellow
}
Write-Host "--- End ---"
}
return 0
}
}
@@ -922,6 +938,18 @@ if ($requested.Count -gt 0 -and $objectAware -notcontains $cmd) {
exit 1
}
# Корень с подчинёнными — это ВСЯ конфигурация, а выглядит как «захвачу корень». Для всей
# конфигурации есть однозначная форма (вызов без -Objects), поэтому двусмысленную отклоняем.
if ($WithChildren) {
$rootAsked = @($requested | Where-Object { $script:ConfigRootAliases -contains $_ })
if ($rootAsked.Count -gt 0) {
Write-Host "Error: '$($rootAsked[0])' with -WithChildren means the WHOLE configuration, not just its root." -ForegroundColor Red
Write-Host " Нужен только корень (чтобы добавить или удалить объект) — уберите -WithChildren." -ForegroundColor Yellow
Write-Host " Нужна вся конфигурация — вызовите без -Objects." -ForegroundColor Yellow
exit 1
}
}
switch ($cmd) {
'report' { if (-not $OutputFile) { Write-Host "Error: -OutputFile is required for report" -ForegroundColor Red; exit 1 } }
'dump-cfg' { if (-not $OutputFile) { Write-Host "Error: -OutputFile (path to the .cf file) is required for dump-cfg" -ForegroundColor Red; exit 1 } }