Введение
За много лет разработки на 1С сформировался привычный подход к сравнению кода: использовать возможности конфигуратора или внешние инструменты для работы с текстовыми файлами. В частности, разработчики использовали VS Code, куда выгружались модули .bsl. Это делало работу с большими модулями удобнее, но сам принцип сравнения оставался основанным преимущественно на сопоставлении текста и последовательности строк.
У такого подхода есть очевидное ограничение: при переносе процедур и функций, рефакторинге или изменении структуры модуля количество формальных различий может значительно превышать количество реальных изменений в логике.
Бурное развитие технологий искусственного интеллекта открывает новые возможности для анализа BSL-кода. AI-инструменты позволяют рассматривать модуль не только как последовательность строк, но и анализировать его структуру и логику. Поэтому задача может смещаться от простого поиска различий к анализу того, что именно изменилось и к каким последствиям это может привести.
Это дает как минимум два существенных преимущества. Во-первых, анализ меньше зависит от последовательного расположения процедур и функций в коде. Во-вторых, значительная часть сравнения и первичного code review может выполняться быстрее и без непосредственного участия разработчика, с одновременным поиском потенциальных ошибок, изменений бизнес-логики и возможных регрессий.
В статье рассмотрим практический вариант такого подхода для разработки на 1С: получение двух версий BSL-модуля из конфигуратора, их передачу в Cursor AI для автоматизированного анализа изменений и проведения code review с помощью искусственного интеллекта (ИИ). Также опишем классический вариант использования Cursor AI для сравнения без использования ИИ.
Стандартное визуальное сравнение (diff-режим, без ИИ)
Очень многие для сравнения модулей bsl используют редактор VS Code. О плюсах применения VS Code для сравнения модулей много написано в интернете. Поскольку редактор Cursor AI построен на базе VS Code, он наследует многие его возможности, в том числе и визуальное сравнение файлов в режиме Diff. Такой подход позволяет отказаться от использования отдельного VS Code и выполнять обычное текстовое сравнение непосредственно в Cursor, сохраняя все используемые инструменты в одной рабочей среде. При этом Diff-режим изолирован от AI-чата: сравниваемые файлы открываются в специальном окне сравнения, и для AI фактически не представлены как обычные файлы текущей рабочей области. Поэтому использовать ИИ непосредственно для анализа такого сравнения не получится. Diff подходит только для визуального просмотра классического построчного сравнения.
Необходимо в параметрах конфигуратора создать новую настройку для внешней программы сравнения, указать в ней путь к исполняемому файлу Cursor.exe, прописать параметры сравнения и выбрать данную настройку для показа различий без учета структуры:
-n -d %baseCfg %secondCfg

После выбора команды сравнения модулей открывается новое окно Cursor AI в режиме сравнения.

Передача модулей для обработки ИИ (без автоматизации)
Чтобы появилась возможность указать ИИ-чату команду сравнения и анализа модулей, они должны быть переданы из конфигуратора не в режиме сравнения (т.е. без параметра -d).
1) Необходимо создать новую настройку для внешней программы сравнения, указать в ней путь к исполняемому файлу Cursor.exe и прописать параметры сравнения:
-n %baseCfg %secondCfg

