diff --git a/.claude/skills/cf-edit/scripts/cf-edit.ps1 b/.claude/skills/cf-edit/scripts/cf-edit.ps1 index f6d7e403b..24bfff6e2 100644 --- a/.claude/skills/cf-edit/scripts/cf-edit.ps1 +++ b/.claude/skills/cf-edit/scripts/cf-edit.ps1 @@ -460,16 +460,16 @@ function Do-ModifyProperty([string]$batchVal) { # databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, # иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида # (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. -# Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: -# настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда -# оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. +# Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же +# его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd +# остаётся рабочим каталогом проекта. # configSrc считается от каталога .v8-project.json, как задокументировано в # docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. function Get-NewObjectPosition([string]$cfgDir) { try { if (-not $cfgDir) { $cfgDir = "." } - $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) - if (-not $pj) { $pj = Find-V8Project (Get-Location).Path } + $pj = Find-V8Project (Get-Location).Path + if (-not $pj) { $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) } if (-not $pj) { return "end" } $proj = Get-Content -Raw $pj | ConvertFrom-Json $projDir = [System.IO.Path]::GetDirectoryName($pj) diff --git a/.claude/skills/cf-edit/scripts/cf-edit.py b/.claude/skills/cf-edit/scripts/cf-edit.py index 5a8d7d926..886226ee6 100644 --- a/.claude/skills/cf-edit/scripts/cf-edit.py +++ b/.claude/skills/cf-edit/scripts/cf-edit.py @@ -360,14 +360,14 @@ def get_new_object_position(cfg_dir): databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. - Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: - настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда - оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. + Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же + его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd + остаётся рабочим каталогом проекта. configSrc считается от каталога .v8-project.json, как задокументировано в docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. """ try: - pj = _sg_find_v8project(os.path.abspath(cfg_dir or ".")) or _sg_find_v8project(os.getcwd()) + pj = _sg_find_v8project(os.getcwd()) or _sg_find_v8project(os.path.abspath(cfg_dir or ".")) if not pj: return "end" proj = json.loads(open(pj, encoding="utf-8-sig").read()) diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 index 0b4b98979..3ef5ed0f2 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 @@ -2261,16 +2261,16 @@ function Find-V8Project([string]$startDir) { # databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, # иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида # (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. -# Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: -# настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда -# оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. +# Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же +# его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd +# остаётся рабочим каталогом проекта. # configSrc считается от каталога .v8-project.json, как задокументировано в # docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. function Get-NewObjectPosition([string]$cfgDir) { try { if (-not $cfgDir) { $cfgDir = "." } - $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) - if (-not $pj) { $pj = Find-V8Project (Get-Location).Path } + $pj = Find-V8Project (Get-Location).Path + if (-not $pj) { $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) } if (-not $pj) { return "end" } $proj = Get-Content -Raw $pj | ConvertFrom-Json $projDir = [System.IO.Path]::GetDirectoryName($pj) diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py index 3d51bba13..966ab7179 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py @@ -224,14 +224,14 @@ def get_new_object_position(cfg_dir): databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. - Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: - настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда - оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. + Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же + его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd + остаётся рабочим каталогом проекта. configSrc считается от каталога .v8-project.json, как задокументировано в docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. """ try: - pj = _sg_find_v8project(os.path.abspath(cfg_dir or ".")) or _sg_find_v8project(os.getcwd()) + pj = _sg_find_v8project(os.getcwd()) or _sg_find_v8project(os.path.abspath(cfg_dir or ".")) if not pj: return "end" proj = json.loads(open(pj, encoding="utf-8-sig").read()) diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index b9b08c225..beef8f4f7 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -5238,16 +5238,16 @@ if ($commands -and $commands.Count -gt 0) { # databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, # иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида # (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. -# Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: -# настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда -# оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. +# Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же +# его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd +# остаётся рабочим каталогом проекта. # configSrc считается от каталога .v8-project.json, как задокументировано в # docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. function Get-NewObjectPosition([string]$cfgDir) { try { if (-not $cfgDir) { $cfgDir = "." } - $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) - if (-not $pj) { $pj = Find-V8Project (Get-Location).Path } + $pj = Find-V8Project (Get-Location).Path + if (-not $pj) { $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) } if (-not $pj) { return "end" } $proj = Get-Content -Raw $pj | ConvertFrom-Json $projDir = [System.IO.Path]::GetDirectoryName($pj) diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 923279b59..ea42151a8 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -5215,14 +5215,14 @@ def get_new_object_position(cfg_dir): databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. - Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: - настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда - оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. + Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же + его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd + остаётся рабочим каталогом проекта. configSrc считается от каталога .v8-project.json, как задокументировано в docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. """ try: - pj = _sg_find_v8project(os.path.abspath(cfg_dir or ".")) or _sg_find_v8project(os.getcwd()) + pj = _sg_find_v8project(os.getcwd()) or _sg_find_v8project(os.path.abspath(cfg_dir or ".")) if not pj: return "end" proj = json.loads(open(pj, encoding="utf-8-sig").read()) diff --git a/.claude/skills/role-compile/scripts/role-compile.ps1 b/.claude/skills/role-compile/scripts/role-compile.ps1 index 0d6a39c6b..65f4e8ab9 100644 --- a/.claude/skills/role-compile/scripts/role-compile.ps1 +++ b/.claude/skills/role-compile/scripts/role-compile.ps1 @@ -1189,16 +1189,16 @@ $enc = New-Object System.Text.UTF8Encoding($true) # databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, # иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида # (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. -# Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: -# настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда -# оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. +# Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же +# его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd +# остаётся рабочим каталогом проекта. # configSrc считается от каталога .v8-project.json, как задокументировано в # docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. function Get-NewObjectPosition([string]$cfgDir) { try { if (-not $cfgDir) { $cfgDir = "." } - $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) - if (-not $pj) { $pj = Find-V8Project (Get-Location).Path } + $pj = Find-V8Project (Get-Location).Path + if (-not $pj) { $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) } if (-not $pj) { return "end" } $proj = Get-Content -Raw $pj | ConvertFrom-Json $projDir = [System.IO.Path]::GetDirectoryName($pj) diff --git a/.claude/skills/role-compile/scripts/role-compile.py b/.claude/skills/role-compile/scripts/role-compile.py index 7a010edf1..367dba15a 100644 --- a/.claude/skills/role-compile/scripts/role-compile.py +++ b/.claude/skills/role-compile/scripts/role-compile.py @@ -1062,14 +1062,14 @@ def get_new_object_position(cfg_dir): databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. - Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: - настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда - оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. + Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же + его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd + остаётся рабочим каталогом проекта. configSrc считается от каталога .v8-project.json, как задокументировано в docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. """ try: - pj = _sg_find_v8project(os.path.abspath(cfg_dir or ".")) or _sg_find_v8project(os.getcwd()) + pj = _sg_find_v8project(os.getcwd()) or _sg_find_v8project(os.path.abspath(cfg_dir or ".")) if not pj: return "end" proj = json.loads(open(pj, encoding="utf-8-sig").read()) diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 index e078360de..caee1ea4b 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 @@ -997,16 +997,16 @@ function Esc-XmlText { # databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, # иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида # (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. -# Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: -# настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда -# оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. +# Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же +# его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd +# остаётся рабочим каталогом проекта. # configSrc считается от каталога .v8-project.json, как задокументировано в # docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. function Get-NewObjectPosition([string]$cfgDir) { try { if (-not $cfgDir) { $cfgDir = "." } - $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) - if (-not $pj) { $pj = Find-V8Project (Get-Location).Path } + $pj = Find-V8Project (Get-Location).Path + if (-not $pj) { $pj = Find-V8Project ([System.IO.Path]::GetFullPath($cfgDir)) } if (-not $pj) { return "end" } $proj = Get-Content -Raw $pj | ConvertFrom-Json $projDir = [System.IO.Path]::GetDirectoryName($pj) diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.py b/.claude/skills/xdto-compile/scripts/xdto-compile.py index 893c74334..3e817bd47 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.py +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.py @@ -1112,14 +1112,14 @@ def get_new_object_position(cfg_dir): databases[].newObjectPosition базы, чей configSrc охватывает каталог родительского XML, иначе корневое поле, иначе end. Значения: end — после последнего объекта того же вида (так дописывает Конфигуратор); byName — по имени среди объектов того же вида. - Файл ищем от каталога конфигурации и лишь потом от cwd — в отличие от support-guard: - настройка принадлежит выгрузке, а рабочим каталогом при вызове навыка почти всегда - оказывается чужой проект со своим .v8-project.json, и он перекрыл бы нужный. + Файл ищем от рабочего каталога вверх, каталог конфигурации — запасной путь: так же + его ищут support-guard и группа db-*, а скрипт навыка зовут по абсолютному пути, и cwd + остаётся рабочим каталогом проекта. configSrc считается от каталога .v8-project.json, как задокументировано в docs/v8-project-guide.md. Реестр семьи: tests/skills/check-inline-drift.mjs. """ try: - pj = _sg_find_v8project(os.path.abspath(cfg_dir or ".")) or _sg_find_v8project(os.getcwd()) + pj = _sg_find_v8project(os.getcwd()) or _sg_find_v8project(os.path.abspath(cfg_dir or ".")) if not pj: return "end" proj = json.loads(open(pj, encoding="utf-8-sig").read()) diff --git a/docs/v8-project-guide.md b/docs/v8-project-guide.md index 7102d378b..aad4482d8 100644 --- a/docs/v8-project-guide.md +++ b/docs/v8-project-guide.md @@ -161,8 +161,6 @@ Читают поле навыки, добавляющие запись в состав: `meta-compile`, `role-compile`, `xdto-compile`, `cfe-borrow` и операция `add-childObject` навыка `cf-edit`. Раскладка та же, что у `editingAllowedCheck`: берётся `databases[].newObjectPosition` базы, чей `configSrc` (относительно каталога `.v8-project.json`) охватывает каталог правимого файла; иначе корневое поле; иначе `end`. -Сам файл `.v8-project.json` ищется вверх **от каталога конфигурации**, и лишь потом от текущего каталога — в отличие от `editingAllowedCheck`, который смотрит сначала на текущий каталог. Настройка принадлежит выгрузке: навык почти всегда вызывают из другого проекта, и его `.v8-project.json` перекрыл бы нужный. - **Порядок имён** — как в дереве Конфигуратора: регистр не учитывается, подчёркивание раньше цифр, цифры раньше букв, латиница раньше кириллицы, `ё` на месте `е`. Сравнение реализовано ключом «ранг+символ», а не культурными таблицами ОС, поэтому PowerShell- и Python-порты дают одинаковый результат на любой платформе. **Подсистемы поле не затрагивает** — они всегда дописываются в конец. Порядок подсистем в дереве задаёт порядок разделов в панели, пока они не перечислены в `` файла `Ext/CommandInterface.xml`; сама платформа этот список не заводит, а `subsystem-compile` его не трогает (это работа `interface-edit`). Сортировка подсистем поэтому переставляла бы разделы интерфейса молча. diff --git a/tests/skills/cases/cfe-borrow/newobjectposition-byname.json b/tests/skills/cases/cfe-borrow/newobjectposition-byname.json index 5f2c7af81..ca07990fc 100644 --- a/tests/skills/cases/cfe-borrow/newobjectposition-byname.json +++ b/tests/skills/cases/cfe-borrow/newobjectposition-byname.json @@ -3,25 +3,56 @@ "preRun": [ { "script": "meta-compile/scripts/meta-compile", - "input": { "type": "Catalog", "name": "Договоры" }, - "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + "input": { + "type": "Catalog", + "name": "Договоры" + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } }, { "script": "meta-compile/scripts/meta-compile", - "input": { "type": "Catalog", "name": "Терминалы", "owners": ["Catalog.Договоры"] }, - "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + "input": { + "type": "Catalog", + "name": "Терминалы", + "owners": [ + "Catalog.Договоры" + ] + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } }, { "script": "cfe-init/scripts/cfe-init", - "args": { "-Name": "Тест", "-OutputDir": "{workDir}/cfe", "-ConfigPath": "{workDir}" } + "args": { + "-Name": "Тест", + "-OutputDir": "{workDir}/cfe", + "-ConfigPath": "{workDir}" + } }, - { "writeFile": { "path": "cfe/.v8-project.json", "content": { "newObjectPosition": "byName", "databases": [] } } } + { + "writeFile": { + "path": ".v8-project.json", + "content": { + "newObjectPosition": "byName", + "databases": [] + } + } + } ], - "params": { "extensionPath": "cfe", "object": "Catalog.Терминалы" }, + "params": { + "extensionPath": "cfe", + "object": "Catalog.Терминалы" + }, "expect": { "fileContains": { "file": "cfe/Configuration.xml", "text": "Договоры\r\n\t\t\tТерминалы" } - } + }, + "cwd": "workDir" } diff --git a/tests/skills/cases/cfe-borrow/snapshots/newobjectposition-byname/cfe/.v8-project.json b/tests/skills/cases/cfe-borrow/snapshots/newobjectposition-byname/.v8-project.json similarity index 100% rename from tests/skills/cases/cfe-borrow/snapshots/newobjectposition-byname/cfe/.v8-project.json rename to tests/skills/cases/cfe-borrow/snapshots/newobjectposition-byname/.v8-project.json