2) Выбрать модули и запустить сравнение.
3) В открывшемся окне Cursor нажать Ctrl+L - чтобы открыть чат ИИ, или Ctrl+I - чтобы открыть Composer.
4) В чате через символ @ надо выбрать файлы и написать свои ожидания от ИИ (сравнение, пожелания, кодревью), нажать ввод.
Дополнительные способы сравнения файлов с помощью ИИ:
- Выделение фрагментов кода: можно выделить кусок кода в одном файле, нажать правой кнопкой мыши или вызвать чат, указать второй файл через
@и попросить сопоставить алгоритмы. - Режим Composer: если нужно не просто сравнить, но и синхронизировать или объединить изменения, надо открыть режим Composer (
Ctrl + I) и попросить ИИ перенести недостающую функциональность из одного файла в другой.
Можно также использовать файл глобальных правил (.cursorrules), чтобы Cursor всегда понимал специфику кода 1С и знал, что от него хотят при сравнении файлов конфигурации. Для этого надо
- Создать в корне вашей рабочей папки проекта файл инструкции.
- Написать туда системный промпт для 1С:
Ты — эксперт по разработке на платформе 1С:Предприятие 8. Если я передаю тебе два файла модулей 1С, твоя задача — провести глубокий код-ревью: 1. Сравнить логику работы процедур и функций. 2. Найти скрытые баги, нарушения стандартов разработки 1С и потенциальные проблемы с производительностью. 3. Показать детальные различия в алгоритмах, игнорируя незначительные изменения форматирования. - Теперь можно просто выбирать при помощи символа
@переданные файлы из списка (они будут в самом верху как недавние) и просто отправлять пустой запрос или слово "Сравни". ИИ отработает строго по вашей заготовленной инструкции для 1С.
Автоматизация при помощи скрипта
Для того, чтобы максимально убрать ручные действия используем PowerShell-скрипт.
Примерный алгоритм работы скрипта:
- 1С передает два сравниваемых файла во внешний PowerShell-скрипт;
- скрипт восстанавливает полные пути к файлам, даже если 1С разбивает их на несколько аргументов из-за пробелов в имени;
- файлы копируются в
C:\1C_Compareпод фиксированными именами (1c_base.bsl и 1c_current.bsl); - содержимое
prompt.txtпомещается в буфер обмена; - запускается Cursor с рабочей папкой
C:\1C_Compare; - в чат Cursor можно вставить из буфера подготовленный промпт и выполнить анализ.
Подготовка
1) Необходимо на диске создать каталог C:\1C_Compare.
2) В созданном каталоге разместить два файла с именами compare.ps1 и prompt.txt.
compare.ps1 — основной PowerShell-скрипт (код скрипта под спойлером).
#Requires -Version 5.1
$ErrorActionPreference = 'Stop'
$DestDir = 'C:\1C_Compare'
$LogFile = Join-Path $DestDir 'compare.log'
$DebugFile = Join-Path $DestDir 'compare_debug.log'
$PromptFile = Join-Path $PSScriptRoot 'prompt.txt'
function Write-Log {
param([string]$Message)
$line = '[{0}] {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message
Add-Content -LiteralPath $LogFile -Value $line -Encoding UTF8
Add-Content -LiteralPath $DebugFile -Value $line -Encoding UTF8
}
function Write-DebugDump {
param([string[]]$RawArgs)
Write-Log ("Args count: {0}" -f $RawArgs.Count)
for ($i = 0; $i -lt $RawArgs.Count; $i++) {
Write-Log ("arg[{0}] = [{1}]" -f $i, $RawArgs[$i])
}
}
function Show-DebugError {
param([string]$Message)
try {
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show(
"$Message`n`nПодробно: C:\1C_Compare\compare_debug.log",
'1C Compare — ошибка',
[System.Windows.Forms.MessageBoxButtons]::OK,
[System.Windows.Forms.MessageBoxIcon]::Warning
) | Out-Null
} catch {
# ok bez GUI
}
}
function Normalize-PathArg {
param([string]$Path)
return $Path.Trim().Trim('"').Replace('/', '\').TrimEnd('%')
}
function Resolve-ComparePaths {
param([string[]]$RawArgs)
$items = @($RawArgs | ForEach-Object { Normalize-PathArg $_ } | Where-Object { $_ })
# Если 1С когда-нибудь начнет передавать два готовых пути
if ($items.Count -ge 2) {
if ((Test-Path -LiteralPath $items[0]) -and (Test-Path -LiteralPath $items[1])) {
Write-Log "Paths via args[0,1]: $($items[0]) | $($items[1])"
return @($items[0], $items[1])
}
}
# Текущий формат 1С: путь разбивается по пробелам.
# Собираем путь, пока не встретим начало следующего абсолютного пути.
$paths = @()
$current = ''
foreach ($item in $items) {
if ($item -match '^[A-Za-z]:[\\/]') {
if ($current) {
$paths += (Normalize-PathArg $current)
}
$current = $item
}
else {
$current += " $item"
}
}
if ($current) {
$paths += (Normalize-PathArg $current)
}
if ($paths.Count -ge 2) {
if ((Test-Path -LiteralPath $paths[0]) -and (Test-Path -LiteralPath $paths[1])) {
Write-Log "Paths via accumulation: $($paths[0]) | $($paths[1])"
return @($paths[0], $paths[1])
}
}
Write-Log 'ERROR: could not resolve compare paths'
for ($i = 0; $i -lt $items.Count; $i++) {
Write-Log " arg[$i]: $($items[$i]) (exists: $(Test-Path -LiteralPath $items[$i]))"
}
return $null
}
function Set-ClipboardText {
param([string]$Text)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Clipboard]::SetText($Text, [System.Windows.Forms.TextDataFormat]::UnicodeText)
}
try {
Write-Log ('--- START ---')
Write-DebugDump -RawArgs @($args)
$paths = Resolve-ComparePaths -RawArgs @($args)
$copied = $false
if ($paths) {
$baseFile = Join-Path $DestDir '1c_base.bsl'
$currentFile = Join-Path $DestDir '1c_current.bsl'
foreach ($file in @($baseFile, $currentFile)) {
if (Test-Path -LiteralPath $file) {
Remove-Item -LiteralPath $file -Force
}
}
Copy-Item -LiteralPath $paths[0] -Destination $baseFile -Force
Copy-Item -LiteralPath $paths[1] -Destination $currentFile -Force
$copied = $true
Write-Log "Copied OK -> 1c_base.bsl, 1c_current.bsl"
}
if (Test-Path -LiteralPath $PromptFile) {
$prompt = Get-Content -LiteralPath $PromptFile -Raw -Encoding UTF8
} else {
$prompt = 'Compare 1c_base.bsl and 1c_current.bsl. Find logic differences and errors.'
Write-Log "WARN: prompt.txt not found, using fallback prompt"
}
Set-ClipboardText -Text $prompt.Trim()
Write-Log 'Prompt copied to clipboard'
Start-Process 'cursor' -ArgumentList @('-n', $DestDir)
Write-Log 'Cursor started'
if (-not $copied) {
Show-DebugError 'Не удалось скопировать файлы. Смотрите compare_debug.log'
exit 1
}
}
catch {
Write-Log ("FATAL: " + $_.Exception.Message)
Write-Log $_.ScriptStackTrace
Show-DebugError $_.Exception.Message
exit 1
}
prompt.txt — текст запроса, который автоматически помещается в буфер обмена при каждом сравнении.
Пример файла prompt.txt:
Проанализируй различия между 1c_base.bsl и 1c_current.bsl.
Определи:
1. функциональные изменения;
2. потенциальные ошибки;
3. изменения бизнес-логики;
4. существенные изменения в обработке данных;
5. изменения, которые могут привести к регрессии.
Не учитывай различия в форматировании и комментариях, если они не влияют на логику.
Текст prompt.txt можно изменять без изменения PowerShell-скрипта
3) Настроить внешнее сравнение в конфигураторе 1С
В конфигураторе нужно завести новую настройку для внешней программы сравнения и указать:
Исполняемый файл:
powershell.exe
Сравнение двух файлов:
-NoProfile -ExecutionPolicy Bypass -File "C:\1C_Compare\compare.ps1" "%baseCfg%" "%secondCfg%"
Здесь %baseCfg% и %secondCfg% — стандартные параметры 1С, содержащие пути к сравниваемым файлам.

Как работает передача файлов
1С в некоторых случаях передает путь к файлу не одним аргументом, а несколькими частями. Например, путь:
C:\...\Форма(Конфигурация хранилища 58406).txt
может поступить в PowerShell как:
C:\...\Форма(Конфигурация
хранилища
58406).txt%
Скрипт compare.ps1 автоматически собирает такие части обратно в полный путь и проверяет существование получившихся файлов.
После успешного определения файлов они копируются в:
C:\1C_Compare\1c_base.bsl
C:\1C_Compare\1c_current.bsl
Поэтому в Cursor всегда используются одинаковые имена файлов независимо от объекта и ревизий 1С.
Последовательность действий пользователя
После настройки обычный сценарий следующий:
- В конфигураторе 1С пользователь выбирает сравнение двух версий/модулей.
- PowerShell автоматически обрабатывает переданные файлы.
- В
C:\1C_Compareбудут обновлены:1c_base.bsl;1c_current.bsl.
- Текст из
prompt.txtбудет помещен в буфер обмена. - Откроется Cursor с рабочим каталогом
C:\1C_Compare. - В чате Cursor пользователь вставляет содержимое буфера (
Ctrl+V) и отправляет запрос. - Cursor проводит анализ в соответствии с запросом и выдает итоговый результат.

Вступайте в нашу телеграмм-группу Инфостарт