mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-17 23:35:22 +03:00
Compare commits
36
Commits
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "cc-1c-skills",
|
||||||
|
"interface": {
|
||||||
|
"displayName": "1C Skills"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "1c-skills",
|
||||||
|
"source": {
|
||||||
|
"source": "url",
|
||||||
|
"url": "https://github.com/Nikolay-Shirokov/cc-1c-skills.git",
|
||||||
|
"ref": "port-codex"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"installation": "AVAILABLE"
|
||||||
|
},
|
||||||
|
"category": "Development"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "1c-skills-py",
|
||||||
|
"source": {
|
||||||
|
"source": "url",
|
||||||
|
"url": "https://github.com/Nikolay-Shirokov/cc-1c-skills.git",
|
||||||
|
"ref": "port-codex-py"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"installation": "AVAILABLE"
|
||||||
|
},
|
||||||
|
"category": "Development"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-marketplace-manifest.json",
|
||||||
|
"name": "cc-1c-skills",
|
||||||
|
"description": "Маркетплейс навыков для разработки на платформе 1С:Предприятие",
|
||||||
|
"owner": {
|
||||||
|
"name": "Nikolay Shirokov"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "1c-skills",
|
||||||
|
"source": "./",
|
||||||
|
"description": "[PowerShell] Навыки для разработки на 1С:Предприятие 8.3 — абстракции над XML-форматами и CLI конфигуратора, плюс глаза и руки для тестирования через веб-клиент."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "1c-skills-py",
|
||||||
|
"source": {
|
||||||
|
"source": "github",
|
||||||
|
"repo": "Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"ref": "port-claude-code-py"
|
||||||
|
},
|
||||||
|
"description": "[Python] То же — для Linux/Mac или когда PowerShell недоступен."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
||||||
|
"name": "1c-skills",
|
||||||
|
"description": "[PowerShell] Навыки для разработки на 1С:Предприятие 8.3 — абстракции над XML-форматами и CLI конфигуратора, плюс глаза и руки для тестирования через веб-клиент.",
|
||||||
|
"author": {
|
||||||
|
"name": "Nikolay Shirokov"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"repository": "https://github.com/Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"1c",
|
||||||
|
"1c-dev",
|
||||||
|
"cf",
|
||||||
|
"cfe",
|
||||||
|
"epf",
|
||||||
|
"erf",
|
||||||
|
"metadata",
|
||||||
|
"configuration",
|
||||||
|
"extension",
|
||||||
|
"form",
|
||||||
|
"report",
|
||||||
|
"skd",
|
||||||
|
"data-processor",
|
||||||
|
"mxl",
|
||||||
|
"web-client",
|
||||||
|
"testing",
|
||||||
|
"test-automation"
|
||||||
|
],
|
||||||
|
"skills": "./.claude/skills/"
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ allowed-tools:
|
|||||||
| `NoValidate` | Пропустить авто-валидацию |
|
| `NoValidate` | Пропустить авто-валидацию |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cf-edit/scripts/cf-edit.ps1 -ConfigPath '<path>' -Operation modify-property -Value 'Version=1.0.0.1'
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cf-edit.ps1" -ConfigPath '<path>' -Operation modify-property -Value 'Version=1.0.0.1'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Операции
|
## Операции
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cf-info/scripts/cf-info.ps1 -ConfigPath "<путь>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cf-info.ps1" -ConfigPath "<путь>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Три режима
|
## Три режима
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ allowed-tools:
|
|||||||
| `CompatibilityMode` | Режим совместимости (default: `Version8_3_24`) |
|
| `CompatibilityMode` | Режим совместимости (default: `Version8_3_24`) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cf-init/scripts/cf-init.ps1 -Name "МояКонфигурация"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cf-init.ps1" -Name "МояКонфигурация"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cf-validate/scripts/cf-validate.ps1 -ConfigPath "upload/cfempty"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cf-validate.ps1" -ConfigPath "upload/cfempty"
|
||||||
powershell.exe -NoProfile -File .claude/skills/cf-validate/scripts/cf-validate.ps1 -ConfigPath "upload/cfempty/Configuration.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cf-validate.ps1" -ConfigPath "upload/cfempty/Configuration.xml"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 -ExtensionPath src -ConfigPath C:\cfsrc\erp -Object "Catalog.Контрагенты"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-borrow.ps1" -ExtensionPath src -ConfigPath C:\cfsrc\erp -Object "Catalog.Контрагенты"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cfe-diff/scripts/cfe-diff.ps1 -ExtensionPath src -ConfigPath C:\cfsrc\erp -Mode A
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-diff.ps1" -ExtensionPath src -ConfigPath C:\cfsrc\erp -Mode A
|
||||||
```
|
```
|
||||||
|
|
||||||
## Mode A — обзор расширения
|
## Mode A — обзор расширения
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cfe-init/scripts/cfe-init.ps1 -Name "МоёРасширение"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-init.ps1" -Name "МоёРасширение"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cfe-patch-method/scripts/cfe-patch-method.ps1 -ExtensionPath src -ModulePath "Catalog.Контрагенты.ObjectModule" -MethodName "ПриЗаписи" -InterceptorType Before
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-patch-method.ps1" -ExtensionPath src -ModulePath "Catalog.Контрагенты.ObjectModule" -MethodName "ПриЗаписи" -InterceptorType Before
|
||||||
```
|
```
|
||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/cfe-validate/scripts/cfe-validate.ps1 -ExtensionPath "src"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-validate.ps1" -ExtensionPath "src"
|
||||||
powershell.exe -NoProfile -File .claude/skills/cfe-validate/scripts/cfe-validate.ps1 -ExtensionPath "src/Configuration.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-validate.ps1" -ExtensionPath "src/Configuration.xml"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-create/scripts/db-create.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-create.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -65,14 +65,14 @@ powershell.exe -NoProfile -File .claude/skills/db-create/scripts/db-create.ps1 <
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Создать файловую базу
|
# Создать файловую базу
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-create/scripts/db-create.ps1 -InfoBasePath "C:\Bases\NewDB"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-create.ps1" -InfoBasePath "C:\Bases\NewDB"
|
||||||
|
|
||||||
# Создать серверную базу
|
# Создать серверную базу
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-create/scripts/db-create.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Test"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-create.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Test"
|
||||||
|
|
||||||
# Создать из шаблона CF
|
# Создать из шаблона CF
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-create/scripts/db-create.ps1 -InfoBasePath "C:\Bases\NewDB" -UseTemplate "C:\Templates\config.cf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-create.ps1" -InfoBasePath "C:\Bases\NewDB" -UseTemplate "C:\Templates\config.cf"
|
||||||
|
|
||||||
# Создать и добавить в список баз
|
# Создать и добавить в список баз
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-create/scripts/db-create.ps1 -InfoBasePath "C:\Bases\NewDB" -AddToList -ListName "Новая база"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-create.ps1" -InfoBasePath "C:\Bases\NewDB" -AddToList -ListName "Новая база"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-cf/scripts/db-dump-cf.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-cf.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -69,11 +69,11 @@ powershell.exe -NoProfile -File .claude/skills/db-dump-cf/scripts/db-dump-cf.ps1
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Выгрузка конфигурации (файловая база)
|
# Выгрузка конфигурации (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-cf/scripts/db-dump-cf.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -OutputFile "C:\backup\config.cf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-cf.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -OutputFile "C:\backup\config.cf"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-cf/scripts/db-dump-cf.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Dev" -UserName "Admin" -Password "secret" -OutputFile "config.cf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-cf.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Dev" -UserName "Admin" -Password "secret" -OutputFile "config.cf"
|
||||||
|
|
||||||
# Выгрузка расширения
|
# Выгрузка расширения
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-cf/scripts/db-dump-cf.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -OutputFile "ext.cfe" -Extension "МоёРасширение"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-cf.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -OutputFile "ext.cfe" -Extension "МоёРасширение"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -81,17 +81,17 @@ powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.p
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Полная выгрузка (файловая база)
|
# Полная выгрузка (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.ps1 -V8Path "C:\Program Files\1cv8\8.3.25.1257\bin" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Full
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" -V8Path "C:\Program Files\1cv8\8.3.25.1257\bin" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Full
|
||||||
|
|
||||||
# Инкрементальная выгрузка
|
# Инкрементальная выгрузка
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Changes
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Changes
|
||||||
|
|
||||||
# Частичная выгрузка
|
# Частичная выгрузка
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Partial -Objects "Справочник.Номенклатура,Документ.Заказ"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Partial -Objects "Справочник.Номенклатура,Документ.Заказ"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Dev" -UserName "Admin" -Password "secret" -ConfigDir "C:\WS\cfsrc" -Mode Full
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Dev" -UserName "Admin" -Password "secret" -ConfigDir "C:\WS\cfsrc" -Mode Full
|
||||||
|
|
||||||
# Выгрузка расширения
|
# Выгрузка расширения
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-dump-xml/scripts/db-dump-xml.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\ext_src" -Mode Full -Extension "МоёРасширение"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\ext_src" -Mode Full -Extension "МоёРасширение"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-cf/scripts/db-load-cf.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-cf.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -71,11 +71,11 @@ powershell.exe -NoProfile -File .claude/skills/db-load-cf/scripts/db-load-cf.ps1
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Файловая база
|
# Файловая база
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-cf/scripts/db-load-cf.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -InputFile "C:\backup\config.cf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-cf.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -InputFile "C:\backup\config.cf"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-cf/scripts/db-load-cf.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Test" -UserName "Admin" -Password "secret" -InputFile "config.cf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-cf.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyApp_Test" -UserName "Admin" -Password "secret" -InputFile "config.cf"
|
||||||
|
|
||||||
# Загрузка расширения
|
# Загрузка расширения
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-cf/scripts/db-load-cf.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -InputFile "ext.cfe" -Extension "МоёРасширение"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-cf.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -InputFile "ext.cfe" -Extension "МоёРасширение"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,78 +1,78 @@
|
|||||||
---
|
---
|
||||||
name: db-load-git
|
name: db-load-git
|
||||||
description: Загрузка изменений из Git в базу 1С. Используй когда нужно загрузить изменения из гита, обновить базу из репозитория, partial load из коммита
|
description: Загрузка изменений из Git в базу 1С. Используй когда нужно загрузить изменения из гита, обновить базу из репозитория, partial load из коммита
|
||||||
argument-hint: "[database] [source]"
|
argument-hint: "[database] [source]"
|
||||||
allowed-tools:
|
allowed-tools:
|
||||||
- Bash
|
- Bash
|
||||||
- Read
|
- Read
|
||||||
- Glob
|
- Glob
|
||||||
- AskUserQuestion
|
- AskUserQuestion
|
||||||
---
|
---
|
||||||
|
|
||||||
# /db-load-git — Загрузка изменений из Git
|
# /db-load-git — Загрузка изменений из Git
|
||||||
|
|
||||||
Определяет изменённые файлы конфигурации по данным Git и выполняет частичную загрузку в информационную базу.
|
Определяет изменённые файлы конфигурации по данным Git и выполняет частичную загрузку в информационную базу.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
/db-load-git [database]
|
/db-load-git [database]
|
||||||
/db-load-git dev — все незафиксированные изменения
|
/db-load-git dev — все незафиксированные изменения
|
||||||
/db-load-git dev -Source Staged — только staged
|
/db-load-git dev -Source Staged — только staged
|
||||||
/db-load-git dev -Source Commit -CommitRange "HEAD~3..HEAD"
|
/db-load-git dev -Source Commit -CommitRange "HEAD~3..HEAD"
|
||||||
/db-load-git dev -DryRun — только показать что будет загружено
|
/db-load-git dev -DryRun — только показать что будет загружено
|
||||||
```
|
```
|
||||||
|
|
||||||
## Параметры подключения
|
## Параметры подключения
|
||||||
|
|
||||||
Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` (путь к платформе) и разреши базу:
|
Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` (путь к платформе) и разреши базу:
|
||||||
1. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
|
1. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
|
||||||
2. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
|
2. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
|
||||||
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
|
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
|
||||||
4. Если ветка не совпала — используй `default`
|
4. Если ветка не совпала — используй `default`
|
||||||
Если `v8path` не задан — автоопределение: `Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort -Desc | Select -First 1`
|
Если `v8path` не задан — автоопределение: `Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort -Desc | Select -First 1`
|
||||||
Если файла нет — предложи `/db-list add`.
|
Если файла нет — предложи `/db-list add`.
|
||||||
Если использованная база не зарегистрирована — после выполнения предложи добавить через `/db-list add`.
|
Если использованная база не зарегистрирована — после выполнения предложи добавить через `/db-list add`.
|
||||||
Если в записи базы указан `configSrc` — используй как каталог конфигурации.
|
Если в записи базы указан `configSrc` — используй как каталог конфигурации.
|
||||||
|
|
||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-git/scripts/db-load-git.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-git.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
|
|
||||||
| Параметр | Обязательный | Описание |
|
| Параметр | Обязательный | Описание |
|
||||||
|----------|:------------:|----------|
|
|----------|:------------:|----------|
|
||||||
| `-V8Path <путь>` | нет | Каталог bin платформы (или полный путь к 1cv8.exe) |
|
| `-V8Path <путь>` | нет | Каталог bin платформы (или полный путь к 1cv8.exe) |
|
||||||
| `-InfoBasePath <путь>` | * | Файловая база |
|
| `-InfoBasePath <путь>` | * | Файловая база |
|
||||||
| `-InfoBaseServer <сервер>` | * | Сервер 1С (для серверной базы) |
|
| `-InfoBaseServer <сервер>` | * | Сервер 1С (для серверной базы) |
|
||||||
| `-InfoBaseRef <имя>` | * | Имя базы на сервере |
|
| `-InfoBaseRef <имя>` | * | Имя базы на сервере |
|
||||||
| `-UserName <имя>` | нет | Имя пользователя |
|
| `-UserName <имя>` | нет | Имя пользователя |
|
||||||
| `-Password <пароль>` | нет | Пароль |
|
| `-Password <пароль>` | нет | Пароль |
|
||||||
| `-ConfigDir <путь>` | да | Каталог XML-выгрузки (git-репозиторий) |
|
| `-ConfigDir <путь>` | да | Каталог XML-выгрузки (git-репозиторий) |
|
||||||
| `-Source <источник>` | нет | `All` (по умолч.) / `Staged` / `Unstaged` / `Commit` |
|
| `-Source <источник>` | нет | `All` (по умолч.) / `Staged` / `Unstaged` / `Commit` |
|
||||||
| `-CommitRange <range>` | для Commit | Диапазон коммитов (напр. `HEAD~3..HEAD`) |
|
| `-CommitRange <range>` | для Commit | Диапазон коммитов (напр. `HEAD~3..HEAD`) |
|
||||||
| `-Extension <имя>` | нет | Загрузить в расширение |
|
| `-Extension <имя>` | нет | Загрузить в расширение |
|
||||||
| `-AllExtensions` | нет | Загрузить все расширения |
|
| `-AllExtensions` | нет | Загрузить все расширения |
|
||||||
| `-Format <формат>` | нет | `Hierarchical` (по умолч.) / `Plain` |
|
| `-Format <формат>` | нет | `Hierarchical` (по умолч.) / `Plain` |
|
||||||
| `-DryRun` | нет | Только показать что будет загружено (без загрузки) |
|
| `-DryRun` | нет | Только показать что будет загружено (без загрузки) |
|
||||||
| `-UpdateDB` | нет | После загрузки сразу обновить конфигурацию БД (`/UpdateDBCfg`) |
|
| `-UpdateDB` | нет | После загрузки сразу обновить конфигурацию БД (`/UpdateDBCfg`) |
|
||||||
|
|
||||||
> `*` — нужен либо `-InfoBasePath`, либо пара `-InfoBaseServer` + `-InfoBaseRef`
|
> `*` — нужен либо `-InfoBasePath`, либо пара `-InfoBaseServer` + `-InfoBaseRef`
|
||||||
|
|
||||||
## После выполнения
|
## После выполнения
|
||||||
|
|
||||||
1. Показать список загруженных файлов и результат из лога
|
1. Показать список загруженных файлов и результат из лога
|
||||||
2. Если `-UpdateDB` не был указан — **предложить `/db-update`** для применения изменений к БД
|
2. Если `-UpdateDB` не был указан — **предложить `/db-update`** для применения изменений к БД
|
||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Все незафиксированные изменения
|
# Все незафиксированные изменения
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-git/scripts/db-load-git.ps1 -V8Path "C:\Program Files\1cv8\8.3.25.1257\bin" -InfoBasePath "C:\Bases\MyDB" -ConfigDir "C:\WS\cfsrc" -Source All -UpdateDB
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-git.ps1" -V8Path "C:\Program Files\1cv8\8.3.25.1257\bin" -InfoBasePath "C:\Bases\MyDB" -ConfigDir "C:\WS\cfsrc" -Source All -UpdateDB
|
||||||
|
|
||||||
# Из диапазона коммитов
|
# Из диапазона коммитов
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-git/scripts/db-load-git.ps1 -InfoBasePath "C:\Bases\MyDB" -ConfigDir "C:\WS\cfsrc" -Source Commit -CommitRange "HEAD~3..HEAD"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-git.ps1" -InfoBasePath "C:\Bases\MyDB" -ConfigDir "C:\WS\cfsrc" -Source Commit -CommitRange "HEAD~3..HEAD"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-xml/scripts/db-load-xml.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-xml.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -96,14 +96,14 @@ Documents/Заказ/Forms/ФормаДокумента.xml
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Полная загрузка
|
# Полная загрузка
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-xml/scripts/db-load-xml.ps1 -V8Path "C:\Program Files\1cv8\8.3.25.1257\bin" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Full
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-xml.ps1" -V8Path "C:\Program Files\1cv8\8.3.25.1257\bin" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Full
|
||||||
|
|
||||||
# Частичная загрузка конкретных файлов
|
# Частичная загрузка конкретных файлов
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-xml/scripts/db-load-xml.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Partial -Files "Catalogs/Номенклатура.xml,Catalogs/Номенклатура/Ext/ObjectModule.bsl"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-xml.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Partial -Files "Catalogs/Номенклатура.xml,Catalogs/Номенклатура/Ext/ObjectModule.bsl"
|
||||||
|
|
||||||
# Загрузка расширения
|
# Загрузка расширения
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-xml/scripts/db-load-xml.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\ext_src" -Mode Full -Extension "МоёРасширение"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-xml.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\ext_src" -Mode Full -Extension "МоёРасширение"
|
||||||
|
|
||||||
# Загрузка + обновление БД в одном запуске
|
# Загрузка + обновление БД в одном запуске
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-load-xml/scripts/db-load-xml.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Full -UpdateDB
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-load-xml.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -ConfigDir "C:\WS\cfsrc" -Mode Full -UpdateDB
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-run/scripts/db-run.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-run.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -63,14 +63,14 @@ powershell.exe -NoProfile -File .claude/skills/db-run/scripts/db-run.ps1 <пар
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Простой запуск
|
# Простой запуск
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-run/scripts/db-run.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-run.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin"
|
||||||
|
|
||||||
# Запуск с обработкой
|
# Запуск с обработкой
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-run/scripts/db-run.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -Execute "C:\epf\МояОбработка.epf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-run.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -Execute "C:\epf\МояОбработка.epf"
|
||||||
|
|
||||||
# Открыть по навигационной ссылке
|
# Открыть по навигационной ссылке
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-run/scripts/db-run.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -URL "e1cib/data/Справочник.Номенклатура"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-run.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -URL "e1cib/data/Справочник.Номенклатура"
|
||||||
|
|
||||||
# Серверная база с параметром запуска
|
# Серверная база с параметром запуска
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-run/scripts/db-run.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -CParam "ЗапуститьОбновление"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-run.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -CParam "ЗапуститьОбновление"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-update/scripts/db-update.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-update.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -83,11 +83,11 @@ powershell.exe -NoProfile -File .claude/skills/db-update/scripts/db-update.ps1 <
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Обычное обновление (файловая база)
|
# Обычное обновление (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-update/scripts/db-update.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-update.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin"
|
||||||
|
|
||||||
# Динамическое обновление (серверная база)
|
# Динамическое обновление (серверная база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-update/scripts/db-update.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -Dynamic "+"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-update.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -Dynamic "+"
|
||||||
|
|
||||||
# Обновление расширения
|
# Обновление расширения
|
||||||
powershell.exe -NoProfile -File .claude/skills/db-update/scripts/db-update.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -Extension "МоёРасширение"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-update.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin" -Extension "МоёРасширение"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-build.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -62,8 +62,8 @@ powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Сборка обработки (файловая база)
|
# Сборка обработки (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 -InfoBasePath "C:\Bases\MyDB" -SourceFile "src/МояОбработка.xml" -OutputFile "build/МояОбработка.epf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-build.ps1" -InfoBasePath "C:\Bases\MyDB" -SourceFile "src/МояОбработка.xml" -OutputFile "build/МояОбработка.epf"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -SourceFile "src/МояОбработка.xml" -OutputFile "build/МояОбработка.epf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-build.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -SourceFile "src/МояОбработка.xml" -OutputFile "build/МояОбработка.epf"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-dump.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -62,8 +62,8 @@ powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 <п
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Разборка обработки (файловая база)
|
# Разборка обработки (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 -InfoBasePath "C:\Bases\MyDB" -InputFile "build/МояОбработка.epf" -OutputDir "src"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-dump.ps1" -InfoBasePath "C:\Bases\MyDB" -InputFile "build/МояОбработка.epf" -OutputDir "src"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -InputFile "build/МояОбработка.epf" -OutputDir "src"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-dump.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -InputFile "build/МояОбработка.epf" -OutputDir "src"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-init/scripts/init.ps1 -Name "<Name>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/init.ps1" -Name "<Name>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Дальнейшие шаги
|
## Дальнейшие шаги
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# epf-init v1.0 — Init 1C external data processor scaffold
|
# epf-init v1.1 — Init 1C external data processor scaffold
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -10,6 +10,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
$uuid1 = [guid]::NewGuid().ToString()
|
$uuid1 = [guid]::NewGuid().ToString()
|
||||||
$uuid2 = [guid]::NewGuid().ToString()
|
$uuid2 = [guid]::NewGuid().ToString()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# epf-init v1.0 — Init 1C external data processor scaffold
|
# epf-init v1.1 — Init 1C external data processor scaffold
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
"""Generates minimal XML source files for a 1C external data processor."""
|
"""Generates minimal XML source files for a 1C external data processor."""
|
||||||
import sys, os, argparse, uuid
|
import sys, os, argparse, uuid
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-validate/scripts/epf-validate.ps1 -ObjectPath "src/МояОбработка"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-validate.ps1" -ObjectPath "src/МояОбработка"
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-validate/scripts/epf-validate.ps1 -ObjectPath "src/МояОбработка/МояОбработка.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/epf-validate.ps1" -ObjectPath "src/МояОбработка/МояОбработка.xml"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ allowed-tools:
|
|||||||
Используй общий скрипт из epf-build:
|
Используй общий скрипт из epf-build:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-build/scripts/epf-build.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -64,8 +64,8 @@ powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Сборка отчёта (файловая база)
|
# Сборка отчёта (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 -InfoBasePath "C:\Bases\MyDB" -SourceFile "src/МойОтчёт.xml" -OutputFile "build/МойОтчёт.erf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-build/scripts/epf-build.ps1" -InfoBasePath "C:\Bases\MyDB" -SourceFile "src/МойОтчёт.xml" -OutputFile "build/МойОтчёт.erf"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -SourceFile "src/МойОтчёт.xml" -OutputFile "build/МойОтчёт.erf"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-build/scripts/epf-build.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -SourceFile "src/МойОтчёт.xml" -OutputFile "build/МойОтчёт.erf"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ allowed-tools:
|
|||||||
Используй общий скрипт из epf-dump:
|
Используй общий скрипт из epf-dump:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-dump/scripts/epf-dump.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -64,8 +64,8 @@ powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 <п
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Разборка отчёта (файловая база)
|
# Разборка отчёта (файловая база)
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 -InfoBasePath "C:\Bases\MyDB" -InputFile "build/МойОтчёт.erf" -OutputDir "src"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-dump/scripts/epf-dump.ps1" -InfoBasePath "C:\Bases\MyDB" -InputFile "build/МойОтчёт.erf" -OutputDir "src"
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -InputFile "build/МойОтчёт.erf" -OutputDir "src"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-dump/scripts/epf-dump.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret" -InputFile "build/МойОтчёт.erf" -OutputDir "src"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/erf-init/scripts/init.ps1 -Name "<Name>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"] [-WithSKD]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/init.ps1" -Name "<Name>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"] [-WithSKD]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Дальнейшие шаги
|
## Дальнейшие шаги
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# erf-init v1.0 — Init 1C external report scaffold
|
# erf-init v1.1 — Init 1C external report scaffold
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -12,6 +12,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
$uuid1 = [guid]::NewGuid().ToString()
|
$uuid1 = [guid]::NewGuid().ToString()
|
||||||
$uuid2 = [guid]::NewGuid().ToString()
|
$uuid2 = [guid]::NewGuid().ToString()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# erf-init v1.0 — Init 1C external report scaffold
|
# erf-init v1.1 — Init 1C external report scaffold
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
"""Generates minimal XML source files for a 1C external report."""
|
"""Generates minimal XML source files for a 1C external report."""
|
||||||
import sys, os, argparse, uuid
|
import sys, os, argparse, uuid
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-validate/scripts/epf-validate.ps1 -ObjectPath "src/МойОтчёт"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-validate/scripts/epf-validate.ps1" -ObjectPath "src/МойОтчёт"
|
||||||
powershell.exe -NoProfile -File .claude/skills/epf-validate/scripts/epf-validate.ps1 -ObjectPath "src/МойОтчёт/МойОтчёт.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/../epf-validate/scripts/epf-validate.ps1" -ObjectPath "src/МойОтчёт/МойОтчёт.xml"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-add/scripts/form-add.ps1 -ObjectPath "<ObjectPath>" -FormName "<FormName>" [-Purpose "<Purpose>"] [-Synonym "<Synonym>"] [-SetDefault]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-add.ps1" -ObjectPath "<ObjectPath>" -FormName "<FormName>" [-Purpose "<Purpose>"] [-Synonym "<Synonym>"] [-SetDefault]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Purpose — назначение формы
|
## Purpose — назначение формы
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-add v1.4 — Add managed form to 1C config object
|
# form-add v1.5 — Add managed form to 1C config object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -15,6 +15,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
# --- Detect XML format version ---
|
# --- Detect XML format version ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# form-add v1.4 — Add managed form to 1C config object
|
# form-add v1.5 — Add managed form to 1C config object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ allowed-tools:
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Режим JSON DSL
|
# Режим JSON DSL
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile.ps1 -JsonPath "<json>" -OutputPath "<Form.xml>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -JsonPath "<json>" -OutputPath "<Form.xml>"
|
||||||
|
|
||||||
# Режим from-object (объект и purpose выводятся из OutputPath; Document и Catalog)
|
# Режим from-object (объект и purpose выводятся из OutputPath; Document и Catalog)
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile.ps1 -FromObject -OutputPath "<.../TypePlural/ObjectName/Forms/FormName/Ext/Form.xml>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-compile.ps1" -FromObject -OutputPath "<.../TypePlural/ObjectName/Forms/FormName/Ext/Form.xml>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## JSON DSL — справка
|
## JSON DSL — справка
|
||||||
@@ -62,8 +62,10 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
| DSL ключ | XML элемент | Значение ключа |
|
| DSL ключ | XML элемент | Значение ключа |
|
||||||
|--------------|-------------------|---------------------------------------------------|
|
|--------------|-------------------|---------------------------------------------------|
|
||||||
| `"group"` | UsualGroup | `"horizontal"` / `"vertical"` / `"alwaysHorizontal"` / `"alwaysVertical"` / `"collapsible"` |
|
| `"group"` | UsualGroup | `"horizontal"` / `"vertical"` / `"alwaysHorizontal"` / `"alwaysVertical"` / `"collapsible"` |
|
||||||
|
| `"columnGroup"` | ColumnGroup | `"horizontal"` / `"vertical"` / `"inCell"` — только внутри `columns` таблицы |
|
||||||
| `"input"` | InputField | имя элемента |
|
| `"input"` | InputField | имя элемента |
|
||||||
| `"check"` | CheckBoxField | имя |
|
| `"check"` | CheckBoxField | имя |
|
||||||
|
| `"radio"` | RadioButtonField | имя |
|
||||||
| `"label"` | LabelDecoration | имя (текст задаётся через `title`) |
|
| `"label"` | LabelDecoration | имя (текст задаётся через `title`) |
|
||||||
| `"labelField"` | LabelField | имя |
|
| `"labelField"` | LabelField | имя |
|
||||||
| `"table"` | Table | имя |
|
| `"table"` | Table | имя |
|
||||||
@@ -97,7 +99,7 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
|
|
||||||
**input / picField**: `OnChange`, `StartChoice`, `ChoiceProcessing`, `AutoComplete`, `TextEditEnd`, `Clearing`, `Creating`, `EditTextChange`
|
**input / picField**: `OnChange`, `StartChoice`, `ChoiceProcessing`, `AutoComplete`, `TextEditEnd`, `Clearing`, `Creating`, `EditTextChange`
|
||||||
|
|
||||||
**check**: `OnChange`
|
**check / radio**: `OnChange`
|
||||||
|
|
||||||
**table**: `OnStartEdit`, `OnEditEnd`, `OnChange`, `Selection`, `ValueChoice`, `BeforeAddRow`, `BeforeDeleteRow`, `AfterDeleteRow`, `BeforeRowChange`, `BeforeEditEnd`, `OnActivateRow`, `OnActivateCell`, `Drag`, `DragStart`, `DragCheck`, `DragEnd`
|
**table**: `OnStartEdit`, `OnEditEnd`, `OnChange`, `Selection`, `ValueChoice`, `BeforeAddRow`, `BeforeDeleteRow`, `AfterDeleteRow`, `BeforeRowChange`, `BeforeEditEnd`, `OnActivateRow`, `OnActivateCell`, `Drag`, `DragStart`, `DragCheck`, `DragEnd`
|
||||||
|
|
||||||
@@ -125,7 +127,8 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
| `skipOnInput: true` | Пропускать при обходе Tab | |
|
| `skipOnInput: true` | Пропускать при обходе Tab | |
|
||||||
| `inputHint` | Подсказка в пустом поле | `"Введите наименование..."` |
|
| `inputHint` | Подсказка в пустом поле | `"Введите наименование..."` |
|
||||||
| `width` / `height` | Размер | числа |
|
| `width` / `height` | Размер | числа |
|
||||||
| `autoMaxWidth: false` | Отключить авто-ширину | для фиксированных полей |
|
| `autoMaxWidth: false` | Снять авто-ограничение ширины (поле растянется) | |
|
||||||
|
| `maxWidth` / `maxHeight` | Жёсткое ограничение размера | числа; обычно вместе с `autoMaxWidth: false` |
|
||||||
| `horizontalStretch: true` | Растягивать по ширине | |
|
| `horizontalStretch: true` | Растягивать по ширине | |
|
||||||
|
|
||||||
### Чекбокс (check)
|
### Чекбокс (check)
|
||||||
@@ -135,6 +138,37 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
| `path` | DataPath |
|
| `path` | DataPath |
|
||||||
| `titleLocation` | Размещение заголовка |
|
| `titleLocation` | Размещение заголовка |
|
||||||
|
|
||||||
|
### Поле переключателя (radio)
|
||||||
|
|
||||||
|
Радиокнопки или тумблер для выбора одного значения из списка.
|
||||||
|
|
||||||
|
| Ключ | Описание | Пример |
|
||||||
|
|------|----------|--------|
|
||||||
|
| `path` | DataPath — привязка к реквизиту | `"СпособКурса"` |
|
||||||
|
| `radioButtonType` | Вид переключателя | `"Auto"` (по умолчанию), `"RadioButtons"`, `"Tumbler"` |
|
||||||
|
| `columnsCount` | Число колонок раскладки | `1`, `2`, ... |
|
||||||
|
| `titleLocation` | Размещение заголовка | по умолчанию `"none"` |
|
||||||
|
| `choiceList` | Список вариантов: массив `{value, presentation}` | см. ниже |
|
||||||
|
|
||||||
|
`choiceList[*]`:
|
||||||
|
|
||||||
|
| Ключ | Описание |
|
||||||
|
|------|----------|
|
||||||
|
| `value` | Значение варианта. Строка/число/булево; для перечисления — `"Enum.ИмяТипа.EnumValue.ИмяЗначения"` |
|
||||||
|
| `presentation` | Текст рядом с переключателем. Строка (русский) либо объект `{ru, en, ...}` для мультиязычности |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"radio": "СпособКурса",
|
||||||
|
"path": "Объект.СпособУстановкиКурса",
|
||||||
|
"radioButtonType": "Auto",
|
||||||
|
"choiceList": [
|
||||||
|
{ "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": { "ru": "Автоматически", "en": "Automatic" } },
|
||||||
|
{ "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Надпись-декорация (label)
|
### Надпись-декорация (label)
|
||||||
|
|
||||||
| Ключ | Описание |
|
| Ключ | Описание |
|
||||||
@@ -150,7 +184,8 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
| Ключ | Описание |
|
| Ключ | Описание |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| `showTitle: true` | Показывать заголовок группы |
|
| `showTitle: true` | Показывать заголовок группы |
|
||||||
| `united: false` | Не объединять рамку |
|
| `united: false` | Левый край полей ввода выравнивается только в пределах этой группы (по умолчанию `true` — сквозное выравнивание по самому длинному заголовку, в т.ч. с соседними группами) |
|
||||||
|
| `collapsed: true` | Только для `"group": "collapsible"` — группа создаётся свёрнутой |
|
||||||
| `representation` | `"none"`, `"normal"`, `"weak"`, `"strong"` |
|
| `representation` | `"none"`, `"normal"`, `"weak"`, `"strong"` |
|
||||||
| `children: [...]` | Вложенные элементы |
|
| `children: [...]` | Вложенные элементы |
|
||||||
|
|
||||||
@@ -176,6 +211,35 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
| `rowPictureDataPath` | Путь к картинке строки (напр. `"Список.DefaultPicture"`) |
|
| `rowPictureDataPath` | Путь к картинке строки (напр. `"Список.DefaultPicture"`) |
|
||||||
| `tableAutofill: false` | Управление Autofill внутреннего AutoCommandBar |
|
| `tableAutofill: false` | Управление Autofill внутреннего AutoCommandBar |
|
||||||
|
|
||||||
|
Колонки можно группировать через `columnGroup` (см. ниже).
|
||||||
|
|
||||||
|
### Группа колонок (columnGroup)
|
||||||
|
|
||||||
|
Используется только внутри `columns` таблицы. Значение ключа задаёт ориентацию: `"horizontal"`, `"vertical"`, `"inCell"` (склеивает колонки в одну ячейку шапки). Допускается вложение `columnGroup` в `columnGroup`.
|
||||||
|
|
||||||
|
| Ключ | Описание |
|
||||||
|
|------|----------|
|
||||||
|
| `name` | Имя элемента (рекомендуется задавать явно) |
|
||||||
|
| `title` | Заголовок группы |
|
||||||
|
| `showTitle: false` | Скрыть заголовок |
|
||||||
|
| `showInHeader: true/false` | Показывать ли группу в шапке таблицы |
|
||||||
|
| `width` | Ширина |
|
||||||
|
| `horizontalStretch: false` | Растягивание |
|
||||||
|
| `children: [...]` | Колонки внутри группы (`input`, `labelField`, `picField`, вложенный `columnGroup` …) |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список", "columns": [
|
||||||
|
{ "columnGroup": "horizontal", "name": "ГруппаДата", "title": "Срок", "children": [
|
||||||
|
{ "input": "СрокИсполнения", "path": "Список.СрокИсполнения" },
|
||||||
|
{ "labelField": "Просрочено", "path": "Список.Просрочено" }
|
||||||
|
]},
|
||||||
|
{ "columnGroup": "inCell", "name": "ГруппаИсполнитель", "showInHeader": true, "children": [
|
||||||
|
{ "input": "Исполнитель", "path": "Список.Исполнитель" }
|
||||||
|
]},
|
||||||
|
{ "input": "Комментарий", "path": "Список.Комментарий" }
|
||||||
|
]}
|
||||||
|
```
|
||||||
|
|
||||||
### Страницы (pages + page)
|
### Страницы (pages + page)
|
||||||
|
|
||||||
| Ключ (pages) | Описание |
|
| Ключ (pages) | Описание |
|
||||||
@@ -196,7 +260,7 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
| `command` | Имя команды формы → `Form.Command.Имя` |
|
| `command` | Имя команды формы → `Form.Command.Имя` |
|
||||||
| `stdCommand` | Стандартная команда: `"Close"` → `Form.StandardCommand.Close`; с точкой: `"Товары.Add"` → `Form.Item.Товары.StandardCommand.Add` |
|
| `stdCommand` | Стандартная команда: `"Close"` → `Form.StandardCommand.Close`; с точкой: `"Товары.Add"` → `Form.Item.Товары.StandardCommand.Add` |
|
||||||
| `defaultButton: true` | Кнопка по умолчанию |
|
| `defaultButton: true` | Кнопка по умолчанию |
|
||||||
| `type` | `"usual"`, `"hyperlink"`, `"commandBar"` |
|
| `type` | `"usual"`, `"hyperlink"`. По умолчанию `"usual"`. Конкретный XML-вид (UsualButton/Hyperlink/CommandBarButton/CommandBarHyperlink) подставляется автоматически по контексту |
|
||||||
| `picture` | Картинка кнопки |
|
| `picture` | Картинка кнопки |
|
||||||
| `representation` | `"Auto"`, `"Text"`, `"Picture"`, `"PictureAndText"` |
|
| `representation` | `"Auto"`, `"Text"`, `"Picture"`, `"PictureAndText"` |
|
||||||
| `locationInCommandBar` | `"Auto"`, `"InCommandBar"`, `"InAdditionalSubmenu"` |
|
| `locationInCommandBar` | `"Auto"`, `"InCommandBar"`, `"InAdditionalSubmenu"` |
|
||||||
@@ -227,6 +291,8 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
]}
|
]}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Кнопки основных действий формы и подменю размещают здесь, а не в отдельной группе на форме. Отдельной кнопкой в layout — только если она логически привязана к конкретному полю или группе.
|
||||||
|
|
||||||
### Выпадающее меню (popup)
|
### Выпадающее меню (popup)
|
||||||
|
|
||||||
| Ключ | Описание |
|
| Ключ | Описание |
|
||||||
@@ -369,9 +435,9 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile
|
|||||||
{ "check": "ПерваяСтрокаЗаголовок", "path": "ПерваяСтрокаЗаголовок" }
|
{ "check": "ПерваяСтрокаЗаголовок", "path": "ПерваяСтрокаЗаголовок" }
|
||||||
]},
|
]},
|
||||||
{ "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true, "title": "Лог" },
|
{ "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true, "title": "Лог" },
|
||||||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
{ "autoCmdBar": "ФормаКоманднаяПанель", "children": [
|
||||||
{ "button": "Загрузить", "command": "Загрузить", "defaultButton": true },
|
{ "button": "Загрузить", "command": "Загрузить", "defaultButton": true },
|
||||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
{ "button": "Закрыть", "stdCommand": "Close" }
|
||||||
]}
|
]}
|
||||||
],
|
],
|
||||||
"attributes": [
|
"attributes": [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-compile v1.9 — Compile 1C managed form from JSON or object metadata
|
# form-compile v1.20 — Compile 1C managed form from JSON or object metadata
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[string]$JsonPath,
|
[string]$JsonPath,
|
||||||
@@ -668,6 +668,7 @@ function Generate-DocumentListDSL($meta, [hashtable]$p) {
|
|||||||
|
|
||||||
$tableEl = [ordered]@{
|
$tableEl = [ordered]@{
|
||||||
table = "Список"; path = "Список"
|
table = "Список"; path = "Список"
|
||||||
|
rowPictureDataPath = "Список.DefaultPicture"
|
||||||
commandBarLocation = "None"
|
commandBarLocation = "None"
|
||||||
tableAutofill = $false
|
tableAutofill = $false
|
||||||
columns = $columns
|
columns = $columns
|
||||||
@@ -1003,6 +1004,7 @@ function Generate-InformationRegisterListDSL($meta, [hashtable]$p) {
|
|||||||
|
|
||||||
$tableEl = [ordered]@{
|
$tableEl = [ordered]@{
|
||||||
table = "Список"; path = "Список"
|
table = "Список"; path = "Список"
|
||||||
|
rowPictureDataPath = "Список.DefaultPicture"
|
||||||
commandBarLocation = "None"
|
commandBarLocation = "None"
|
||||||
tableAutofill = $false
|
tableAutofill = $false
|
||||||
columns = $columns
|
columns = $columns
|
||||||
@@ -1060,6 +1062,7 @@ function Generate-AccumulationRegisterListDSL($meta, [hashtable]$p) {
|
|||||||
|
|
||||||
$tableEl = [ordered]@{
|
$tableEl = [ordered]@{
|
||||||
table = "Список"; path = "Список"
|
table = "Список"; path = "Список"
|
||||||
|
rowPictureDataPath = "Список.DefaultPicture"
|
||||||
commandBarLocation = "None"
|
commandBarLocation = "None"
|
||||||
tableAutofill = $false
|
tableAutofill = $false
|
||||||
columns = $columns
|
columns = $columns
|
||||||
@@ -1771,6 +1774,7 @@ function Get-ElementName {
|
|||||||
$script:knownEvents = @{
|
$script:knownEvents = @{
|
||||||
"input" = @("OnChange","StartChoice","ChoiceProcessing","AutoComplete","TextEditEnd","Clearing","Creating","EditTextChange")
|
"input" = @("OnChange","StartChoice","ChoiceProcessing","AutoComplete","TextEditEnd","Clearing","Creating","EditTextChange")
|
||||||
"check" = @("OnChange")
|
"check" = @("OnChange")
|
||||||
|
"radio" = @("OnChange")
|
||||||
"label" = @("Click","URLProcessing")
|
"label" = @("Click","URLProcessing")
|
||||||
"labelField"= @("OnChange","StartChoice","ChoiceProcessing","Click","URLProcessing","Clearing")
|
"labelField"= @("OnChange","StartChoice","ChoiceProcessing","Click","URLProcessing","Clearing")
|
||||||
"table" = @("Selection","BeforeAddRow","AfterDeleteRow","BeforeDeleteRow","OnActivateRow","OnEditEnd","OnStartEdit","BeforeRowChange","BeforeEditEnd","ValueChoice","OnActivateCell","OnActivateField","Drag","DragStart","DragCheck","DragEnd","OnGetDataAtServer","BeforeLoadUserSettingsAtServer","OnUpdateUserSettingSetAtServer","OnChange")
|
"table" = @("Selection","BeforeAddRow","AfterDeleteRow","BeforeDeleteRow","OnActivateRow","OnEditEnd","OnStartEdit","BeforeRowChange","BeforeEditEnd","ValueChoice","OnActivateCell","OnActivateField","Drag","DragStart","DragCheck","DragEnd","OnGetDataAtServer","BeforeLoadUserSettingsAtServer","OnUpdateUserSettingSetAtServer","OnChange")
|
||||||
@@ -1821,11 +1825,47 @@ function Emit-Companion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Emit-Element {
|
function Emit-Element {
|
||||||
param($el, [string]$indent)
|
param($el, [string]$indent, [bool]$inCmdBar = $false)
|
||||||
|
|
||||||
# Silent synonyms: commandBar -> cmdBar, autoCommandBar -> autoCmdBar
|
# Silent synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio).
|
||||||
# (autoCmdBar inside def.elements is normally extracted in pre-pass; this is a safety net for nested cases)
|
# Maps any synonym to canonical short DSL key.
|
||||||
$synonyms = @{ "commandBar" = "cmdBar"; "autoCommandBar" = "autoCmdBar" }
|
$synonyms = @{
|
||||||
|
"commandBar" = "cmdBar"
|
||||||
|
"autoCommandBar" = "autoCmdBar"
|
||||||
|
"КоманднаяПанель" = "cmdBar"
|
||||||
|
"InputField" = "input"
|
||||||
|
"ПолеВвода" = "input"
|
||||||
|
"CheckBoxField" = "check"
|
||||||
|
"ПолеФлажка" = "check"
|
||||||
|
"RadioButtonField" = "radio"
|
||||||
|
"ПолеПереключателя" = "radio"
|
||||||
|
"radioButton" = "radio"
|
||||||
|
"PictureField" = "picField"
|
||||||
|
"ПолеКартинки" = "picField"
|
||||||
|
"LabelField" = "labelField"
|
||||||
|
"ПолеНадписи" = "labelField"
|
||||||
|
"CalendarField" = "calendar"
|
||||||
|
"ПолеКалендаря" = "calendar"
|
||||||
|
"LabelDecoration" = "label"
|
||||||
|
"Надпись" = "label"
|
||||||
|
"PictureDecoration" = "picture"
|
||||||
|
"Картинка" = "picture"
|
||||||
|
"UsualGroup" = "group"
|
||||||
|
"Группа" = "group"
|
||||||
|
"ОбычнаяГруппа" = "group"
|
||||||
|
"ColumnGroup" = "columnGroup"
|
||||||
|
"ГруппаКолонок" = "columnGroup"
|
||||||
|
"Pages" = "pages"
|
||||||
|
"ГруппаСтраниц" = "pages"
|
||||||
|
"Page" = "page"
|
||||||
|
"Страница" = "page"
|
||||||
|
"Table" = "table"
|
||||||
|
"Таблица" = "table"
|
||||||
|
"Button" = "button"
|
||||||
|
"Кнопка" = "button"
|
||||||
|
"Popup" = "popup"
|
||||||
|
"ВсплывающееМеню" = "popup"
|
||||||
|
}
|
||||||
foreach ($pair in $synonyms.GetEnumerator()) {
|
foreach ($pair in $synonyms.GetEnumerator()) {
|
||||||
if ($null -ne $el.PSObject.Properties[$pair.Key] -and $null -eq $el.PSObject.Properties[$pair.Value]) {
|
if ($null -ne $el.PSObject.Properties[$pair.Key] -and $null -eq $el.PSObject.Properties[$pair.Value]) {
|
||||||
$val = $el.($pair.Key)
|
$val = $el.($pair.Key)
|
||||||
@@ -1838,7 +1878,7 @@ function Emit-Element {
|
|||||||
$typeKey = $null
|
$typeKey = $null
|
||||||
$xmlTag = $null
|
$xmlTag = $null
|
||||||
|
|
||||||
foreach ($key in @("group","input","check","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) {
|
foreach ($key in @("columnGroup","group","input","check","radio","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) {
|
||||||
if ($el.$key -ne $null) {
|
if ($el.$key -ne $null) {
|
||||||
$typeKey = $key
|
$typeKey = $key
|
||||||
break
|
break
|
||||||
@@ -1853,8 +1893,12 @@ function Emit-Element {
|
|||||||
# Validate known keys — warn about typos and unknown properties
|
# Validate known keys — warn about typos and unknown properties
|
||||||
$knownKeys = @{
|
$knownKeys = @{
|
||||||
# type keys
|
# type keys
|
||||||
"group"=1;"input"=1;"check"=1;"label"=1;"labelField"=1;"table"=1;"pages"=1;"page"=1
|
"group"=1;"columnGroup"=1;"input"=1;"check"=1;"radio"=1;"label"=1;"labelField"=1;"table"=1;"pages"=1;"page"=1
|
||||||
"button"=1;"picture"=1;"picField"=1;"calendar"=1;"cmdBar"=1;"popup"=1
|
"button"=1;"picture"=1;"picField"=1;"calendar"=1;"cmdBar"=1;"popup"=1
|
||||||
|
# columnGroup-specific
|
||||||
|
"showInHeader"=1
|
||||||
|
# radio-specific
|
||||||
|
"radioButtonType"=1;"choiceList"=1;"columnsCount"=1
|
||||||
# naming & binding
|
# naming & binding
|
||||||
"name"=1;"path"=1;"title"=1
|
"name"=1;"path"=1;"title"=1
|
||||||
# visibility & state
|
# visibility & state
|
||||||
@@ -1864,13 +1908,14 @@ function Emit-Element {
|
|||||||
# layout
|
# layout
|
||||||
"titleLocation"=1;"representation"=1;"width"=1;"height"=1
|
"titleLocation"=1;"representation"=1;"width"=1;"height"=1
|
||||||
"horizontalStretch"=1;"verticalStretch"=1;"autoMaxWidth"=1;"autoMaxHeight"=1
|
"horizontalStretch"=1;"verticalStretch"=1;"autoMaxWidth"=1;"autoMaxHeight"=1
|
||||||
|
"maxWidth"=1;"maxHeight"=1
|
||||||
# input-specific
|
# input-specific
|
||||||
"multiLine"=1;"passwordMode"=1;"choiceButton"=1;"clearButton"=1
|
"multiLine"=1;"passwordMode"=1;"choiceButton"=1;"clearButton"=1
|
||||||
"spinButton"=1;"dropListButton"=1;"markIncomplete"=1;"skipOnInput"=1;"inputHint"=1
|
"spinButton"=1;"dropListButton"=1;"markIncomplete"=1;"skipOnInput"=1;"inputHint"=1
|
||||||
# label/hyperlink
|
# label/hyperlink
|
||||||
"hyperlink"=1
|
"hyperlink"=1
|
||||||
# group-specific
|
# group-specific
|
||||||
"showTitle"=1;"united"=1
|
"showTitle"=1;"united"=1;"collapsed"=1
|
||||||
# hierarchy
|
# hierarchy
|
||||||
"children"=1;"columns"=1
|
"children"=1;"columns"=1
|
||||||
# table-specific
|
# table-specific
|
||||||
@@ -1898,14 +1943,16 @@ function Emit-Element {
|
|||||||
|
|
||||||
switch ($typeKey) {
|
switch ($typeKey) {
|
||||||
"group" { Emit-Group -el $el -name $name -id $id -indent $indent }
|
"group" { Emit-Group -el $el -name $name -id $id -indent $indent }
|
||||||
|
"columnGroup" { Emit-ColumnGroup -el $el -name $name -id $id -indent $indent }
|
||||||
"input" { Emit-Input -el $el -name $name -id $id -indent $indent }
|
"input" { Emit-Input -el $el -name $name -id $id -indent $indent }
|
||||||
"check" { Emit-Check -el $el -name $name -id $id -indent $indent }
|
"check" { Emit-Check -el $el -name $name -id $id -indent $indent }
|
||||||
|
"radio" { Emit-Radio -el $el -name $name -id $id -indent $indent }
|
||||||
"label" { Emit-Label -el $el -name $name -id $id -indent $indent }
|
"label" { Emit-Label -el $el -name $name -id $id -indent $indent }
|
||||||
"labelField" { Emit-LabelField -el $el -name $name -id $id -indent $indent }
|
"labelField" { Emit-LabelField -el $el -name $name -id $id -indent $indent }
|
||||||
"table" { Emit-Table -el $el -name $name -id $id -indent $indent }
|
"table" { Emit-Table -el $el -name $name -id $id -indent $indent }
|
||||||
"pages" { Emit-Pages -el $el -name $name -id $id -indent $indent }
|
"pages" { Emit-Pages -el $el -name $name -id $id -indent $indent }
|
||||||
"page" { Emit-Page -el $el -name $name -id $id -indent $indent }
|
"page" { Emit-Page -el $el -name $name -id $id -indent $indent }
|
||||||
"button" { Emit-Button -el $el -name $name -id $id -indent $indent }
|
"button" { Emit-Button -el $el -name $name -id $id -indent $indent -inCmdBar $inCmdBar }
|
||||||
"picture" { Emit-PictureDecoration -el $el -name $name -id $id -indent $indent }
|
"picture" { Emit-PictureDecoration -el $el -name $name -id $id -indent $indent }
|
||||||
"picField" { Emit-PictureField -el $el -name $name -id $id -indent $indent }
|
"picField" { Emit-PictureField -el $el -name $name -id $id -indent $indent }
|
||||||
"calendar" { Emit-Calendar -el $el -name $name -id $id -indent $indent }
|
"calendar" { Emit-Calendar -el $el -name $name -id $id -indent $indent }
|
||||||
@@ -1926,10 +1973,34 @@ function Emit-CommonFlags {
|
|||||||
if ($el.readOnly -eq $true) { X "$indent<ReadOnly>true</ReadOnly>" }
|
if ($el.readOnly -eq $true) { X "$indent<ReadOnly>true</ReadOnly>" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Title-FromName {
|
||||||
|
param([string]$name)
|
||||||
|
if (-not $name) { return '' }
|
||||||
|
$s = [regex]::Replace($name, '([А-ЯA-Z])([А-ЯA-Z][а-яa-z])', '$1 $2')
|
||||||
|
$s = [regex]::Replace($s, '([а-яa-z0-9])([А-ЯA-Z])', '$1 $2')
|
||||||
|
$parts = $s -split ' '
|
||||||
|
if ($parts.Count -eq 0) { return $s }
|
||||||
|
$out = New-Object System.Collections.ArrayList
|
||||||
|
[void]$out.Add($parts[0])
|
||||||
|
for ($i = 1; $i -lt $parts.Count; $i++) {
|
||||||
|
$p = $parts[$i]
|
||||||
|
if ($p.Length -gt 1 -and $p -ceq $p.ToUpper()) {
|
||||||
|
[void]$out.Add($p)
|
||||||
|
} else {
|
||||||
|
[void]$out.Add($p.ToLower())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ($out -join ' ')
|
||||||
|
}
|
||||||
|
|
||||||
function Emit-Title {
|
function Emit-Title {
|
||||||
param($el, [string]$name, [string]$indent)
|
param($el, [string]$name, [string]$indent, [switch]$auto)
|
||||||
if ($el.title) {
|
$title = $el.title
|
||||||
Emit-MLText -tag "Title" -text "$($el.title)" -indent $indent
|
if (-not $title -and $auto -and $name) {
|
||||||
|
$title = Title-FromName -name $name
|
||||||
|
}
|
||||||
|
if ($title) {
|
||||||
|
Emit-MLText -tag "Title" -text "$title" -indent $indent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1956,6 +2027,7 @@ function Emit-Group {
|
|||||||
if ($groupVal -eq "collapsible") {
|
if ($groupVal -eq "collapsible") {
|
||||||
X "$inner<Group>Vertical</Group>"
|
X "$inner<Group>Vertical</Group>"
|
||||||
X "$inner<Behavior>Collapsible</Behavior>"
|
X "$inner<Behavior>Collapsible</Behavior>"
|
||||||
|
if ($el.collapsed -eq $true) { X "$inner<Collapsed>true</Collapsed>" }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Representation
|
# Representation
|
||||||
@@ -1993,6 +2065,48 @@ function Emit-Group {
|
|||||||
X "$indent</UsualGroup>"
|
X "$indent</UsualGroup>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Emit-ColumnGroup {
|
||||||
|
param($el, [string]$name, [int]$id, [string]$indent)
|
||||||
|
|
||||||
|
X "$indent<ColumnGroup name=`"$name`" id=`"$id`">"
|
||||||
|
$inner = "$indent`t"
|
||||||
|
|
||||||
|
Emit-Title -el $el -name $name -indent $inner
|
||||||
|
|
||||||
|
# Group orientation (horizontal / vertical / inCell — последнее только здесь)
|
||||||
|
$groupVal = "$($el.columnGroup)"
|
||||||
|
$orientation = switch ($groupVal) {
|
||||||
|
"horizontal" { "Horizontal" }
|
||||||
|
"vertical" { "Vertical" }
|
||||||
|
"inCell" { "InCell" }
|
||||||
|
default { $null }
|
||||||
|
}
|
||||||
|
if ($orientation) { X "$inner<Group>$orientation</Group>" }
|
||||||
|
|
||||||
|
if ($el.showTitle -eq $false) { X "$inner<ShowTitle>false</ShowTitle>" }
|
||||||
|
if ($null -ne $el.showInHeader) {
|
||||||
|
$shVal = if ($el.showInHeader) { "true" } else { "false" }
|
||||||
|
X "$inner<ShowInHeader>$shVal</ShowInHeader>"
|
||||||
|
}
|
||||||
|
if ($el.width) { X "$inner<Width>$($el.width)</Width>" }
|
||||||
|
|
||||||
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
|
# Companion: ExtendedTooltip
|
||||||
|
Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner
|
||||||
|
|
||||||
|
# Children
|
||||||
|
if ($el.children -and $el.children.Count -gt 0) {
|
||||||
|
X "$inner<ChildItems>"
|
||||||
|
foreach ($child in $el.children) {
|
||||||
|
Emit-Element -el $child -indent "$inner`t"
|
||||||
|
}
|
||||||
|
X "$inner</ChildItems>"
|
||||||
|
}
|
||||||
|
|
||||||
|
X "$indent</ColumnGroup>"
|
||||||
|
}
|
||||||
|
|
||||||
function Emit-Input {
|
function Emit-Input {
|
||||||
param($el, [string]$name, [int]$id, [string]$indent)
|
param($el, [string]$name, [int]$id, [string]$indent)
|
||||||
|
|
||||||
@@ -2001,7 +2115,7 @@ function Emit-Input {
|
|||||||
|
|
||||||
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.titleLocation) {
|
if ($el.titleLocation) {
|
||||||
@@ -2024,8 +2138,15 @@ function Emit-Input {
|
|||||||
if ($el.dropListButton -eq $true) { X "$inner<DropListButton>true</DropListButton>" }
|
if ($el.dropListButton -eq $true) { X "$inner<DropListButton>true</DropListButton>" }
|
||||||
if ($el.markIncomplete -eq $true) { X "$inner<AutoMarkIncomplete>true</AutoMarkIncomplete>" }
|
if ($el.markIncomplete -eq $true) { X "$inner<AutoMarkIncomplete>true</AutoMarkIncomplete>" }
|
||||||
if ($el.skipOnInput -eq $true) { X "$inner<SkipOnInput>true</SkipOnInput>" }
|
if ($el.skipOnInput -eq $true) { X "$inner<SkipOnInput>true</SkipOnInput>" }
|
||||||
if ($el.autoMaxWidth -eq $false) { X "$inner<AutoMaxWidth>false</AutoMaxWidth>" }
|
$hasAmw = $el.PSObject.Properties.Name -contains 'autoMaxWidth'
|
||||||
|
if ($hasAmw) {
|
||||||
|
if ($el.autoMaxWidth -eq $false) { X "$inner<AutoMaxWidth>false</AutoMaxWidth>" }
|
||||||
|
} elseif ($el.multiLine -eq $true) {
|
||||||
|
X "$inner<AutoMaxWidth>false</AutoMaxWidth>"
|
||||||
|
}
|
||||||
|
if ($null -ne $el.maxWidth) { X "$inner<MaxWidth>$($el.maxWidth)</MaxWidth>" }
|
||||||
if ($el.autoMaxHeight -eq $false) { X "$inner<AutoMaxHeight>false</AutoMaxHeight>" }
|
if ($el.autoMaxHeight -eq $false) { X "$inner<AutoMaxHeight>false</AutoMaxHeight>" }
|
||||||
|
if ($null -ne $el.maxHeight) { X "$inner<MaxHeight>$($el.maxHeight)</MaxHeight>" }
|
||||||
if ($el.width) { X "$inner<Width>$($el.width)</Width>" }
|
if ($el.width) { X "$inner<Width>$($el.width)</Width>" }
|
||||||
if ($el.height) { X "$inner<Height>$($el.height)</Height>" }
|
if ($el.height) { X "$inner<Height>$($el.height)</Height>" }
|
||||||
if ($el.horizontalStretch -eq $true) { X "$inner<HorizontalStretch>true</HorizontalStretch>" }
|
if ($el.horizontalStretch -eq $true) { X "$inner<HorizontalStretch>true</HorizontalStretch>" }
|
||||||
@@ -2052,12 +2173,11 @@ function Emit-Check {
|
|||||||
|
|
||||||
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.titleLocation) {
|
$tl = if ($el.titleLocation) { "$($el.titleLocation)" } else { "Right" }
|
||||||
X "$inner<TitleLocation>$($el.titleLocation)</TitleLocation>"
|
X "$inner<TitleLocation>$tl</TitleLocation>"
|
||||||
}
|
|
||||||
|
|
||||||
# Companions
|
# Companions
|
||||||
Emit-Companion -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner
|
Emit-Companion -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner
|
||||||
@@ -2068,18 +2188,237 @@ function Emit-Check {
|
|||||||
X "$indent</CheckBoxField>"
|
X "$indent</CheckBoxField>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Maps Russian/English root of a typed reference path to canonical English root.
|
||||||
|
# Used to normalize ChoiceList values like "Перечисление.X.Y" → "Enum.X.EnumValue.Y".
|
||||||
|
$script:refRootSynonyms = @{
|
||||||
|
"Перечисление" = "Enum"
|
||||||
|
"Справочник" = "Catalog"
|
||||||
|
"Документ" = "Document"
|
||||||
|
"ПланСчетов" = "ChartOfAccounts"
|
||||||
|
"ПланВидовХарактеристик" = "ChartOfCharacteristicTypes"
|
||||||
|
"ПланВидовРасчета" = "ChartOfCalculationTypes"
|
||||||
|
"ПланВидовРасчёта" = "ChartOfCalculationTypes"
|
||||||
|
"ПланОбмена" = "ExchangePlan"
|
||||||
|
"БизнесПроцесс" = "BusinessProcess"
|
||||||
|
"Задача" = "Task"
|
||||||
|
"РегистрСведений" = "InformationRegister"
|
||||||
|
"РегистрНакопления" = "AccumulationRegister"
|
||||||
|
"РегистрБухгалтерии" = "AccountingRegister"
|
||||||
|
"РегистрРасчета" = "CalculationRegister"
|
||||||
|
"РегистрРасчёта" = "CalculationRegister"
|
||||||
|
}
|
||||||
|
$script:enumValueSynonyms = @("EnumValue","ЗначениеПеречисления")
|
||||||
|
|
||||||
|
# Normalize a choiceList item value: returns @{ XsiType = "..."; Text = "..." }
|
||||||
|
function Normalize-ChoiceValue {
|
||||||
|
param($value)
|
||||||
|
|
||||||
|
# Booleans
|
||||||
|
if ($value -is [bool]) {
|
||||||
|
return @{ XsiType = "xs:boolean"; Text = if ($value) { "true" } else { "false" } }
|
||||||
|
}
|
||||||
|
# Numbers (int / decimal / double)
|
||||||
|
if ($value -is [int] -or $value -is [long] -or $value -is [double] -or $value -is [decimal]) {
|
||||||
|
return @{ XsiType = "xs:decimal"; Text = "$value" }
|
||||||
|
}
|
||||||
|
|
||||||
|
$s = "$value"
|
||||||
|
if ([string]::IsNullOrEmpty($s)) {
|
||||||
|
return @{ XsiType = "xs:string"; Text = "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try to detect typed reference path: "<Root>.<Type>[.<Member>.<Value>]"
|
||||||
|
$parts = $s -split '\.'
|
||||||
|
if ($parts.Count -ge 2) {
|
||||||
|
$root = $parts[0]
|
||||||
|
$canonRoot = $null
|
||||||
|
if ($script:refRootSynonyms.ContainsKey($root)) { $canonRoot = $script:refRootSynonyms[$root] }
|
||||||
|
elseif ($script:refRootSynonyms.Values -contains $root) { $canonRoot = $root }
|
||||||
|
|
||||||
|
if ($canonRoot) {
|
||||||
|
$typeName = $parts[1]
|
||||||
|
$normalized = $null
|
||||||
|
|
||||||
|
if ($canonRoot -eq "Enum") {
|
||||||
|
if ($parts.Count -eq 2) {
|
||||||
|
# "Enum.X" alone — not a value, treat as string
|
||||||
|
} elseif ($parts.Count -eq 3) {
|
||||||
|
# "Enum.X.Y" — insert .EnumValue.
|
||||||
|
$normalized = "Enum.$typeName.EnumValue.$($parts[2])"
|
||||||
|
} else {
|
||||||
|
# "Enum.X.<member>.Y..." — replace member with EnumValue (handles ЗначениеПеречисления too)
|
||||||
|
$member = $parts[2]
|
||||||
|
if ($script:enumValueSynonyms -contains $member) {
|
||||||
|
$rest = $parts[3..($parts.Count-1)] -join '.'
|
||||||
|
$normalized = "Enum.$typeName.EnumValue.$rest"
|
||||||
|
} else {
|
||||||
|
$rest = $parts[2..($parts.Count-1)] -join '.'
|
||||||
|
$normalized = "Enum.$typeName.EnumValue.$rest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Other ref roots: just translate root, keep tail as-is
|
||||||
|
if ($parts.Count -ge 3) {
|
||||||
|
$tail = $parts[1..($parts.Count-1)] -join '.'
|
||||||
|
$normalized = "$canonRoot.$tail"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($normalized) {
|
||||||
|
return @{ XsiType = "xr:DesignTimeRef"; Text = $normalized }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return @{ XsiType = "xs:string"; Text = $s }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Emit Presentation block for a choiceList item.
|
||||||
|
# Accepts string (ru only), or hashtable/PSCustomObject {ru, en, ...}.
|
||||||
|
# Empty/null → emits empty <Presentation/>.
|
||||||
|
function Emit-ChoicePresentation {
|
||||||
|
param($pres, [string]$indent)
|
||||||
|
if ($null -eq $pres -or ($pres -is [string] -and [string]::IsNullOrEmpty($pres))) {
|
||||||
|
X "$indent<Presentation/>"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$pairs = @()
|
||||||
|
if ($pres -is [string]) {
|
||||||
|
$pairs += ,@("ru", $pres)
|
||||||
|
} elseif ($pres -is [hashtable] -or $pres -is [System.Collections.IDictionary]) {
|
||||||
|
foreach ($k in $pres.Keys) { $pairs += ,@("$k", "$($pres[$k])") }
|
||||||
|
} elseif ($pres.PSObject -and $pres.PSObject.Properties) {
|
||||||
|
foreach ($p in $pres.PSObject.Properties) { $pairs += ,@("$($p.Name)", "$($p.Value)") }
|
||||||
|
} else {
|
||||||
|
$pairs += ,@("ru", "$pres")
|
||||||
|
}
|
||||||
|
|
||||||
|
X "$indent<Presentation>"
|
||||||
|
foreach ($pair in $pairs) {
|
||||||
|
X "$indent`t<v8:item>"
|
||||||
|
X "$indent`t`t<v8:lang>$($pair[0])</v8:lang>"
|
||||||
|
X "$indent`t`t<v8:content>$(Esc-Xml $pair[1])</v8:content>"
|
||||||
|
X "$indent`t</v8:item>"
|
||||||
|
}
|
||||||
|
X "$indent</Presentation>"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Emit-Radio {
|
||||||
|
param($el, [string]$name, [int]$id, [string]$indent)
|
||||||
|
|
||||||
|
X "$indent<RadioButtonField name=`"$name`" id=`"$id`">"
|
||||||
|
$inner = "$indent`t"
|
||||||
|
|
||||||
|
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||||
|
|
||||||
|
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||||
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
|
# TitleLocation default is None for radio (matches typical configurator behavior)
|
||||||
|
$tl = if ($el.titleLocation) {
|
||||||
|
switch ("$($el.titleLocation)") {
|
||||||
|
"none" { "None" }
|
||||||
|
"left" { "Left" }
|
||||||
|
"right" { "Right" }
|
||||||
|
"top" { "Top" }
|
||||||
|
"bottom" { "Bottom" }
|
||||||
|
default { "$($el.titleLocation)" }
|
||||||
|
}
|
||||||
|
} else { "None" }
|
||||||
|
X "$inner<TitleLocation>$tl</TitleLocation>"
|
||||||
|
|
||||||
|
# RadioButtonType: Auto | RadioButtons | Tumbler. Accept synonyms.
|
||||||
|
$rbtRaw = if ($el.radioButtonType) { "$($el.radioButtonType)".Trim() } else { "Auto" }
|
||||||
|
$rbt = switch -Regex ($rbtRaw.ToLower()) {
|
||||||
|
'^(auto|авто)$' { "Auto"; break }
|
||||||
|
'^(radiobuttons?|переключатель|радио)$' { "RadioButtons"; break }
|
||||||
|
'^(tumbler|тумблер)$' { "Tumbler"; break }
|
||||||
|
default { $rbtRaw }
|
||||||
|
}
|
||||||
|
X "$inner<RadioButtonType>$rbt</RadioButtonType>"
|
||||||
|
|
||||||
|
if ($null -ne $el.columnsCount) {
|
||||||
|
X "$inner<ColumnsCount>$($el.columnsCount)</ColumnsCount>"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ChoiceList
|
||||||
|
if ($el.choiceList -and $el.choiceList.Count -gt 0) {
|
||||||
|
X "$inner<ChoiceList>"
|
||||||
|
$itemIndent = "$inner`t"
|
||||||
|
foreach ($item in $el.choiceList) {
|
||||||
|
# Pull value (and tolerate Russian synonym "значение")
|
||||||
|
$valRaw = $null
|
||||||
|
if ($item -is [hashtable] -or $item -is [System.Collections.IDictionary]) {
|
||||||
|
if ($item.Contains("value")) { $valRaw = $item["value"] }
|
||||||
|
elseif ($item.Contains("значение")) { $valRaw = $item["значение"] }
|
||||||
|
} else {
|
||||||
|
if ($item.PSObject.Properties["value"]) { $valRaw = $item.value }
|
||||||
|
elseif ($item.PSObject.Properties["значение"]) { $valRaw = $item."значение" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pull presentation (presentation OR title synonym)
|
||||||
|
$presRaw = $null
|
||||||
|
$hasPres = $false
|
||||||
|
if ($item -is [hashtable] -or $item -is [System.Collections.IDictionary]) {
|
||||||
|
if ($item.Contains("presentation")) { $presRaw = $item["presentation"]; $hasPres = $true }
|
||||||
|
elseif ($item.Contains("представление")) { $presRaw = $item["представление"]; $hasPres = $true }
|
||||||
|
elseif ($item.Contains("title")) { $presRaw = $item["title"]; $hasPres = $true }
|
||||||
|
} else {
|
||||||
|
if ($item.PSObject.Properties["presentation"]) { $presRaw = $item.presentation; $hasPres = $true }
|
||||||
|
elseif ($item.PSObject.Properties["представление"]) { $presRaw = $item."представление"; $hasPres = $true }
|
||||||
|
elseif ($item.PSObject.Properties["title"]) { $presRaw = $item.title; $hasPres = $true }
|
||||||
|
}
|
||||||
|
|
||||||
|
$norm = Normalize-ChoiceValue -value $valRaw
|
||||||
|
|
||||||
|
# Auto-derive presentation if missing
|
||||||
|
if (-not $hasPres) {
|
||||||
|
if ($norm.XsiType -eq "xr:DesignTimeRef") {
|
||||||
|
$tail = ($norm.Text -split '\.')[-1]
|
||||||
|
$presRaw = Title-FromName -name $tail
|
||||||
|
} elseif ($norm.XsiType -eq "xs:string") {
|
||||||
|
$presRaw = $norm.Text
|
||||||
|
} else {
|
||||||
|
$presRaw = $norm.Text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
X "$itemIndent<xr:Item>"
|
||||||
|
$valIndent = "$itemIndent`t"
|
||||||
|
X "$valIndent<xr:Presentation/>"
|
||||||
|
X "$valIndent<xr:CheckState>0</xr:CheckState>"
|
||||||
|
X "$valIndent<xr:Value xsi:type=`"FormChoiceListDesTimeValue`">"
|
||||||
|
Emit-ChoicePresentation -pres $presRaw -indent "$valIndent`t"
|
||||||
|
X "$valIndent`t<Value xsi:type=`"$($norm.XsiType)`">$(Esc-Xml $norm.Text)</Value>"
|
||||||
|
X "$valIndent</xr:Value>"
|
||||||
|
X "$itemIndent</xr:Item>"
|
||||||
|
}
|
||||||
|
X "$inner</ChoiceList>"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Companions
|
||||||
|
Emit-Companion -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner
|
||||||
|
Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner
|
||||||
|
|
||||||
|
Emit-Events -el $el -elementName $name -indent $inner -typeKey "radio"
|
||||||
|
|
||||||
|
X "$indent</RadioButtonField>"
|
||||||
|
}
|
||||||
|
|
||||||
function Emit-Label {
|
function Emit-Label {
|
||||||
param($el, [string]$name, [int]$id, [string]$indent)
|
param($el, [string]$name, [int]$id, [string]$indent)
|
||||||
|
|
||||||
X "$indent<LabelDecoration name=`"$name`" id=`"$id`">"
|
X "$indent<LabelDecoration name=`"$name`" id=`"$id`">"
|
||||||
$inner = "$indent`t"
|
$inner = "$indent`t"
|
||||||
|
|
||||||
if ($el.title) {
|
$labelTitle = if ($el.title) { "$($el.title)" } else { Title-FromName -name $name }
|
||||||
|
if ($labelTitle) {
|
||||||
$formatted = if ($el.hyperlink -eq $true) { "true" } else { "false" }
|
$formatted = if ($el.hyperlink -eq $true) { "true" } else { "false" }
|
||||||
X "$inner<Title formatted=`"$formatted`">"
|
X "$inner<Title formatted=`"$formatted`">"
|
||||||
X "$inner`t<v8:item>"
|
X "$inner`t<v8:item>"
|
||||||
X "$inner`t`t<v8:lang>ru</v8:lang>"
|
X "$inner`t`t<v8:lang>ru</v8:lang>"
|
||||||
X "$inner`t`t<v8:content>$(Esc-Xml "$($el.title)")</v8:content>"
|
X "$inner`t`t<v8:content>$(Esc-Xml "$labelTitle")</v8:content>"
|
||||||
X "$inner`t</v8:item>"
|
X "$inner`t</v8:item>"
|
||||||
X "$inner</Title>"
|
X "$inner</Title>"
|
||||||
}
|
}
|
||||||
@@ -2088,7 +2427,9 @@ function Emit-Label {
|
|||||||
|
|
||||||
if ($el.hyperlink -eq $true) { X "$inner<Hyperlink>true</Hyperlink>" }
|
if ($el.hyperlink -eq $true) { X "$inner<Hyperlink>true</Hyperlink>" }
|
||||||
if ($el.autoMaxWidth -eq $false) { X "$inner<AutoMaxWidth>false</AutoMaxWidth>" }
|
if ($el.autoMaxWidth -eq $false) { X "$inner<AutoMaxWidth>false</AutoMaxWidth>" }
|
||||||
|
if ($null -ne $el.maxWidth) { X "$inner<MaxWidth>$($el.maxWidth)</MaxWidth>" }
|
||||||
if ($el.autoMaxHeight -eq $false) { X "$inner<AutoMaxHeight>false</AutoMaxHeight>" }
|
if ($el.autoMaxHeight -eq $false) { X "$inner<AutoMaxHeight>false</AutoMaxHeight>" }
|
||||||
|
if ($null -ne $el.maxHeight) { X "$inner<MaxHeight>$($el.maxHeight)</MaxHeight>" }
|
||||||
if ($el.width) { X "$inner<Width>$($el.width)</Width>" }
|
if ($el.width) { X "$inner<Width>$($el.width)</Width>" }
|
||||||
if ($el.height) { X "$inner<Height>$($el.height)</Height>" }
|
if ($el.height) { X "$inner<Height>$($el.height)</Height>" }
|
||||||
|
|
||||||
@@ -2109,7 +2450,7 @@ function Emit-LabelField {
|
|||||||
|
|
||||||
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.hyperlink -eq $true) { X "$inner<Hyperlink>true</Hyperlink>" }
|
if ($el.hyperlink -eq $true) { X "$inner<Hyperlink>true</Hyperlink>" }
|
||||||
@@ -2131,7 +2472,7 @@ function Emit-Table {
|
|||||||
|
|
||||||
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.representation) {
|
if ($el.representation) {
|
||||||
@@ -2220,7 +2561,7 @@ function Emit-Page {
|
|||||||
X "$indent<Page name=`"$name`" id=`"$id`">"
|
X "$indent<Page name=`"$name`" id=`"$id`">"
|
||||||
$inner = "$indent`t"
|
$inner = "$indent`t"
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.group) {
|
if ($el.group) {
|
||||||
@@ -2250,19 +2591,48 @@ function Emit-Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Emit-Button {
|
function Emit-Button {
|
||||||
param($el, [string]$name, [int]$id, [string]$indent)
|
param($el, [string]$name, [int]$id, [string]$indent, [bool]$inCmdBar = $false)
|
||||||
|
|
||||||
X "$indent<Button name=`"$name`" id=`"$id`">"
|
X "$indent<Button name=`"$name`" id=`"$id`">"
|
||||||
$inner = "$indent`t"
|
$inner = "$indent`t"
|
||||||
|
|
||||||
# Type
|
# Type — context-aware:
|
||||||
|
# Inside command bar (cmdBar/autoCmdBar/popup) only CommandBarButton/CommandBarHyperlink are valid.
|
||||||
|
# UsualButton/Hyperlink would be silently ignored by 1C.
|
||||||
|
$btnType = $null
|
||||||
if ($el.type) {
|
if ($el.type) {
|
||||||
$btnType = switch ("$($el.type)") {
|
$rawType = "$($el.type)"
|
||||||
"usual" { "UsualButton" }
|
if ($inCmdBar) {
|
||||||
"hyperlink" { "Hyperlink" }
|
# Be forgiving: any "ordinary button" hint resolves to CommandBarButton,
|
||||||
"commandBar" { "CommandBarButton" }
|
# any "hyperlink" hint resolves to CommandBarHyperlink. The model can pass
|
||||||
default { "$($el.type)" }
|
# either DSL ("usual"/"hyperlink") or XML names — all map to the right kind.
|
||||||
|
switch ($rawType) {
|
||||||
|
"usual" { $btnType = "CommandBarButton" }
|
||||||
|
"UsualButton" { $btnType = "CommandBarButton" }
|
||||||
|
"commandBar" { $btnType = "CommandBarButton" }
|
||||||
|
"CommandBarButton" { $btnType = "CommandBarButton" }
|
||||||
|
"hyperlink" { $btnType = "CommandBarHyperlink" }
|
||||||
|
"Hyperlink" { $btnType = "CommandBarHyperlink" }
|
||||||
|
"CommandBarHyperlink" { $btnType = "CommandBarHyperlink" }
|
||||||
|
default { $btnType = $rawType }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Symmetric: any "ordinary button" hint → UsualButton, any "hyperlink" → Hyperlink.
|
||||||
|
switch ($rawType) {
|
||||||
|
"usual" { $btnType = "UsualButton" }
|
||||||
|
"UsualButton" { $btnType = "UsualButton" }
|
||||||
|
"commandBar" { $btnType = "UsualButton" }
|
||||||
|
"CommandBarButton" { $btnType = "UsualButton" }
|
||||||
|
"hyperlink" { $btnType = "Hyperlink" }
|
||||||
|
"Hyperlink" { $btnType = "Hyperlink" }
|
||||||
|
"CommandBarHyperlink" { $btnType = "Hyperlink" }
|
||||||
|
default { $btnType = $rawType }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} elseif ($inCmdBar) {
|
||||||
|
$btnType = "CommandBarButton"
|
||||||
|
}
|
||||||
|
if ($btnType) {
|
||||||
X "$inner<Type>$btnType</Type>"
|
X "$inner<Type>$btnType</Type>"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2279,7 +2649,8 @@ function Emit-Button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
$btnAuto = -not ($el.command -or $el.stdCommand)
|
||||||
|
Emit-Title -el $el -name $name -indent $inner -auto:$btnAuto
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.defaultButton -eq $true) { X "$inner<DefaultButton>true</DefaultButton>" }
|
if ($el.defaultButton -eq $true) { X "$inner<DefaultButton>true</DefaultButton>" }
|
||||||
@@ -2369,7 +2740,7 @@ function Emit-Calendar {
|
|||||||
|
|
||||||
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
# Companions
|
# Companions
|
||||||
@@ -2395,7 +2766,7 @@ function Emit-CommandBar {
|
|||||||
if ($el.children -and $el.children.Count -gt 0) {
|
if ($el.children -and $el.children.Count -gt 0) {
|
||||||
X "$inner<ChildItems>"
|
X "$inner<ChildItems>"
|
||||||
foreach ($child in $el.children) {
|
foreach ($child in $el.children) {
|
||||||
Emit-Element -el $child -indent "$inner`t"
|
Emit-Element -el $child -indent "$inner`t" -inCmdBar $true
|
||||||
}
|
}
|
||||||
X "$inner</ChildItems>"
|
X "$inner</ChildItems>"
|
||||||
}
|
}
|
||||||
@@ -2409,7 +2780,7 @@ function Emit-Popup {
|
|||||||
X "$indent<Popup name=`"$name`" id=`"$id`">"
|
X "$indent<Popup name=`"$name`" id=`"$id`">"
|
||||||
$inner = "$indent`t"
|
$inner = "$indent`t"
|
||||||
|
|
||||||
Emit-Title -el $el -name $name -indent $inner
|
Emit-Title -el $el -name $name -indent $inner -auto
|
||||||
Emit-CommonFlags -el $el -indent $inner
|
Emit-CommonFlags -el $el -indent $inner
|
||||||
|
|
||||||
if ($el.picture) {
|
if ($el.picture) {
|
||||||
@@ -2427,7 +2798,7 @@ function Emit-Popup {
|
|||||||
if ($el.children -and $el.children.Count -gt 0) {
|
if ($el.children -and $el.children.Count -gt 0) {
|
||||||
X "$inner<ChildItems>"
|
X "$inner<ChildItems>"
|
||||||
foreach ($child in $el.children) {
|
foreach ($child in $el.children) {
|
||||||
Emit-Element -el $child -indent "$inner`t"
|
Emit-Element -el $child -indent "$inner`t" -inCmdBar $true
|
||||||
}
|
}
|
||||||
X "$inner</ChildItems>"
|
X "$inner</ChildItems>"
|
||||||
}
|
}
|
||||||
@@ -2450,8 +2821,9 @@ function Emit-Attributes {
|
|||||||
X "$indent`t<Attribute name=`"$attrName`" id=`"$attrId`">"
|
X "$indent`t<Attribute name=`"$attrName`" id=`"$attrId`">"
|
||||||
$inner = "$indent`t`t"
|
$inner = "$indent`t`t"
|
||||||
|
|
||||||
if ($attr.title) {
|
$attrTitle = if ($attr.title) { "$($attr.title)" } elseif ($attr.main -ne $true) { Title-FromName -name $attrName } else { '' }
|
||||||
Emit-MLText -tag "Title" -text "$($attr.title)" -indent $inner
|
if ($attrTitle) {
|
||||||
|
Emit-MLText -tag "Title" -text "$attrTitle" -indent $inner
|
||||||
}
|
}
|
||||||
|
|
||||||
# Type
|
# Type
|
||||||
@@ -2464,7 +2836,11 @@ function Emit-Attributes {
|
|||||||
if ($attr.main -eq $true) {
|
if ($attr.main -eq $true) {
|
||||||
X "$inner<MainAttribute>true</MainAttribute>"
|
X "$inner<MainAttribute>true</MainAttribute>"
|
||||||
}
|
}
|
||||||
if ($attr.savedData -eq $true) {
|
$mainSaved = $false
|
||||||
|
if ($attr.main -eq $true -and $attr.type) {
|
||||||
|
$mainSaved = ("$($attr.type)") -match '^(CatalogObject|DocumentObject|ChartOfAccountsObject|ChartOfCalculationTypesObject|ChartOfCharacteristicTypesObject|ExchangePlanObject|BusinessProcessObject|TaskObject)\.' -or ("$($attr.type)") -match 'RecordManager\.'
|
||||||
|
}
|
||||||
|
if ($attr.savedData -eq $true -or $mainSaved) {
|
||||||
X "$inner<SavedData>true</SavedData>"
|
X "$inner<SavedData>true</SavedData>"
|
||||||
}
|
}
|
||||||
if ($attr.fillChecking) {
|
if ($attr.fillChecking) {
|
||||||
@@ -2539,8 +2915,9 @@ function Emit-Commands {
|
|||||||
X "$indent`t<Command name=`"$($cmd.name)`" id=`"$cmdId`">"
|
X "$indent`t<Command name=`"$($cmd.name)`" id=`"$cmdId`">"
|
||||||
$inner = "$indent`t`t"
|
$inner = "$indent`t`t"
|
||||||
|
|
||||||
if ($cmd.title) {
|
$cmdTitle = if ($cmd.title) { "$($cmd.title)" } else { Title-FromName -name "$($cmd.name)" }
|
||||||
Emit-MLText -tag "Title" -text "$($cmd.title)" -indent $inner
|
if ($cmdTitle) {
|
||||||
|
Emit-MLText -tag "Title" -text "$cmdTitle" -indent $inner
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cmd.action) {
|
if ($cmd.action) {
|
||||||
@@ -2649,7 +3026,7 @@ function HasCmdBarRecursive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ApplyDynamicListTableHeuristic {
|
function ApplyDynamicListTableHeuristic {
|
||||||
param($el, [string]$listName)
|
param($el, [string]$listName, [bool]$hasMainTable)
|
||||||
if ($null -eq $el) { return }
|
if ($null -eq $el) { return }
|
||||||
if ($el.PSObject.Properties["table"] -and $null -ne $el.table -and "$($el.path)" -eq $listName) {
|
if ($el.PSObject.Properties["table"] -and $null -ne $el.table -and "$($el.path)" -eq $listName) {
|
||||||
if ($null -eq $el.PSObject.Properties["tableAutofill"]) {
|
if ($null -eq $el.PSObject.Properties["tableAutofill"]) {
|
||||||
@@ -2658,9 +3035,13 @@ function ApplyDynamicListTableHeuristic {
|
|||||||
if ($null -eq $el.PSObject.Properties["commandBarLocation"]) {
|
if ($null -eq $el.PSObject.Properties["commandBarLocation"]) {
|
||||||
$el | Add-Member -NotePropertyName "commandBarLocation" -NotePropertyValue "None" -Force
|
$el | Add-Member -NotePropertyName "commandBarLocation" -NotePropertyValue "None" -Force
|
||||||
}
|
}
|
||||||
|
# DefaultPicture доступен только если у DynamicList есть основная таблица
|
||||||
|
if ($hasMainTable -and ($null -eq $el.PSObject.Properties["rowPictureDataPath"] -or [string]::IsNullOrEmpty("$($el.rowPictureDataPath)"))) {
|
||||||
|
$el | Add-Member -NotePropertyName "rowPictureDataPath" -NotePropertyValue "$listName.DefaultPicture" -Force
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($el.PSObject.Properties["children"] -and $el.children) {
|
if ($el.PSObject.Properties["children"] -and $el.children) {
|
||||||
foreach ($child in $el.children) { ApplyDynamicListTableHeuristic $child $listName }
|
foreach ($child in $el.children) { ApplyDynamicListTableHeuristic $child $listName $hasMainTable }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2749,8 +3130,17 @@ if ($def.attributes -and $def.elements) {
|
|||||||
if ($attr.main -eq $true) { $mainAttr = $attr; break }
|
if ($attr.main -eq $true) { $mainAttr = $attr; break }
|
||||||
}
|
}
|
||||||
if ($mainAttr -and "$($mainAttr.type)" -eq "DynamicList") {
|
if ($mainAttr -and "$($mainAttr.type)" -eq "DynamicList") {
|
||||||
|
$mt = $null
|
||||||
|
if ($mainAttr.PSObject.Properties["settings"] -and $null -ne $mainAttr.settings) {
|
||||||
|
if ($mainAttr.settings -is [hashtable]) {
|
||||||
|
if ($mainAttr.settings.ContainsKey("mainTable")) { $mt = $mainAttr.settings["mainTable"] }
|
||||||
|
} elseif ($mainAttr.settings.PSObject.Properties["mainTable"]) {
|
||||||
|
$mt = $mainAttr.settings.mainTable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$hasMt = -not [string]::IsNullOrEmpty("$mt")
|
||||||
foreach ($el in $def.elements) {
|
foreach ($el in $def.elements) {
|
||||||
ApplyDynamicListTableHeuristic $el $mainAttr.name
|
ApplyDynamicListTableHeuristic $el $mainAttr.name $hasMt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2802,17 +3192,26 @@ if ($formTitle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 12b. Properties (skip 'title' — handled above as multilingual)
|
# 12b. Properties (skip 'title' — handled above as multilingual)
|
||||||
|
# When form-level Title is set, default autoTitle=false (≈95% of ERP forms do this;
|
||||||
|
# otherwise platform appends synonym → "Title: Synonym" double-titles).
|
||||||
|
$propsClone = New-Object PSObject
|
||||||
|
$hasAutoTitle = $false
|
||||||
|
if ($def.properties) {
|
||||||
|
foreach ($p in $def.properties.PSObject.Properties) {
|
||||||
|
if ($p.Name -eq "autoTitle") { $hasAutoTitle = $true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($formTitle -and -not $hasAutoTitle) {
|
||||||
|
$propsClone | Add-Member -NotePropertyName "autoTitle" -NotePropertyValue $false
|
||||||
|
}
|
||||||
if ($def.properties) {
|
if ($def.properties) {
|
||||||
$propsClone = New-Object PSObject
|
|
||||||
foreach ($p in $def.properties.PSObject.Properties) {
|
foreach ($p in $def.properties.PSObject.Properties) {
|
||||||
if ($p.Name -ne "title") {
|
if ($p.Name -ne "title") {
|
||||||
$propsClone | Add-Member -NotePropertyName $p.Name -NotePropertyValue $p.Value
|
$propsClone | Add-Member -NotePropertyName $p.Name -NotePropertyValue $p.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Emit-Properties -props $propsClone -indent "`t"
|
|
||||||
} else {
|
|
||||||
Emit-Properties -props $null -indent "`t"
|
|
||||||
}
|
}
|
||||||
|
Emit-Properties -props $propsClone -indent "`t"
|
||||||
|
|
||||||
# 12c. CommandSet (excluded commands)
|
# 12c. CommandSet (excluded commands)
|
||||||
if ($def.excludedCommands -and $def.excludedCommands.Count -gt 0) {
|
if ($def.excludedCommands -and $def.excludedCommands.Count -gt 0) {
|
||||||
@@ -2847,7 +3246,7 @@ if ($acbHasInner) {
|
|||||||
if ($hasAcbChildren) {
|
if ($hasAcbChildren) {
|
||||||
X "`t`t<ChildItems>"
|
X "`t`t<ChildItems>"
|
||||||
foreach ($child in $script:mainAcbDef.children) {
|
foreach ($child in $script:mainAcbDef.children) {
|
||||||
Emit-Element -el $child -indent "`t`t`t"
|
Emit-Element -el $child -indent "`t`t`t" -inCmdBar $true
|
||||||
}
|
}
|
||||||
X "`t`t</ChildItems>"
|
X "`t`t</ChildItems>"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# form-compile v1.9 — Compile 1C managed form from JSON or object metadata
|
# form-compile v1.20 — Compile 1C managed form from JSON or object metadata
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
@@ -625,6 +625,7 @@ def generate_document_list_dsl(meta, p):
|
|||||||
|
|
||||||
table_el = OrderedDict([
|
table_el = OrderedDict([
|
||||||
('table', '\u0421\u043f\u0438\u0441\u043e\u043a'), ('path', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
('table', '\u0421\u043f\u0438\u0441\u043e\u043a'), ('path', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
||||||
|
('rowPictureDataPath', '\u0421\u043f\u0438\u0441\u043e\u043a.DefaultPicture'),
|
||||||
('commandBarLocation', 'None'),
|
('commandBarLocation', 'None'),
|
||||||
('tableAutofill', False),
|
('tableAutofill', False),
|
||||||
('columns', columns),
|
('columns', columns),
|
||||||
@@ -938,6 +939,7 @@ def generate_information_register_list_dsl(meta, p):
|
|||||||
table_el = OrderedDict([
|
table_el = OrderedDict([
|
||||||
('table', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
('table', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
||||||
('path', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
('path', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
||||||
|
('rowPictureDataPath', '\u0421\u043f\u0438\u0441\u043e\u043a.DefaultPicture'),
|
||||||
('commandBarLocation', 'None'),
|
('commandBarLocation', 'None'),
|
||||||
('tableAutofill', False),
|
('tableAutofill', False),
|
||||||
('columns', columns_list),
|
('columns', columns_list),
|
||||||
@@ -996,6 +998,7 @@ def generate_accumulation_register_list_dsl(meta, p):
|
|||||||
table_el = OrderedDict([
|
table_el = OrderedDict([
|
||||||
('table', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
('table', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
||||||
('path', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
('path', '\u0421\u043f\u0438\u0441\u043e\u043a'),
|
||||||
|
('rowPictureDataPath', '\u0421\u043f\u0438\u0441\u043e\u043a.DefaultPicture'),
|
||||||
('commandBarLocation', 'None'),
|
('commandBarLocation', 'None'),
|
||||||
('tableAutofill', False),
|
('tableAutofill', False),
|
||||||
('columns', columns_list),
|
('columns', columns_list),
|
||||||
@@ -1311,6 +1314,7 @@ EVENT_SUFFIX_MAP = {
|
|||||||
KNOWN_EVENTS = {
|
KNOWN_EVENTS = {
|
||||||
"input": ["OnChange", "StartChoice", "ChoiceProcessing", "AutoComplete", "TextEditEnd", "Clearing", "Creating", "EditTextChange"],
|
"input": ["OnChange", "StartChoice", "ChoiceProcessing", "AutoComplete", "TextEditEnd", "Clearing", "Creating", "EditTextChange"],
|
||||||
"check": ["OnChange"],
|
"check": ["OnChange"],
|
||||||
|
"radio": ["OnChange"],
|
||||||
"label": ["Click", "URLProcessing"],
|
"label": ["Click", "URLProcessing"],
|
||||||
"labelField": ["OnChange", "StartChoice", "ChoiceProcessing", "Click", "URLProcessing", "Clearing"],
|
"labelField": ["OnChange", "StartChoice", "ChoiceProcessing", "Click", "URLProcessing", "Clearing"],
|
||||||
"table": ["Selection", "BeforeAddRow", "AfterDeleteRow", "BeforeDeleteRow", "OnActivateRow", "OnEditEnd", "OnStartEdit", "BeforeRowChange", "BeforeEditEnd", "ValueChoice", "OnActivateCell", "OnActivateField", "Drag", "DragStart", "DragCheck", "DragEnd", "OnGetDataAtServer", "BeforeLoadUserSettingsAtServer", "OnUpdateUserSettingSetAtServer", "OnChange"],
|
"table": ["Selection", "BeforeAddRow", "AfterDeleteRow", "BeforeDeleteRow", "OnActivateRow", "OnEditEnd", "OnStartEdit", "BeforeRowChange", "BeforeEditEnd", "ValueChoice", "OnActivateCell", "OnActivateField", "Drag", "DragStart", "DragCheck", "DragEnd", "OnGetDataAtServer", "BeforeLoadUserSettingsAtServer", "OnUpdateUserSettingSetAtServer", "OnChange"],
|
||||||
@@ -1334,17 +1338,20 @@ KNOWN_FORM_EVENTS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
KNOWN_KEYS = {
|
KNOWN_KEYS = {
|
||||||
"group", "input", "check", "label", "labelField", "table", "pages", "page",
|
"group", "columnGroup", "input", "check", "radio", "label", "labelField", "table", "pages", "page",
|
||||||
"button", "picture", "picField", "calendar", "cmdBar", "popup",
|
"button", "picture", "picField", "calendar", "cmdBar", "popup",
|
||||||
|
"showInHeader",
|
||||||
|
"radioButtonType", "choiceList", "columnsCount",
|
||||||
"name", "path", "title",
|
"name", "path", "title",
|
||||||
"visible", "hidden", "enabled", "disabled", "readOnly", "userVisible",
|
"visible", "hidden", "enabled", "disabled", "readOnly", "userVisible",
|
||||||
"on", "handlers",
|
"on", "handlers",
|
||||||
"titleLocation", "representation", "width", "height",
|
"titleLocation", "representation", "width", "height",
|
||||||
"horizontalStretch", "verticalStretch", "autoMaxWidth", "autoMaxHeight",
|
"horizontalStretch", "verticalStretch", "autoMaxWidth", "autoMaxHeight",
|
||||||
|
"maxWidth", "maxHeight",
|
||||||
"multiLine", "passwordMode", "choiceButton", "clearButton",
|
"multiLine", "passwordMode", "choiceButton", "clearButton",
|
||||||
"spinButton", "dropListButton", "markIncomplete", "skipOnInput", "inputHint",
|
"spinButton", "dropListButton", "markIncomplete", "skipOnInput", "inputHint",
|
||||||
"hyperlink",
|
"hyperlink",
|
||||||
"showTitle", "united",
|
"showTitle", "united", "collapsed",
|
||||||
"children", "columns",
|
"children", "columns",
|
||||||
"changeRowSet", "changeRowOrder", "header", "footer",
|
"changeRowSet", "changeRowOrder", "header", "footer",
|
||||||
"commandBarLocation", "searchStringLocation",
|
"commandBarLocation", "searchStringLocation",
|
||||||
@@ -1356,9 +1363,147 @@ KNOWN_KEYS = {
|
|||||||
"rowPictureDataPath", "tableAutofill",
|
"rowPictureDataPath", "tableAutofill",
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE_KEYS = ["group", "input", "check", "label", "labelField", "table", "pages", "page",
|
TYPE_KEYS = ["columnGroup", "group", "input", "check", "radio", "label", "labelField", "table", "pages", "page",
|
||||||
"button", "picture", "picField", "calendar", "cmdBar", "popup"]
|
"button", "picture", "picField", "calendar", "cmdBar", "popup"]
|
||||||
|
|
||||||
|
# Synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio)
|
||||||
|
ELEMENT_TYPE_SYNONYMS = {
|
||||||
|
"commandBar": "cmdBar",
|
||||||
|
"autoCommandBar": "autoCmdBar",
|
||||||
|
"КоманднаяПанель": "cmdBar",
|
||||||
|
"InputField": "input",
|
||||||
|
"ПолеВвода": "input",
|
||||||
|
"CheckBoxField": "check",
|
||||||
|
"ПолеФлажка": "check",
|
||||||
|
"RadioButtonField": "radio",
|
||||||
|
"ПолеПереключателя": "radio",
|
||||||
|
"radioButton": "radio",
|
||||||
|
"PictureField": "picField",
|
||||||
|
"ПолеКартинки": "picField",
|
||||||
|
"LabelField": "labelField",
|
||||||
|
"ПолеНадписи": "labelField",
|
||||||
|
"CalendarField": "calendar",
|
||||||
|
"ПолеКалендаря": "calendar",
|
||||||
|
"LabelDecoration": "label",
|
||||||
|
"Надпись": "label",
|
||||||
|
"PictureDecoration": "picture",
|
||||||
|
"Картинка": "picture",
|
||||||
|
"UsualGroup": "group",
|
||||||
|
"Группа": "group",
|
||||||
|
"ОбычнаяГруппа": "group",
|
||||||
|
"ColumnGroup": "columnGroup",
|
||||||
|
"ГруппаКолонок": "columnGroup",
|
||||||
|
"Pages": "pages",
|
||||||
|
"ГруппаСтраниц": "pages",
|
||||||
|
"Page": "page",
|
||||||
|
"Страница": "page",
|
||||||
|
"Table": "table",
|
||||||
|
"Таблица": "table",
|
||||||
|
"Button": "button",
|
||||||
|
"Кнопка": "button",
|
||||||
|
"Popup": "popup",
|
||||||
|
"ВсплывающееМеню": "popup",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Maps Russian/English root of typed reference path to canonical English root
|
||||||
|
REF_ROOT_SYNONYMS = {
|
||||||
|
"Перечисление": "Enum",
|
||||||
|
"Справочник": "Catalog",
|
||||||
|
"Документ": "Document",
|
||||||
|
"ПланСчетов": "ChartOfAccounts",
|
||||||
|
"ПланВидовХарактеристик": "ChartOfCharacteristicTypes",
|
||||||
|
"ПланВидовРасчета": "ChartOfCalculationTypes",
|
||||||
|
"ПланВидовРасчёта": "ChartOfCalculationTypes",
|
||||||
|
"ПланОбмена": "ExchangePlan",
|
||||||
|
"БизнесПроцесс": "BusinessProcess",
|
||||||
|
"Задача": "Task",
|
||||||
|
"РегистрСведений": "InformationRegister",
|
||||||
|
"РегистрНакопления": "AccumulationRegister",
|
||||||
|
"РегистрБухгалтерии": "AccountingRegister",
|
||||||
|
"РегистрРасчета": "CalculationRegister",
|
||||||
|
"РегистрРасчёта": "CalculationRegister",
|
||||||
|
}
|
||||||
|
ENUM_VALUE_SYNONYMS = {"EnumValue", "ЗначениеПеречисления"}
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_choice_value(value):
|
||||||
|
"""Returns dict {xsi_type, text} for a choiceList item value."""
|
||||||
|
if isinstance(value, bool):
|
||||||
|
return {"xsi_type": "xs:boolean", "text": "true" if value else "false"}
|
||||||
|
if isinstance(value, (int, float)):
|
||||||
|
return {"xsi_type": "xs:decimal", "text": str(value)}
|
||||||
|
|
||||||
|
s = "" if value is None else str(value)
|
||||||
|
if not s:
|
||||||
|
return {"xsi_type": "xs:string", "text": ""}
|
||||||
|
|
||||||
|
parts = s.split(".")
|
||||||
|
if len(parts) >= 2:
|
||||||
|
root = parts[0]
|
||||||
|
canon_root = None
|
||||||
|
if root in REF_ROOT_SYNONYMS:
|
||||||
|
canon_root = REF_ROOT_SYNONYMS[root]
|
||||||
|
elif root in REF_ROOT_SYNONYMS.values():
|
||||||
|
canon_root = root
|
||||||
|
|
||||||
|
if canon_root:
|
||||||
|
type_name = parts[1]
|
||||||
|
normalized = None
|
||||||
|
if canon_root == "Enum":
|
||||||
|
if len(parts) == 3:
|
||||||
|
normalized = f"Enum.{type_name}.EnumValue.{parts[2]}"
|
||||||
|
elif len(parts) >= 4:
|
||||||
|
member = parts[2]
|
||||||
|
if member in ENUM_VALUE_SYNONYMS:
|
||||||
|
rest = ".".join(parts[3:])
|
||||||
|
else:
|
||||||
|
rest = ".".join(parts[2:])
|
||||||
|
normalized = f"Enum.{type_name}.EnumValue.{rest}"
|
||||||
|
else:
|
||||||
|
if len(parts) >= 3:
|
||||||
|
tail = ".".join(parts[1:])
|
||||||
|
normalized = f"{canon_root}.{tail}"
|
||||||
|
|
||||||
|
if normalized:
|
||||||
|
return {"xsi_type": "xr:DesignTimeRef", "text": normalized}
|
||||||
|
|
||||||
|
return {"xsi_type": "xs:string", "text": s}
|
||||||
|
|
||||||
|
|
||||||
|
def emit_choice_presentation(lines, pres, indent):
|
||||||
|
"""Accepts None/empty → <Presentation/>; str → ru only; dict → multi-lang."""
|
||||||
|
if pres is None or (isinstance(pres, str) and pres == ""):
|
||||||
|
lines.append(f"{indent}<Presentation/>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(pres, str):
|
||||||
|
pairs = [("ru", pres)]
|
||||||
|
elif isinstance(pres, dict):
|
||||||
|
pairs = [(str(k), str(v)) for k, v in pres.items()]
|
||||||
|
else:
|
||||||
|
pairs = [("ru", str(pres))]
|
||||||
|
|
||||||
|
lines.append(f"{indent}<Presentation>")
|
||||||
|
for lang, content in pairs:
|
||||||
|
lines.append(f"{indent}\t<v8:item>")
|
||||||
|
lines.append(f"{indent}\t\t<v8:lang>{lang}</v8:lang>")
|
||||||
|
lines.append(f"{indent}\t\t<v8:content>{esc_xml(content)}</v8:content>")
|
||||||
|
lines.append(f"{indent}\t</v8:item>")
|
||||||
|
lines.append(f"{indent}</Presentation>")
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_radio_button_type(raw):
|
||||||
|
if not raw:
|
||||||
|
return "Auto"
|
||||||
|
s = str(raw).strip().lower()
|
||||||
|
if s in ("auto", "авто"):
|
||||||
|
return "Auto"
|
||||||
|
if s in ("radiobutton", "radiobuttons", "переключатель", "радио"):
|
||||||
|
return "RadioButtons"
|
||||||
|
if s in ("tumbler", "тумблер"):
|
||||||
|
return "Tumbler"
|
||||||
|
return str(raw).strip()
|
||||||
|
|
||||||
|
|
||||||
def get_handler_name(element_name, event_name):
|
def get_handler_name(element_name, event_name):
|
||||||
suffix = EVENT_SUFFIX_MAP.get(event_name)
|
suffix = EVENT_SUFFIX_MAP.get(event_name)
|
||||||
@@ -1414,9 +1559,27 @@ def emit_common_flags(lines, el, indent):
|
|||||||
lines.append(f"{indent}<ReadOnly>true</ReadOnly>")
|
lines.append(f"{indent}<ReadOnly>true</ReadOnly>")
|
||||||
|
|
||||||
|
|
||||||
def emit_title(lines, el, name, indent):
|
def title_from_name(name):
|
||||||
if el.get('title'):
|
"""СуммаДокумента → 'Сумма документа'. НДСВключен → 'НДС включен'."""
|
||||||
emit_mltext(lines, indent, 'Title', str(el['title']))
|
if not name:
|
||||||
|
return ''
|
||||||
|
s = re.sub(r'([А-ЯA-Z])([А-ЯA-Z][а-яa-z])', r'\1 \2', name)
|
||||||
|
s = re.sub(r'([а-яa-z0-9])([А-ЯA-Z])', r'\1 \2', s)
|
||||||
|
parts = s.split(' ')
|
||||||
|
if not parts:
|
||||||
|
return s
|
||||||
|
out = [parts[0]]
|
||||||
|
for p in parts[1:]:
|
||||||
|
out.append(p if (len(p) > 1 and p.isupper()) else p.lower())
|
||||||
|
return ' '.join(out)
|
||||||
|
|
||||||
|
|
||||||
|
def emit_title(lines, el, name, indent, auto=False):
|
||||||
|
title = el.get('title')
|
||||||
|
if not title and auto and name:
|
||||||
|
title = title_from_name(name)
|
||||||
|
if title:
|
||||||
|
emit_mltext(lines, indent, 'Title', str(title))
|
||||||
|
|
||||||
|
|
||||||
# --- Type emitter ---
|
# --- Type emitter ---
|
||||||
@@ -1601,10 +1764,9 @@ def emit_type(lines, type_str, indent):
|
|||||||
|
|
||||||
# --- Element emitters ---
|
# --- Element emitters ---
|
||||||
|
|
||||||
def emit_element(lines, el, indent):
|
def emit_element(lines, el, indent, in_cmd_bar=False):
|
||||||
# Silent synonyms (safety net; top-level autoCmdBar is normally extracted in pre-pass)
|
# Silent synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio)
|
||||||
_synonyms = {'commandBar': 'cmdBar', 'autoCommandBar': 'autoCmdBar'}
|
for src, dst in ELEMENT_TYPE_SYNONYMS.items():
|
||||||
for src, dst in _synonyms.items():
|
|
||||||
if src in el and dst not in el:
|
if src in el and dst not in el:
|
||||||
el[dst] = el.pop(src)
|
el[dst] = el.pop(src)
|
||||||
|
|
||||||
@@ -1628,8 +1790,10 @@ def emit_element(lines, el, indent):
|
|||||||
|
|
||||||
emitters = {
|
emitters = {
|
||||||
'group': emit_group,
|
'group': emit_group,
|
||||||
|
'columnGroup': emit_column_group,
|
||||||
'input': emit_input,
|
'input': emit_input,
|
||||||
'check': emit_check,
|
'check': emit_check,
|
||||||
|
'radio': emit_radio_button_field,
|
||||||
'label': emit_label,
|
'label': emit_label,
|
||||||
'labelField': emit_label_field,
|
'labelField': emit_label_field,
|
||||||
'table': emit_table,
|
'table': emit_table,
|
||||||
@@ -1645,7 +1809,10 @@ def emit_element(lines, el, indent):
|
|||||||
|
|
||||||
emitter = emitters.get(type_key)
|
emitter = emitters.get(type_key)
|
||||||
if emitter:
|
if emitter:
|
||||||
emitter(lines, el, name, eid, indent)
|
if type_key == 'button':
|
||||||
|
emitter(lines, el, name, eid, indent, in_cmd_bar=in_cmd_bar)
|
||||||
|
else:
|
||||||
|
emitter(lines, el, name, eid, indent)
|
||||||
|
|
||||||
|
|
||||||
def emit_group(lines, el, name, eid, indent):
|
def emit_group(lines, el, name, eid, indent):
|
||||||
@@ -1670,6 +1837,8 @@ def emit_group(lines, el, name, eid, indent):
|
|||||||
if group_val == 'collapsible':
|
if group_val == 'collapsible':
|
||||||
lines.append(f'{inner}<Group>Vertical</Group>')
|
lines.append(f'{inner}<Group>Vertical</Group>')
|
||||||
lines.append(f'{inner}<Behavior>Collapsible</Behavior>')
|
lines.append(f'{inner}<Behavior>Collapsible</Behavior>')
|
||||||
|
if el.get('collapsed') is True:
|
||||||
|
lines.append(f'{inner}<Collapsed>true</Collapsed>')
|
||||||
|
|
||||||
# Representation
|
# Representation
|
||||||
if el.get('representation'):
|
if el.get('representation'):
|
||||||
@@ -1705,6 +1874,43 @@ def emit_group(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{indent}</UsualGroup>')
|
lines.append(f'{indent}</UsualGroup>')
|
||||||
|
|
||||||
|
|
||||||
|
def emit_column_group(lines, el, name, eid, indent):
|
||||||
|
lines.append(f'{indent}<ColumnGroup name="{name}" id="{eid}">')
|
||||||
|
inner = f'{indent}\t'
|
||||||
|
|
||||||
|
emit_title(lines, el, name, inner)
|
||||||
|
|
||||||
|
group_val = str(el.get('columnGroup', ''))
|
||||||
|
orientation_map = {
|
||||||
|
'horizontal': 'Horizontal',
|
||||||
|
'vertical': 'Vertical',
|
||||||
|
'inCell': 'InCell',
|
||||||
|
}
|
||||||
|
orientation = orientation_map.get(group_val)
|
||||||
|
if orientation:
|
||||||
|
lines.append(f'{inner}<Group>{orientation}</Group>')
|
||||||
|
|
||||||
|
if el.get('showTitle') is False:
|
||||||
|
lines.append(f'{inner}<ShowTitle>false</ShowTitle>')
|
||||||
|
if el.get('showInHeader') is not None:
|
||||||
|
sh_val = 'true' if el['showInHeader'] else 'false'
|
||||||
|
lines.append(f'{inner}<ShowInHeader>{sh_val}</ShowInHeader>')
|
||||||
|
if el.get('width'):
|
||||||
|
lines.append(f'{inner}<Width>{el["width"]}</Width>')
|
||||||
|
|
||||||
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
|
emit_companion(lines, 'ExtendedTooltip', f'{name}РасширеннаяПодсказка', inner)
|
||||||
|
|
||||||
|
if el.get('children') and len(el['children']) > 0:
|
||||||
|
lines.append(f'{inner}<ChildItems>')
|
||||||
|
for child in el['children']:
|
||||||
|
emit_element(lines, child, f'{inner}\t')
|
||||||
|
lines.append(f'{inner}</ChildItems>')
|
||||||
|
|
||||||
|
lines.append(f'{indent}</ColumnGroup>')
|
||||||
|
|
||||||
|
|
||||||
def emit_input(lines, el, name, eid, indent):
|
def emit_input(lines, el, name, eid, indent):
|
||||||
lines.append(f'{indent}<InputField name="{name}" id="{eid}">')
|
lines.append(f'{indent}<InputField name="{name}" id="{eid}">')
|
||||||
inner = f'{indent}\t'
|
inner = f'{indent}\t'
|
||||||
@@ -1712,7 +1918,7 @@ def emit_input(lines, el, name, eid, indent):
|
|||||||
if el.get('path'):
|
if el.get('path'):
|
||||||
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('titleLocation'):
|
if el.get('titleLocation'):
|
||||||
@@ -1736,10 +1942,17 @@ def emit_input(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{inner}<AutoMarkIncomplete>true</AutoMarkIncomplete>')
|
lines.append(f'{inner}<AutoMarkIncomplete>true</AutoMarkIncomplete>')
|
||||||
if el.get('skipOnInput') is True:
|
if el.get('skipOnInput') is True:
|
||||||
lines.append(f'{inner}<SkipOnInput>true</SkipOnInput>')
|
lines.append(f'{inner}<SkipOnInput>true</SkipOnInput>')
|
||||||
if el.get('autoMaxWidth') is False:
|
if 'autoMaxWidth' in el:
|
||||||
|
if el['autoMaxWidth'] is False:
|
||||||
|
lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>')
|
||||||
|
elif el.get('multiLine') is True:
|
||||||
lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>')
|
lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>')
|
||||||
|
if el.get('maxWidth') is not None:
|
||||||
|
lines.append(f'{inner}<MaxWidth>{el["maxWidth"]}</MaxWidth>')
|
||||||
if el.get('autoMaxHeight') is False:
|
if el.get('autoMaxHeight') is False:
|
||||||
lines.append(f'{inner}<AutoMaxHeight>false</AutoMaxHeight>')
|
lines.append(f'{inner}<AutoMaxHeight>false</AutoMaxHeight>')
|
||||||
|
if el.get('maxHeight') is not None:
|
||||||
|
lines.append(f'{inner}<MaxHeight>{el["maxHeight"]}</MaxHeight>')
|
||||||
if el.get('width'):
|
if el.get('width'):
|
||||||
lines.append(f'{inner}<Width>{el["width"]}</Width>')
|
lines.append(f'{inner}<Width>{el["width"]}</Width>')
|
||||||
if el.get('height'):
|
if el.get('height'):
|
||||||
@@ -1768,11 +1981,11 @@ def emit_check(lines, el, name, eid, indent):
|
|||||||
if el.get('path'):
|
if el.get('path'):
|
||||||
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('titleLocation'):
|
tl = el.get('titleLocation') or 'Right'
|
||||||
lines.append(f'{inner}<TitleLocation>{el["titleLocation"]}</TitleLocation>')
|
lines.append(f'{inner}<TitleLocation>{tl}</TitleLocation>')
|
||||||
|
|
||||||
# Companions
|
# Companions
|
||||||
emit_companion(lines, 'ContextMenu', f'{name}\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435\u041c\u0435\u043d\u044e', inner)
|
emit_companion(lines, 'ContextMenu', f'{name}\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435\u041c\u0435\u043d\u044e', inner)
|
||||||
@@ -1783,16 +1996,80 @@ def emit_check(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{indent}</CheckBoxField>')
|
lines.append(f'{indent}</CheckBoxField>')
|
||||||
|
|
||||||
|
|
||||||
|
def emit_radio_button_field(lines, el, name, eid, indent):
|
||||||
|
lines.append(f'{indent}<RadioButtonField name="{name}" id="{eid}">')
|
||||||
|
inner = f'{indent}\t'
|
||||||
|
|
||||||
|
if el.get('path'):
|
||||||
|
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||||
|
|
||||||
|
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||||
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
|
tl_raw = el.get('titleLocation')
|
||||||
|
if tl_raw:
|
||||||
|
loc_map = {'none': 'None', 'left': 'Left', 'right': 'Right', 'top': 'Top', 'bottom': 'Bottom'}
|
||||||
|
tl = loc_map.get(str(tl_raw), str(tl_raw))
|
||||||
|
else:
|
||||||
|
tl = 'None'
|
||||||
|
lines.append(f'{inner}<TitleLocation>{tl}</TitleLocation>')
|
||||||
|
|
||||||
|
rbt = normalize_radio_button_type(el.get('radioButtonType'))
|
||||||
|
lines.append(f'{inner}<RadioButtonType>{rbt}</RadioButtonType>')
|
||||||
|
|
||||||
|
if el.get('columnsCount') is not None:
|
||||||
|
lines.append(f'{inner}<ColumnsCount>{el["columnsCount"]}</ColumnsCount>')
|
||||||
|
|
||||||
|
choice_list = el.get('choiceList') or []
|
||||||
|
if choice_list:
|
||||||
|
lines.append(f'{inner}<ChoiceList>')
|
||||||
|
item_indent = f'{inner}\t'
|
||||||
|
for item in choice_list:
|
||||||
|
if not isinstance(item, dict):
|
||||||
|
continue
|
||||||
|
val_raw = item.get('value', item.get('значение'))
|
||||||
|
has_pres = any(k in item for k in ('presentation', 'представление', 'title'))
|
||||||
|
pres_raw = item.get('presentation', item.get('представление', item.get('title')))
|
||||||
|
|
||||||
|
norm = normalize_choice_value(val_raw)
|
||||||
|
|
||||||
|
if not has_pres:
|
||||||
|
if norm['xsi_type'] == 'xr:DesignTimeRef':
|
||||||
|
tail = norm['text'].split('.')[-1]
|
||||||
|
pres_raw = title_from_name(tail)
|
||||||
|
else:
|
||||||
|
pres_raw = norm['text']
|
||||||
|
|
||||||
|
lines.append(f'{item_indent}<xr:Item>')
|
||||||
|
val_indent = f'{item_indent}\t'
|
||||||
|
lines.append(f'{val_indent}<xr:Presentation/>')
|
||||||
|
lines.append(f'{val_indent}<xr:CheckState>0</xr:CheckState>')
|
||||||
|
lines.append(f'{val_indent}<xr:Value xsi:type="FormChoiceListDesTimeValue">')
|
||||||
|
emit_choice_presentation(lines, pres_raw, f'{val_indent}\t')
|
||||||
|
lines.append(f'{val_indent}\t<Value xsi:type="{norm["xsi_type"]}">{esc_xml(norm["text"])}</Value>')
|
||||||
|
lines.append(f'{val_indent}</xr:Value>')
|
||||||
|
lines.append(f'{item_indent}</xr:Item>')
|
||||||
|
lines.append(f'{inner}</ChoiceList>')
|
||||||
|
|
||||||
|
emit_companion(lines, 'ContextMenu', f'{name}КонтекстноеМеню', inner)
|
||||||
|
emit_companion(lines, 'ExtendedTooltip', f'{name}РасширеннаяПодсказка', inner)
|
||||||
|
|
||||||
|
emit_events(lines, el, name, inner, 'radio')
|
||||||
|
|
||||||
|
lines.append(f'{indent}</RadioButtonField>')
|
||||||
|
|
||||||
|
|
||||||
def emit_label(lines, el, name, eid, indent):
|
def emit_label(lines, el, name, eid, indent):
|
||||||
lines.append(f'{indent}<LabelDecoration name="{name}" id="{eid}">')
|
lines.append(f'{indent}<LabelDecoration name="{name}" id="{eid}">')
|
||||||
inner = f'{indent}\t'
|
inner = f'{indent}\t'
|
||||||
|
|
||||||
if el.get('title'):
|
label_title = el.get('title') or title_from_name(name)
|
||||||
|
if label_title:
|
||||||
formatted = 'true' if el.get('hyperlink') is True else 'false'
|
formatted = 'true' if el.get('hyperlink') is True else 'false'
|
||||||
lines.append(f'{inner}<Title formatted="{formatted}">')
|
lines.append(f'{inner}<Title formatted="{formatted}">')
|
||||||
lines.append(f'{inner}\t<v8:item>')
|
lines.append(f'{inner}\t<v8:item>')
|
||||||
lines.append(f'{inner}\t\t<v8:lang>ru</v8:lang>')
|
lines.append(f'{inner}\t\t<v8:lang>ru</v8:lang>')
|
||||||
lines.append(f'{inner}\t\t<v8:content>{esc_xml(str(el["title"]))}</v8:content>')
|
lines.append(f'{inner}\t\t<v8:content>{esc_xml(str(label_title))}</v8:content>')
|
||||||
lines.append(f'{inner}\t</v8:item>')
|
lines.append(f'{inner}\t</v8:item>')
|
||||||
lines.append(f'{inner}</Title>')
|
lines.append(f'{inner}</Title>')
|
||||||
|
|
||||||
@@ -1802,8 +2079,12 @@ def emit_label(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{inner}<Hyperlink>true</Hyperlink>')
|
lines.append(f'{inner}<Hyperlink>true</Hyperlink>')
|
||||||
if el.get('autoMaxWidth') is False:
|
if el.get('autoMaxWidth') is False:
|
||||||
lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>')
|
lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>')
|
||||||
|
if el.get('maxWidth') is not None:
|
||||||
|
lines.append(f'{inner}<MaxWidth>{el["maxWidth"]}</MaxWidth>')
|
||||||
if el.get('autoMaxHeight') is False:
|
if el.get('autoMaxHeight') is False:
|
||||||
lines.append(f'{inner}<AutoMaxHeight>false</AutoMaxHeight>')
|
lines.append(f'{inner}<AutoMaxHeight>false</AutoMaxHeight>')
|
||||||
|
if el.get('maxHeight') is not None:
|
||||||
|
lines.append(f'{inner}<MaxHeight>{el["maxHeight"]}</MaxHeight>')
|
||||||
if el.get('width'):
|
if el.get('width'):
|
||||||
lines.append(f'{inner}<Width>{el["width"]}</Width>')
|
lines.append(f'{inner}<Width>{el["width"]}</Width>')
|
||||||
if el.get('height'):
|
if el.get('height'):
|
||||||
@@ -1825,7 +2106,7 @@ def emit_label_field(lines, el, name, eid, indent):
|
|||||||
if el.get('path'):
|
if el.get('path'):
|
||||||
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('hyperlink') is True:
|
if el.get('hyperlink') is True:
|
||||||
@@ -1847,7 +2128,7 @@ def emit_table(lines, el, name, eid, indent):
|
|||||||
if el.get('path'):
|
if el.get('path'):
|
||||||
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('representation'):
|
if el.get('representation'):
|
||||||
@@ -1935,7 +2216,7 @@ def emit_page(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{indent}<Page name="{name}" id="{eid}">')
|
lines.append(f'{indent}<Page name="{name}" id="{eid}">')
|
||||||
inner = f'{indent}\t'
|
inner = f'{indent}\t'
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=True)
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('group'):
|
if el.get('group'):
|
||||||
@@ -1962,14 +2243,42 @@ def emit_page(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{indent}</Page>')
|
lines.append(f'{indent}</Page>')
|
||||||
|
|
||||||
|
|
||||||
def emit_button(lines, el, name, eid, indent):
|
def emit_button(lines, el, name, eid, indent, in_cmd_bar=False):
|
||||||
lines.append(f'{indent}<Button name="{name}" id="{eid}">')
|
lines.append(f'{indent}<Button name="{name}" id="{eid}">')
|
||||||
inner = f'{indent}\t'
|
inner = f'{indent}\t'
|
||||||
|
|
||||||
# Type
|
# Type — context-aware. Inside command bars (cmdBar/autoCmdBar/popup) only
|
||||||
|
# CommandBarButton/CommandBarHyperlink are valid; UsualButton/Hyperlink would be ignored.
|
||||||
|
# Forgiving resolver: any "ordinary button" hint resolves to UsualButton/CommandBarButton,
|
||||||
|
# any "hyperlink" hint resolves to Hyperlink/CommandBarHyperlink — depending on context.
|
||||||
|
btn_type = None
|
||||||
if el.get('type'):
|
if el.get('type'):
|
||||||
btn_type_map = {'usual': 'UsualButton', 'hyperlink': 'Hyperlink', 'commandBar': 'CommandBarButton'}
|
raw = str(el['type'])
|
||||||
btn_type = btn_type_map.get(str(el['type']), str(el['type']))
|
if in_cmd_bar:
|
||||||
|
cmd_bar_map = {
|
||||||
|
'usual': 'CommandBarButton',
|
||||||
|
'UsualButton': 'CommandBarButton',
|
||||||
|
'commandBar': 'CommandBarButton',
|
||||||
|
'CommandBarButton': 'CommandBarButton',
|
||||||
|
'hyperlink': 'CommandBarHyperlink',
|
||||||
|
'Hyperlink': 'CommandBarHyperlink',
|
||||||
|
'CommandBarHyperlink': 'CommandBarHyperlink',
|
||||||
|
}
|
||||||
|
btn_type = cmd_bar_map.get(raw, raw)
|
||||||
|
else:
|
||||||
|
normal_map = {
|
||||||
|
'usual': 'UsualButton',
|
||||||
|
'UsualButton': 'UsualButton',
|
||||||
|
'commandBar': 'UsualButton',
|
||||||
|
'CommandBarButton': 'UsualButton',
|
||||||
|
'hyperlink': 'Hyperlink',
|
||||||
|
'Hyperlink': 'Hyperlink',
|
||||||
|
'CommandBarHyperlink': 'Hyperlink',
|
||||||
|
}
|
||||||
|
btn_type = normal_map.get(raw, raw)
|
||||||
|
elif in_cmd_bar:
|
||||||
|
btn_type = 'CommandBarButton'
|
||||||
|
if btn_type:
|
||||||
lines.append(f'{inner}<Type>{btn_type}</Type>')
|
lines.append(f'{inner}<Type>{btn_type}</Type>')
|
||||||
|
|
||||||
# CommandName
|
# CommandName
|
||||||
@@ -1983,7 +2292,7 @@ def emit_button(lines, el, name, eid, indent):
|
|||||||
else:
|
else:
|
||||||
lines.append(f'{inner}<CommandName>Form.StandardCommand.{sc}</CommandName>')
|
lines.append(f'{inner}<CommandName>Form.StandardCommand.{sc}</CommandName>')
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=not (el.get('command') or el.get('stdCommand')))
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('defaultButton') is True:
|
if el.get('defaultButton') is True:
|
||||||
@@ -2071,7 +2380,7 @@ def emit_calendar(lines, el, name, eid, indent):
|
|||||||
if el.get('path'):
|
if el.get('path'):
|
||||||
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
# Companions
|
# Companions
|
||||||
@@ -2096,7 +2405,7 @@ def emit_command_bar(lines, el, name, eid, indent):
|
|||||||
if el.get('children') and len(el['children']) > 0:
|
if el.get('children') and len(el['children']) > 0:
|
||||||
lines.append(f'{inner}<ChildItems>')
|
lines.append(f'{inner}<ChildItems>')
|
||||||
for child in el['children']:
|
for child in el['children']:
|
||||||
emit_element(lines, child, f'{inner}\t')
|
emit_element(lines, child, f'{inner}\t', in_cmd_bar=True)
|
||||||
lines.append(f'{inner}</ChildItems>')
|
lines.append(f'{inner}</ChildItems>')
|
||||||
|
|
||||||
lines.append(f'{indent}</CommandBar>')
|
lines.append(f'{indent}</CommandBar>')
|
||||||
@@ -2106,7 +2415,7 @@ def emit_popup(lines, el, name, eid, indent):
|
|||||||
lines.append(f'{indent}<Popup name="{name}" id="{eid}">')
|
lines.append(f'{indent}<Popup name="{name}" id="{eid}">')
|
||||||
inner = f'{indent}\t'
|
inner = f'{indent}\t'
|
||||||
|
|
||||||
emit_title(lines, el, name, inner)
|
emit_title(lines, el, name, inner, auto=True)
|
||||||
emit_common_flags(lines, el, inner)
|
emit_common_flags(lines, el, inner)
|
||||||
|
|
||||||
if el.get('picture'):
|
if el.get('picture'):
|
||||||
@@ -2122,7 +2431,7 @@ def emit_popup(lines, el, name, eid, indent):
|
|||||||
if el.get('children') and len(el['children']) > 0:
|
if el.get('children') and len(el['children']) > 0:
|
||||||
lines.append(f'{inner}<ChildItems>')
|
lines.append(f'{inner}<ChildItems>')
|
||||||
for child in el['children']:
|
for child in el['children']:
|
||||||
emit_element(lines, child, f'{inner}\t')
|
emit_element(lines, child, f'{inner}\t', in_cmd_bar=True)
|
||||||
lines.append(f'{inner}</ChildItems>')
|
lines.append(f'{inner}</ChildItems>')
|
||||||
|
|
||||||
lines.append(f'{indent}</Popup>')
|
lines.append(f'{indent}</Popup>')
|
||||||
@@ -2142,8 +2451,11 @@ def emit_attributes(lines, attrs, indent):
|
|||||||
lines.append(f'{indent}\t<Attribute name="{attr_name}" id="{attr_id}">')
|
lines.append(f'{indent}\t<Attribute name="{attr_name}" id="{attr_id}">')
|
||||||
inner = f'{indent}\t\t'
|
inner = f'{indent}\t\t'
|
||||||
|
|
||||||
if attr.get('title'):
|
attr_title = attr.get('title')
|
||||||
emit_mltext(lines, inner, 'Title', str(attr['title']))
|
if not attr_title and attr.get('main') is not True:
|
||||||
|
attr_title = title_from_name(attr_name)
|
||||||
|
if attr_title:
|
||||||
|
emit_mltext(lines, inner, 'Title', str(attr_title))
|
||||||
|
|
||||||
# Type
|
# Type
|
||||||
if attr.get('type'):
|
if attr.get('type'):
|
||||||
@@ -2153,7 +2465,11 @@ def emit_attributes(lines, attrs, indent):
|
|||||||
|
|
||||||
if attr.get('main') is True:
|
if attr.get('main') is True:
|
||||||
lines.append(f'{inner}<MainAttribute>true</MainAttribute>')
|
lines.append(f'{inner}<MainAttribute>true</MainAttribute>')
|
||||||
if attr.get('savedData') is True:
|
main_saved = False
|
||||||
|
if attr.get('main') is True and attr.get('type'):
|
||||||
|
t = str(attr['type'])
|
||||||
|
main_saved = bool(re.match(r'^(CatalogObject|DocumentObject|ChartOfAccountsObject|ChartOfCalculationTypesObject|ChartOfCharacteristicTypesObject|ExchangePlanObject|BusinessProcessObject|TaskObject)\.', t)) or ('RecordManager.' in t)
|
||||||
|
if attr.get('savedData') is True or main_saved:
|
||||||
lines.append(f'{inner}<SavedData>true</SavedData>')
|
lines.append(f'{inner}<SavedData>true</SavedData>')
|
||||||
if attr.get('fillChecking'):
|
if attr.get('fillChecking'):
|
||||||
lines.append(f'{inner}<FillChecking>{attr["fillChecking"]}</FillChecking>')
|
lines.append(f'{inner}<FillChecking>{attr["fillChecking"]}</FillChecking>')
|
||||||
@@ -2219,8 +2535,9 @@ def emit_commands(lines, cmds, indent):
|
|||||||
lines.append(f'{indent}\t<Command name="{cmd["name"]}" id="{cmd_id}">')
|
lines.append(f'{indent}\t<Command name="{cmd["name"]}" id="{cmd_id}">')
|
||||||
inner = f'{indent}\t\t'
|
inner = f'{indent}\t\t'
|
||||||
|
|
||||||
if cmd.get('title'):
|
cmd_title = cmd.get('title') or title_from_name(str(cmd['name']))
|
||||||
emit_mltext(lines, inner, 'Title', str(cmd['title']))
|
if cmd_title:
|
||||||
|
emit_mltext(lines, inner, 'Title', str(cmd_title))
|
||||||
|
|
||||||
if cmd.get('action'):
|
if cmd.get('action'):
|
||||||
lines.append(f'{inner}<Action>{cmd["action"]}</Action>')
|
lines.append(f'{inner}<Action>{cmd["action"]}</Action>')
|
||||||
@@ -2572,7 +2889,7 @@ def main():
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _apply_dlist_table_heuristic(el, list_name):
|
def _apply_dlist_table_heuristic(el, list_name, has_main_table):
|
||||||
if not isinstance(el, dict):
|
if not isinstance(el, dict):
|
||||||
return
|
return
|
||||||
if el.get('table') is not None and str(el.get('path', '')) == list_name:
|
if el.get('table') is not None and str(el.get('path', '')) == list_name:
|
||||||
@@ -2580,9 +2897,12 @@ def main():
|
|||||||
el['tableAutofill'] = False
|
el['tableAutofill'] = False
|
||||||
if 'commandBarLocation' not in el:
|
if 'commandBarLocation' not in el:
|
||||||
el['commandBarLocation'] = 'None'
|
el['commandBarLocation'] = 'None'
|
||||||
|
# DefaultPicture доступен только если у DynamicList есть основная таблица
|
||||||
|
if has_main_table and not el.get('rowPictureDataPath'):
|
||||||
|
el['rowPictureDataPath'] = f'{list_name}.DefaultPicture'
|
||||||
if isinstance(el.get('children'), list):
|
if isinstance(el.get('children'), list):
|
||||||
for child in el['children']:
|
for child in el['children']:
|
||||||
_apply_dlist_table_heuristic(child, list_name)
|
_apply_dlist_table_heuristic(child, list_name, has_main_table)
|
||||||
|
|
||||||
def _is_object_like_type(t):
|
def _is_object_like_type(t):
|
||||||
if not t:
|
if not t:
|
||||||
@@ -2647,8 +2967,10 @@ def main():
|
|||||||
if isinstance(defn.get('attributes'), list) and isinstance(defn.get('elements'), list):
|
if isinstance(defn.get('attributes'), list) and isinstance(defn.get('elements'), list):
|
||||||
main_attr = next((a for a in defn['attributes'] if isinstance(a, dict) and a.get('main') is True), None)
|
main_attr = next((a for a in defn['attributes'] if isinstance(a, dict) and a.get('main') is True), None)
|
||||||
if main_attr and str(main_attr.get('type', '')) == 'DynamicList':
|
if main_attr and str(main_attr.get('type', '')) == 'DynamicList':
|
||||||
|
settings = main_attr.get('settings') or {}
|
||||||
|
has_mt = bool(isinstance(settings, dict) and settings.get('mainTable'))
|
||||||
for el in defn['elements']:
|
for el in defn['elements']:
|
||||||
_apply_dlist_table_heuristic(el, main_attr.get('name', ''))
|
_apply_dlist_table_heuristic(el, main_attr.get('name', ''), has_mt)
|
||||||
|
|
||||||
# 1b.5: Compute main AutoCommandBar Autofill (B3)
|
# 1b.5: Compute main AutoCommandBar Autofill (B3)
|
||||||
def _compute_main_acb_autofill():
|
def _compute_main_acb_autofill():
|
||||||
@@ -2677,9 +2999,16 @@ def main():
|
|||||||
emit_mltext(lines, '\t', 'Title', str(form_title))
|
emit_mltext(lines, '\t', 'Title', str(form_title))
|
||||||
|
|
||||||
# Properties (skip 'title' — handled above)
|
# Properties (skip 'title' — handled above)
|
||||||
if defn.get('properties'):
|
# When form-level Title is set, default autoTitle=false (≈95% of ERP forms do this;
|
||||||
props_clone = {k: v for k, v in defn['properties'].items() if k != 'title'}
|
# otherwise platform appends synonym → "Title: Synonym" double-titles).
|
||||||
emit_properties(lines, props_clone, '\t')
|
props_src = defn.get('properties') or {}
|
||||||
|
props_clone = OrderedDict()
|
||||||
|
if form_title and 'autoTitle' not in props_src:
|
||||||
|
props_clone['autoTitle'] = False
|
||||||
|
for k, v in props_src.items():
|
||||||
|
if k != 'title':
|
||||||
|
props_clone[k] = v
|
||||||
|
emit_properties(lines, props_clone, '\t')
|
||||||
|
|
||||||
# CommandSet (excluded commands)
|
# CommandSet (excluded commands)
|
||||||
if defn.get('excludedCommands') and len(defn['excludedCommands']) > 0:
|
if defn.get('excludedCommands') and len(defn['excludedCommands']) > 0:
|
||||||
@@ -2711,7 +3040,7 @@ def main():
|
|||||||
if has_acb_children:
|
if has_acb_children:
|
||||||
lines.append('\t\t<ChildItems>')
|
lines.append('\t\t<ChildItems>')
|
||||||
for child in main_acb_def['children']:
|
for child in main_acb_def['children']:
|
||||||
emit_element(lines, child, '\t\t\t')
|
emit_element(lines, child, '\t\t\t', in_cmd_bar=True)
|
||||||
lines.append('\t\t</ChildItems>')
|
lines.append('\t\t</ChildItems>')
|
||||||
lines.append('\t</AutoCommandBar>')
|
lines.append('\t</AutoCommandBar>')
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-edit/scripts/form-edit.ps1 -FormPath "<путь>" -JsonPath "<путь>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-edit.ps1" -FormPath "<путь>" -JsonPath "<путь>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## JSON формат
|
## JSON формат
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-info/scripts/form-info.ps1 -FormPath "<путь к Form.xml>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-info.ps1" -FormPath "<путь к Form.xml>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Параметры
|
## Параметры
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ allowed-tools: []
|
|||||||
├─ Информационные надписи (label, hyperlink)
|
├─ Информационные надписи (label, hyperlink)
|
||||||
Рабочая область
|
Рабочая область
|
||||||
├─ Таблица данных или Pages с вкладками
|
├─ Таблица данных или Pages с вкладками
|
||||||
Кнопки действий
|
Главная АКП формы (autoCmdBar)
|
||||||
├─ Выполнить / Применить (defaultButton)
|
├─ Выполнить / Применить (defaultButton: true)
|
||||||
├─ Закрыть (stdCommand: Close)
|
└─ Закрыть (stdCommand: Close)
|
||||||
```
|
```
|
||||||
|
|
||||||
**События:** OnCreateAtServer, OnOpen, NotificationProcessing
|
**События:** OnCreateAtServer, OnOpen, NotificationProcessing
|
||||||
@@ -90,12 +90,12 @@ allowed-tools: []
|
|||||||
├─ Шаг1: описание + параметры
|
├─ Шаг1: описание + параметры
|
||||||
├─ Шаг2: основная работа
|
├─ Шаг2: основная работа
|
||||||
└─ Шаг3: результат
|
└─ Шаг3: результат
|
||||||
Кнопки (horizontal)
|
Главная АКП формы (autoCmdBar)
|
||||||
├─ Назад (command), Далее (command, defaultButton), Выполнить (command)
|
├─ Назад, Далее (defaultButton: true), Выполнить
|
||||||
└─ Закрыть (stdCommand: Close)
|
└─ Закрыть (stdCommand: Close)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Свойства:** windowOpeningMode=LockOwnerWindow, commandBarLocation=None
|
**Свойства:** windowOpeningMode=LockOwnerWindow
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ allowed-tools: []
|
|||||||
| Номер+Дата | `ГруппаНомерДата` | horizontal |
|
| Номер+Дата | `ГруппаНомерДата` | horizontal |
|
||||||
| Подвал | `ГруппаПодвал` | vertical |
|
| Подвал | `ГруппаПодвал` | vertical |
|
||||||
| Итоги | `ГруппаИтоги` | horizontal |
|
| Итоги | `ГруппаИтоги` | horizontal |
|
||||||
| Кнопки | `ГруппаКнопок` | horizontal |
|
| Главная АКП формы | `ФормаКоманднаяПанель` | autoCmdBar |
|
||||||
| Страницы | `ГруппаСтраницы` / `Страницы` | pages |
|
| Страницы | `ГруппаСтраницы` / `Страницы` | pages |
|
||||||
| Предупреждение | `ГруппаПредупреждение` | horizontal, visible:false |
|
| Предупреждение | `ГруппаПредупреждение` | horizontal, visible:false |
|
||||||
| Доп. секция | `ГруппаДополнительно` / `ГруппаПрочее` | vertical, collapse |
|
| Доп. секция | `ГруппаДополнительно` / `ГруппаПрочее` | vertical, collapse |
|
||||||
@@ -150,7 +150,7 @@ allowed-tools: []
|
|||||||
|
|
||||||
1. **Порядок чтения.** Сверху вниз, слева направо. Самое важное — вверху.
|
1. **Порядок чтения.** Сверху вниз, слева направо. Самое важное — вверху.
|
||||||
2. **Двухколоночная шапка.** Основные реквизиты слева (контрагент, склад), организационные справа (организация, подразделение).
|
2. **Двухколоночная шапка.** Основные реквизиты слева (контрагент, склад), организационные справа (организация, подразделение).
|
||||||
3. **Кнопки действий внизу.** Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя.
|
3. **Кнопки действий — на главной АКП формы** (`autoCmdBar`), не в отдельной группе на форме. Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя.
|
||||||
4. **Таблицы — основная область.** Табличные части занимают большую часть формы, обычно на Pages.
|
4. **Таблицы — основная область.** Табличные части занимают большую часть формы, обычно на Pages.
|
||||||
5. **Итоги рядом с таблицей.** В подвале, горизонтальная группа, все поля readOnly.
|
5. **Итоги рядом с таблицей.** В подвале, горизонтальная группа, все поля readOnly.
|
||||||
6. **Фильтры — отдельная зона.** Над списком, alwaysHorizontal, пара «флажок + поле» на каждый фильтр.
|
6. **Фильтры — отдельная зона.** Над списком, alwaysHorizontal, пара «флажок + поле» на каждый фильтр.
|
||||||
@@ -166,8 +166,8 @@ allowed-tools: []
|
|||||||
Для необязательных секций (подписи, дополнительно, прочее):
|
Для необязательных секций (подписи, дополнительно, прочее):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{ "group": "vertical", "name": "ГруппаПодписи", "title": "Подписи",
|
{ "group": "collapsible", "name": "ГруппаПодписи", "title": "Подписи",
|
||||||
"behavior": "Collapsible", "collapsed": true, "children": [...] }
|
"collapsed": true, "children": [...] }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Баннер-предупреждение
|
### Баннер-предупреждение
|
||||||
@@ -233,7 +233,7 @@ allowed-tools: []
|
|||||||
{ "input": "ДанныеКоличество", "path": "Объект.Данные.Количество", "on": ["OnChange"] },
|
{ "input": "ДанныеКоличество", "path": "Объект.Данные.Количество", "on": ["OnChange"] },
|
||||||
{ "input": "ДанныеСумма", "path": "Объект.Данные.Сумма", "readOnly": true }
|
{ "input": "ДанныеСумма", "path": "Объект.Данные.Сумма", "readOnly": true }
|
||||||
]},
|
]},
|
||||||
{ "group": "horizontal", "name": "ГруппаКнопок", "children": [
|
{ "autoCmdBar": "ФормаКоманднаяПанель", "children": [
|
||||||
{ "button": "Загрузить", "command": "Загрузить", "title": "Загрузить из файла", "defaultButton": true },
|
{ "button": "Загрузить", "command": "Загрузить", "title": "Загрузить из файла", "defaultButton": true },
|
||||||
{ "button": "Очистить", "command": "Очистить", "title": "Очистить таблицу" },
|
{ "button": "Очистить", "command": "Очистить", "title": "Очистить таблицу" },
|
||||||
{ "button": "Закрыть", "stdCommand": "Close" }
|
{ "button": "Закрыть", "stdCommand": "Close" }
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-remove/scripts/remove-form.ps1 -ObjectName "<ObjectName>" -FormName "<FormName>" [-SrcDir "<SrcDir>"]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/remove-form.ps1" -ObjectName "<ObjectName>" -FormName "<FormName>" [-SrcDir "<SrcDir>"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Что удаляется
|
## Что удаляется
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-remove v1.1 — Remove form from 1C object
|
# form-remove v1.2 — Remove form from 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -12,6 +12,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
# --- Проверки ---
|
# --- Проверки ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# remove-form v1.0 — Remove form from 1C object
|
# remove-form v1.1 — Remove form from 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-validate/scripts/form-validate.ps1 -FormPath "Catalogs/Номенклатура/Forms/ФормаЭлемента"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-validate.ps1" -FormPath "Catalogs/Номенклатура/Forms/ФормаЭлемента"
|
||||||
powershell.exe -NoProfile -File .claude/skills/form-validate/scripts/form-validate.ps1 -FormPath "src/МояОбработка/Forms/Форма/Ext/Form.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/form-validate.ps1" -FormPath "src/МояОбработка/Forms/Форма/Ext/Form.xml"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/help-add/scripts/add-help.ps1 -ObjectName "<ObjectName>" [-Lang "<Lang>"] [-SrcDir "<SrcDir>"]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/add-help.ps1" -ObjectName "<ObjectName>" [-Lang "<Lang>"] [-SrcDir "<SrcDir>"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Что делает скрипт
|
## Что делает скрипт
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# help-add v1.3 — Add built-in help to 1C object
|
# help-add v1.4 — Add built-in help to 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -10,6 +10,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
# --- Detect format version ---
|
# --- Detect format version ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# add-help v1.3 — Add built-in help to 1C object
|
# add-help v1.4 — Add built-in help to 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python .claude/skills/img-grid/scripts/overlay-grid.py "<ImagePath>" [-c 50] [-o "<OutputPath>"]
|
python "${CLAUDE_SKILL_DIR}/scripts/overlay-grid.py" "<ImagePath>" [-c 50] [-o "<OutputPath>"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Требуется Python 3 с библиотекой Pillow (`pip install Pillow`).
|
Требуется Python 3 с библиотекой Pillow (`pip install Pillow`).
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ allowed-tools:
|
|||||||
### Inline mode
|
### Inline mode
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File '.claude/skills/interface-edit/scripts/interface-edit.ps1' -CIPath '<path>' -Operation hide -Value '<cmd>'
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/interface-edit.ps1" -CIPath '<path>' -Operation hide -Value '<cmd>'
|
||||||
```
|
```
|
||||||
|
|
||||||
### JSON mode
|
### JSON mode
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File '.claude/skills/interface-edit/scripts/interface-edit.ps1' -CIPath '<path>' -DefinitionFile '<json>'
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/interface-edit.ps1" -CIPath '<path>' -DefinitionFile '<json>'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Операции
|
## Операции
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File ".claude/skills/interface-validate/scripts/interface-validate.ps1" -CIPath "Subsystems/Продажи"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/interface-validate.ps1" -CIPath "Subsystems/Продажи"
|
||||||
powershell.exe -NoProfile -File ".claude/skills/interface-validate/scripts/interface-validate.ps1" -CIPath "Subsystems/Продажи/Ext/CommandInterface.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/interface-validate.ps1" -CIPath "Subsystems/Продажи/Ext/CommandInterface.xml"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-compile/scripts/meta-compile.ps1 -JsonPath "<json>" -OutputDir "<ConfigDir>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-compile.ps1" -JsonPath "<json>" -OutputDir "<ConfigDir>"
|
||||||
```
|
```
|
||||||
|
|
||||||
| Параметр | Описание |
|
| Параметр | Описание |
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
| `checkUnique` | `false` | CheckUnique |
|
| `checkUnique` | `false` | CheckUnique |
|
||||||
| `defaultPresentation` | `AsDescription` | DefaultPresentation |
|
| `defaultPresentation` | `AsDescription` | DefaultPresentation |
|
||||||
| `subordinationUse` | `ToItems` | SubordinationUse |
|
| `subordinationUse` | `ToItems` | SubordinationUse |
|
||||||
| `quickChoice` | `true` | QuickChoice |
|
| `quickChoice` | `false` | QuickChoice |
|
||||||
| `choiceMode` | `BothWays` | ChoiceMode |
|
| `choiceMode` | `BothWays` | ChoiceMode |
|
||||||
| `owners` | `[]` | Owners |
|
| `owners` | `[]` | Owners |
|
||||||
| `attributes` | `[]` | → Attribute в ChildObjects |
|
| `attributes` | `[]` | → Attribute в ChildObjects |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-compile v1.10 — Compile 1C metadata object from JSON
|
# meta-compile v1.11 — Compile 1C metadata object from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -1129,7 +1129,7 @@ function Emit-CatalogProperties {
|
|||||||
X "$i<Characteristics/>"
|
X "$i<Characteristics/>"
|
||||||
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
||||||
X "$i<EditType>InDialog</EditType>"
|
X "$i<EditType>InDialog</EditType>"
|
||||||
$quickChoice = if ($def.quickChoice -eq $false) { "false" } else { "true" }
|
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||||
$choiceMode = Get-EnumProp "ChoiceMode" "choiceMode" "BothWays"
|
$choiceMode = Get-EnumProp "ChoiceMode" "choiceMode" "BothWays"
|
||||||
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||||
X "$i<ChoiceMode>$choiceMode</ChoiceMode>"
|
X "$i<ChoiceMode>$choiceMode</ChoiceMode>"
|
||||||
@@ -1292,7 +1292,8 @@ function Emit-EnumProperties {
|
|||||||
Emit-StandardAttributes $i "Enum"
|
Emit-StandardAttributes $i "Enum"
|
||||||
X "$i<Characteristics/>"
|
X "$i<Characteristics/>"
|
||||||
|
|
||||||
X "$i<QuickChoice>true</QuickChoice>"
|
$quickChoice = if ($def.quickChoice -eq $false) { "false" } else { "true" }
|
||||||
|
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||||
X "$i<DefaultListForm/>"
|
X "$i<DefaultListForm/>"
|
||||||
X "$i<DefaultChoiceForm/>"
|
X "$i<DefaultChoiceForm/>"
|
||||||
@@ -1663,7 +1664,8 @@ function Emit-ExchangePlanProperties {
|
|||||||
X "$i<IncludeConfigurationExtensions>$includeExt</IncludeConfigurationExtensions>"
|
X "$i<IncludeConfigurationExtensions>$includeExt</IncludeConfigurationExtensions>"
|
||||||
|
|
||||||
X "$i<BasedOn/>"
|
X "$i<BasedOn/>"
|
||||||
X "$i<QuickChoice>true</QuickChoice>"
|
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||||
|
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||||
X "$i<InputByString>"
|
X "$i<InputByString>"
|
||||||
X "$i`t<xr:Field>ExchangePlan.$objName.StandardAttribute.Description</xr:Field>"
|
X "$i`t<xr:Field>ExchangePlan.$objName.StandardAttribute.Description</xr:Field>"
|
||||||
@@ -1764,7 +1766,8 @@ function Emit-ChartOfCharacteristicTypesProperties {
|
|||||||
X "$i<Characteristics/>"
|
X "$i<Characteristics/>"
|
||||||
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
||||||
X "$i<EditType>InDialog</EditType>"
|
X "$i<EditType>InDialog</EditType>"
|
||||||
X "$i<QuickChoice>true</QuickChoice>"
|
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||||
|
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||||
X "$i<InputByString>"
|
X "$i<InputByString>"
|
||||||
X "$i`t<xr:Field>ChartOfCharacteristicTypes.$objName.StandardAttribute.Description</xr:Field>"
|
X "$i`t<xr:Field>ChartOfCharacteristicTypes.$objName.StandardAttribute.Description</xr:Field>"
|
||||||
@@ -1905,7 +1908,8 @@ function Emit-ChartOfAccountsProperties {
|
|||||||
|
|
||||||
X "$i<Characteristics/>"
|
X "$i<Characteristics/>"
|
||||||
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
||||||
X "$i<QuickChoice>true</QuickChoice>"
|
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||||
|
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||||
X "$i<InputByString>"
|
X "$i<InputByString>"
|
||||||
X "$i`t<xr:Field>ChartOfAccounts.$objName.StandardAttribute.Description</xr:Field>"
|
X "$i`t<xr:Field>ChartOfAccounts.$objName.StandardAttribute.Description</xr:Field>"
|
||||||
@@ -2021,7 +2025,8 @@ function Emit-ChartOfCalculationTypesProperties {
|
|||||||
X "$i<Characteristics/>"
|
X "$i<Characteristics/>"
|
||||||
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
||||||
X "$i<EditType>InDialog</EditType>"
|
X "$i<EditType>InDialog</EditType>"
|
||||||
X "$i<QuickChoice>true</QuickChoice>"
|
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||||
|
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||||
X "$i<InputByString>"
|
X "$i<InputByString>"
|
||||||
X "$i`t<xr:Field>ChartOfCalculationTypes.$objName.StandardAttribute.Description</xr:Field>"
|
X "$i`t<xr:Field>ChartOfCalculationTypes.$objName.StandardAttribute.Description</xr:Field>"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# meta-compile v1.10 — Compile 1C metadata object from JSON
|
# meta-compile v1.11 — Compile 1C metadata object from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -1024,7 +1024,7 @@ def emit_catalog_properties(indent):
|
|||||||
X(f'{i}<Characteristics/>')
|
X(f'{i}<Characteristics/>')
|
||||||
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
||||||
X(f'{i}<EditType>InDialog</EditType>')
|
X(f'{i}<EditType>InDialog</EditType>')
|
||||||
quick_choice = 'false' if defn.get('quickChoice') is False else 'true'
|
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||||
choice_mode = get_enum_prop('ChoiceMode', 'choiceMode', 'BothWays')
|
choice_mode = get_enum_prop('ChoiceMode', 'choiceMode', 'BothWays')
|
||||||
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||||
X(f'{i}<ChoiceMode>{choice_mode}</ChoiceMode>')
|
X(f'{i}<ChoiceMode>{choice_mode}</ChoiceMode>')
|
||||||
@@ -1157,7 +1157,8 @@ def emit_enum_properties(indent):
|
|||||||
X(f'{i}<UseStandardCommands>false</UseStandardCommands>')
|
X(f'{i}<UseStandardCommands>false</UseStandardCommands>')
|
||||||
emit_standard_attributes(i, 'Enum')
|
emit_standard_attributes(i, 'Enum')
|
||||||
X(f'{i}<Characteristics/>')
|
X(f'{i}<Characteristics/>')
|
||||||
X(f'{i}<QuickChoice>true</QuickChoice>')
|
quick_choice = 'false' if defn.get('quickChoice') is False else 'true'
|
||||||
|
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||||
X(f'{i}<DefaultListForm/>')
|
X(f'{i}<DefaultListForm/>')
|
||||||
X(f'{i}<DefaultChoiceForm/>')
|
X(f'{i}<DefaultChoiceForm/>')
|
||||||
@@ -1471,7 +1472,8 @@ def emit_exchange_plan_properties(indent):
|
|||||||
X(f'{i}<DistributedInfoBase>{distributed}</DistributedInfoBase>')
|
X(f'{i}<DistributedInfoBase>{distributed}</DistributedInfoBase>')
|
||||||
X(f'{i}<IncludeConfigurationExtensions>{include_ext}</IncludeConfigurationExtensions>')
|
X(f'{i}<IncludeConfigurationExtensions>{include_ext}</IncludeConfigurationExtensions>')
|
||||||
X(f'{i}<BasedOn/>')
|
X(f'{i}<BasedOn/>')
|
||||||
X(f'{i}<QuickChoice>true</QuickChoice>')
|
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||||
|
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||||
X(f'{i}<InputByString>')
|
X(f'{i}<InputByString>')
|
||||||
X(f'{i}\t<xr:Field>ExchangePlan.{obj_name}.StandardAttribute.Description</xr:Field>')
|
X(f'{i}\t<xr:Field>ExchangePlan.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||||
@@ -1557,7 +1559,8 @@ def emit_chart_of_characteristic_types_properties(indent):
|
|||||||
X(f'{i}<Characteristics/>')
|
X(f'{i}<Characteristics/>')
|
||||||
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
||||||
X(f'{i}<EditType>InDialog</EditType>')
|
X(f'{i}<EditType>InDialog</EditType>')
|
||||||
X(f'{i}<QuickChoice>true</QuickChoice>')
|
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||||
|
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||||
X(f'{i}<InputByString>')
|
X(f'{i}<InputByString>')
|
||||||
X(f'{i}\t<xr:Field>ChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Description</xr:Field>')
|
X(f'{i}\t<xr:Field>ChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||||
@@ -1673,7 +1676,8 @@ def emit_chart_of_accounts_properties(indent):
|
|||||||
X(f'{i}</StandardTabularSections>')
|
X(f'{i}</StandardTabularSections>')
|
||||||
X(f'{i}<Characteristics/>')
|
X(f'{i}<Characteristics/>')
|
||||||
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
||||||
X(f'{i}<QuickChoice>true</QuickChoice>')
|
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||||
|
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||||
X(f'{i}<InputByString>')
|
X(f'{i}<InputByString>')
|
||||||
X(f'{i}\t<xr:Field>ChartOfAccounts.{obj_name}.StandardAttribute.Description</xr:Field>')
|
X(f'{i}\t<xr:Field>ChartOfAccounts.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||||
@@ -1764,7 +1768,8 @@ def emit_chart_of_calculation_types_properties(indent):
|
|||||||
X(f'{i}<Characteristics/>')
|
X(f'{i}<Characteristics/>')
|
||||||
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
||||||
X(f'{i}<EditType>InDialog</EditType>')
|
X(f'{i}<EditType>InDialog</EditType>')
|
||||||
X(f'{i}<QuickChoice>true</QuickChoice>')
|
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||||
|
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||||
X(f'{i}<InputByString>')
|
X(f'{i}<InputByString>')
|
||||||
X(f'{i}\t<xr:Field>ChartOfCalculationTypes.{obj_name}.StandardAttribute.Description</xr:Field>')
|
X(f'{i}\t<xr:Field>ChartOfCalculationTypes.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ allowed-tools:
|
|||||||
### Inline mode (простые операции)
|
### Inline mode (простые операции)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-edit/scripts/meta-edit.ps1 -ObjectPath "<path>" -Operation <op> -Value "<val>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-edit.ps1" -ObjectPath "<path>" -Operation <op> -Value "<val>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### JSON mode (сложные/комбинированные)
|
### JSON mode (сложные/комбинированные)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-edit/scripts/meta-edit.ps1 -DefinitionFile "<json>" -ObjectPath "<path>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-edit.ps1" -DefinitionFile "<json>" -ObjectPath "<path>"
|
||||||
```
|
```
|
||||||
|
|
||||||
| Параметр | Описание |
|
| Параметр | Описание |
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-info/scripts/meta-info.ps1 -ObjectPath "<путь>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-info.ps1" -ObjectPath "<путь>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Три режима
|
## Три режима
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-remove/scripts/meta-remove.ps1 -ConfigDir "<путь>" -Object "Catalog.Товары"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-remove.ps1" -ConfigDir "<путь>" -Object "Catalog.Товары"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Поддерживаемые типы
|
## Поддерживаемые типы
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-validate/scripts/meta-validate.ps1 -ObjectPath "Catalogs/Номенклатура/Номенклатура.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-validate.ps1" -ObjectPath "Catalogs/Номенклатура/Номенклатура.xml"
|
||||||
powershell.exe -NoProfile -File .claude/skills/meta-validate/scripts/meta-validate.ps1 -ObjectPath "Catalogs/Банки|Documents/Заказ"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-validate.ps1" -ObjectPath "Catalogs/Банки|Documents/Заказ"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/mxl-compile/scripts/mxl-compile.ps1 -JsonPath "<путь>.json" -OutputPath "<путь>/Template.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -JsonPath "<путь>.json" -OutputPath "<путь>/Template.xml"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Рабочий процесс
|
## Рабочий процесс
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/mxl-decompile/scripts/mxl-decompile.ps1 -TemplatePath "<путь>/Template.xml" [-OutputPath "<путь>.json"]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-decompile.ps1" -TemplatePath "<путь>/Template.xml" [-OutputPath "<путь>.json"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Рабочий процесс
|
## Рабочий процесс
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/mxl-info/scripts/mxl-info.ps1 -TemplatePath "<путь>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-info.ps1" -TemplatePath "<путь>"
|
||||||
```
|
```
|
||||||
|
|
||||||
Или по имени обработки/макета:
|
Или по имени обработки/макета:
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/mxl-info/scripts/mxl-info.ps1 -ProcessorName "<Имя>" -TemplateName "<Макет>" [-SrcDir "<каталог>"]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-info.ps1" -ProcessorName "<Имя>" -TemplateName "<Макет>" [-SrcDir "<каталог>"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Дополнительные флаги:
|
Дополнительные флаги:
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/mxl-validate/scripts/mxl-validate.ps1 -TemplatePath "Catalogs/Номенклатура/Templates/Макет"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-validate.ps1" -TemplatePath "Catalogs/Номенклатура/Templates/Макет"
|
||||||
powershell.exe -NoProfile -File .claude/skills/mxl-validate/scripts/mxl-validate.ps1 -TemplatePath "src/МояОбработка/Templates/ПечатнаяФорма"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-validate.ps1" -TemplatePath "src/МояОбработка/Templates/ПечатнаяФорма"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ allowed-tools:
|
|||||||
| `OutputDir` | Корень выгрузки конфигурации (где `Configuration.xml`, `Roles/` и т.д.) |
|
| `OutputDir` | Корень выгрузки конфигурации (где `Configuration.xml`, `Roles/` и т.д.) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/role-compile/scripts/role-compile.ps1 -JsonPath "<json>" -OutputDir "<ConfigDir>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/role-compile.ps1" -JsonPath "<json>" -OutputDir "<ConfigDir>"
|
||||||
```
|
```
|
||||||
|
|
||||||
Создаёт `{OutputDir}/Roles/Имя.xml` и `{OutputDir}/Roles/Имя/Ext/Rights.xml`. Регистрирует `<Role>` в `Configuration.xml`.
|
Создаёт `{OutputDir}/Roles/Имя.xml` и `{OutputDir}/Roles/Имя/Ext/Rights.xml`. Регистрирует `<Role>` в `Configuration.xml`.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ allowed-tools:
|
|||||||
## Запуск скрипта
|
## Запуск скрипта
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/role-info/scripts/role-info.ps1 -RightsPath <path> -OutFile <output.txt>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/role-info.ps1" -RightsPath <path> -OutFile <output.txt>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры
|
### Параметры
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/role-validate/scripts/role-validate.ps1 -RightsPath "Roles/МояРоль"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/role-validate.ps1" -RightsPath "Roles/МояРоль"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ allowed-tools:
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Из файла
|
# Из файла
|
||||||
powershell.exe -NoProfile -File .claude/skills/skd-compile/scripts/skd-compile.ps1 -DefinitionFile "<json>" -OutputPath "<Template.xml>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-compile.ps1" -DefinitionFile "<json>" -OutputPath "<Template.xml>"
|
||||||
|
|
||||||
# Из строки (без промежуточного файла)
|
# Из строки (без промежуточного файла)
|
||||||
powershell.exe -NoProfile -File .claude/skills/skd-compile/scripts/skd-compile.ps1 -Value '<json-string>' -OutputPath "<Template.xml>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-compile.ps1" -Value '<json-string>' -OutputPath "<Template.xml>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## JSON DSL — краткий справочник
|
## JSON DSL — краткий справочник
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ allowed-tools:
|
|||||||
| `NoSelection` | (опц.) Не добавлять поле в selection варианта |
|
| `NoSelection` | (опц.) Не добавлять поле в selection варианта |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/skd-edit/scripts/skd-edit.ps1 -TemplatePath "<path>" -Operation <op> -Value "<value>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-edit.ps1" -TemplatePath "<path>" -Operation <op> -Value "<value>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Пакетный режим (batch)
|
## Пакетный режим (batch)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ allowed-tools:
|
|||||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/skd-info/scripts/skd-info.ps1 -TemplatePath "<путь>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -TemplatePath "<путь>"
|
||||||
```
|
```
|
||||||
|
|
||||||
С указанием режима:
|
С указанием режима:
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/skd-validate/scripts/skd-validate.ps1 -TemplatePath "src/МойОтчёт/Templates/ОсновнаяСхема"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-validate.ps1" -TemplatePath "src/МойОтчёт/Templates/ОсновнаяСхема"
|
||||||
powershell.exe -NoProfile -File .claude/skills/skd-validate/scripts/skd-validate.ps1 -TemplatePath "Catalogs/Номенклатура/Templates/СКД/Ext/Template.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-validate.ps1" -TemplatePath "Catalogs/Номенклатура/Templates/СКД/Ext/Template.xml"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ allowed-tools:
|
|||||||
| `NoValidate` | Пропустить авто-валидацию |
|
| `NoValidate` | Пропустить авто-валидацию |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File '.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1' -Value '<json>' -OutputDir '<ConfigDir>'
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/subsystem-compile.ps1" -Value '<json>' -OutputDir '<ConfigDir>'
|
||||||
```
|
```
|
||||||
|
|
||||||
## JSON-определение
|
## JSON-определение
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ allowed-tools:
|
|||||||
| `NoValidate` | Пропустить авто-валидацию |
|
| `NoValidate` | Пропустить авто-валидацию |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File '.claude/skills/subsystem-edit/scripts/subsystem-edit.ps1' -SubsystemPath '<path>' -Operation add-content -Value 'Catalog.Товары'
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/subsystem-edit.ps1" -SubsystemPath '<path>' -Operation add-content -Value 'Catalog.Товары'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Операции
|
## Операции
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ allowed-tools:
|
|||||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/subsystem-info/scripts/subsystem-info.ps1 -SubsystemPath "<путь>"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/subsystem-info.ps1" -SubsystemPath "<путь>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Пять режимов
|
## Пять режимов
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File ".claude/skills/subsystem-validate/scripts/subsystem-validate.ps1" -SubsystemPath "Subsystems/Продажи"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/subsystem-validate.ps1" -SubsystemPath "Subsystems/Продажи"
|
||||||
powershell.exe -NoProfile -File ".claude/skills/subsystem-validate/scripts/subsystem-validate.ps1" -SubsystemPath "Subsystems/Продажи.xml"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/subsystem-validate.ps1" -SubsystemPath "Subsystems/Продажи.xml"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/template-add/scripts/add-template.ps1 -ObjectName "<ObjectName>" -TemplateName "<TemplateName>" -TemplateType "<TemplateType>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"] [-SetMainSKD]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/add-template.ps1" -ObjectName "<ObjectName>" -TemplateName "<TemplateName>" -TemplateType "<TemplateType>" [-Synonym "<Synonym>"] [-SrcDir "<SrcDir>"] [-SetMainSKD]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Пример
|
## Пример
|
||||||
@@ -41,7 +41,7 @@ powershell.exe -NoProfile -File .claude/skills/template-add/scripts/add-template
|
|||||||
Добавить основную СКД к отчёту в расширении:
|
Добавить основную СКД к отчёту в расширении:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/template-add/scripts/add-template.ps1 -ObjectName "ОтчётПродажи" -TemplateName "ОсновнаяСхемаКомпоновкиДанных" -TemplateType "DataCompositionSchema" -SrcDir "src/cfe/МоёРасширение/Reports"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/add-template.ps1" -ObjectName "ОтчётПродажи" -TemplateName "ОсновнаяСхемаКомпоновкиДанных" -TemplateType "DataCompositionSchema" -SrcDir "src/cfe/МоёРасширение/Reports"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Маппинг типов
|
## Маппинг типов
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# template-add v1.4 — Add template to 1C object
|
# template-add v1.5 — Add template to 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -20,6 +20,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
# --- Маппинг типов ---
|
# --- Маппинг типов ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# add-template v1.4 — Add template to 1C object
|
# add-template v1.5 — Add template to 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/template-remove/scripts/remove-template.ps1 -ObjectName "<ObjectName>" -TemplateName "<TemplateName>" [-SrcDir "<SrcDir>"]
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/remove-template.ps1" -ObjectName "<ObjectName>" -TemplateName "<TemplateName>" [-SrcDir "<SrcDir>"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Что удаляется
|
## Что удаляется
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# template-remove v1.1 — Remove template from 1C object
|
# template-remove v1.2 — Remove template from 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -12,6 +12,8 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
# --- Проверки ---
|
# --- Проверки ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# remove-template v1.0 — Remove template from 1C object
|
# remove-template v1.1 — Remove template from 1C object
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-info/scripts/web-info.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-info.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -55,8 +55,8 @@ Module: C:/Program Files/1cv8/8.3.24.1691/bin/wsap24.dll
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Статус по умолчанию
|
# Статус по умолчанию
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-info/scripts/web-info.ps1
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-info.ps1"
|
||||||
|
|
||||||
# Указать путь к Apache
|
# Указать путь к Apache
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-info/scripts/web-info.ps1 -ApachePath "C:\tools\apache24"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-info.ps1" -ApachePath "C:\tools\apache24"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-publish/scripts/web-publish.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-publish.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -88,14 +88,14 @@ powershell.exe -NoProfile -File .claude/skills/web-publish/scripts/web-publish.p
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Файловая база
|
# Файловая база
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-publish/scripts/web-publish.ps1 -InfoBasePath "C:\Bases\MyDB" -UserName "Admin"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-publish.ps1" -InfoBasePath "C:\Bases\MyDB" -UserName "Admin"
|
||||||
|
|
||||||
# С явным именем публикации и портом
|
# С явным именем публикации и портом
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-publish/scripts/web-publish.ps1 -InfoBasePath "C:\Bases\MyDB" -AppName "mydb" -Port 9090
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-publish.ps1" -InfoBasePath "C:\Bases\MyDB" -AppName "mydb" -Port 9090
|
||||||
|
|
||||||
# Серверная база
|
# Серверная база
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-publish/scripts/web-publish.ps1 -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-publish.ps1" -InfoBaseServer "srv01" -InfoBaseRef "MyDB" -UserName "Admin" -Password "secret"
|
||||||
|
|
||||||
# Ручной режим (только инструкция)
|
# Ручной режим (только инструкция)
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-publish/scripts/web-publish.ps1 -InfoBasePath "C:\Bases\MyDB" -Manual
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-publish.ps1" -InfoBasePath "C:\Bases\MyDB" -Manual
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-stop/scripts/web-stop.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-stop.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -45,8 +45,8 @@ powershell.exe -NoProfile -File .claude/skills/web-stop/scripts/web-stop.ps1 <п
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Остановить Apache
|
# Остановить Apache
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-stop/scripts/web-stop.ps1
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-stop.ps1"
|
||||||
|
|
||||||
# С указанием пути
|
# С указанием пути
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-stop/scripts/web-stop.ps1 -ApachePath "C:\tools\apache24"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-stop.ps1" -ApachePath "C:\tools\apache24"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Automates user interactions with 1C:Enterprise web client via Playwright — nav
|
|||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
RUN=".claude/skills/web-test/scripts/run.mjs"
|
RUN="${CLAUDE_SKILL_DIR}/scripts/run.mjs"
|
||||||
|
|
||||||
# One-shot: opens browser → runs script → closes browser → exits
|
# One-shot: opens browser → runs script → closes browser → exits
|
||||||
node $RUN run http://localhost:8081/bpdemo test-scenario.js
|
node $RUN run http://localhost:8081/bpdemo test-scenario.js
|
||||||
@@ -35,7 +35,7 @@ SCRIPT
|
|||||||
## Setup (first time)
|
## Setup (first time)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd .claude/skills/web-test/scripts && npm install
|
cd "${CLAUDE_SKILL_DIR}/scripts" && npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
Requires Node.js 18+. `npm install` downloads Playwright and Chromium.
|
Requires Node.js 18+. `npm install` downloads Playwright and Chromium.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ allowed-tools:
|
|||||||
## Команда
|
## Команда
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-unpublish/scripts/web-unpublish.ps1 <параметры>
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-unpublish.ps1" <параметры>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Параметры скрипта
|
### Параметры скрипта
|
||||||
@@ -52,11 +52,11 @@ powershell.exe -NoProfile -File .claude/skills/web-unpublish/scripts/web-unpubli
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Удалить одну публикацию
|
# Удалить одну публикацию
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-unpublish/scripts/web-unpublish.ps1 -AppName "bpdemo"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-unpublish.ps1" -AppName "bpdemo"
|
||||||
|
|
||||||
# Удалить все публикации
|
# Удалить все публикации
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-unpublish/scripts/web-unpublish.ps1 -All
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-unpublish.ps1" -All
|
||||||
|
|
||||||
# С указанием пути
|
# С указанием пути
|
||||||
powershell.exe -NoProfile -File .claude/skills/web-unpublish/scripts/web-unpublish.ps1 -AppName "mydb" -ApachePath "C:\tools\apache24"
|
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/web-unpublish.ps1" -AppName "mydb" -ApachePath "C:\tools\apache24"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# 1C Skills for {{PLATFORM_LABEL}} ({{RUNTIME_LABEL}})
|
||||||
|
|
||||||
|
Автоматическая сборка из [main]({{MAIN_REPO_URL}}) — навыки 1С:Предприятие 8.3 для AI-агента **{{PLATFORM_LABEL}}** с рантаймом **{{RUNTIME_LABEL}}**.
|
||||||
|
|
||||||
|
> Эта ветка генерируется CI на каждый push в main. **Не редактируйте напрямую** — все правки идут в [main]({{MAIN_REPO_URL}}).
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
|
||||||
|
1. Скачайте ZIP этой ветки: **Code → Download ZIP** (или `git archive`).
|
||||||
|
2. Распакуйте в корень своего проекта — должна появиться папка `{{PLATFORM_DIR}}/`.
|
||||||
|
3. Запустите {{PLATFORM_LABEL}} из этого проекта — навыки станут доступны.
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- **Windows** с PowerShell 5.1+ (входит в Windows) — для PowerShell-сборки.
|
||||||
|
- **Python 3.10+** — для Python-сборки. Зависимости: `lxml>=4.9.0`, `psutil>=5.9.0` (для DOM- и web-навыков).
|
||||||
|
- **1С:Предприятие 8.3** — для сборки/разборки EPF/ERF и работы с базами.
|
||||||
|
- **Node.js 18+** — для `/web-test`.
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
Полные гайды, спецификации и описание навыков — в [main]({{MAIN_REPO_URL}}).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Source: {{MAIN_REPO_URL}}
|
||||||
|
Build commit: `{{COMMIT_SHA}}`
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
||||||
|
"name": "{{PLUGIN_NAME}}",
|
||||||
|
"description": "[Python] Навыки для разработки на 1С:Предприятие 8.3 — абстракции над XML-форматами и CLI конфигуратора, плюс глаза и руки для тестирования через веб-клиент. Linux/Mac или когда PowerShell недоступен.",
|
||||||
|
"author": {
|
||||||
|
"name": "Nikolay Shirokov"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"repository": "https://github.com/Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"1c",
|
||||||
|
"1c-dev",
|
||||||
|
"cf",
|
||||||
|
"cfe",
|
||||||
|
"epf",
|
||||||
|
"erf",
|
||||||
|
"metadata",
|
||||||
|
"configuration",
|
||||||
|
"extension",
|
||||||
|
"form",
|
||||||
|
"report",
|
||||||
|
"skd",
|
||||||
|
"data-processor",
|
||||||
|
"mxl",
|
||||||
|
"web-client",
|
||||||
|
"testing",
|
||||||
|
"test-automation"
|
||||||
|
],
|
||||||
|
"skills": "./.claude/skills/"
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "{{PLUGIN_NAME}}",
|
||||||
|
"version": "{{VERSION}}",
|
||||||
|
"description": "[{{RUNTIME_LABEL}}] Навыки для разработки на 1С:Предприятие 8.3 — абстракции над XML-форматами и CLI конфигуратора, плюс глаза и руки для тестирования через веб-клиент.",
|
||||||
|
"author": {
|
||||||
|
"name": "Nikolay Shirokov"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"repository": "https://github.com/Nikolay-Shirokov/cc-1c-skills",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"1c",
|
||||||
|
"1c-dev",
|
||||||
|
"cf",
|
||||||
|
"cfe",
|
||||||
|
"epf",
|
||||||
|
"erf",
|
||||||
|
"metadata",
|
||||||
|
"configuration",
|
||||||
|
"extension",
|
||||||
|
"form",
|
||||||
|
"report",
|
||||||
|
"skd",
|
||||||
|
"data-processor",
|
||||||
|
"mxl",
|
||||||
|
"web-client",
|
||||||
|
"testing",
|
||||||
|
"test-automation"
|
||||||
|
],
|
||||||
|
"skills": "./.codex/skills/",
|
||||||
|
"interface": {
|
||||||
|
"displayName": "1C Skills ({{RUNTIME_LABEL}})",
|
||||||
|
"shortDescription": "{{SHORT_DESCRIPTION}}",
|
||||||
|
"category": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
name: Build port branches
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- '.claude/skills/**'
|
||||||
|
- 'scripts/switch.py'
|
||||||
|
- '.github/templates/README.port.md.tmpl'
|
||||||
|
- '.github/templates/codex-plugin.json.tmpl'
|
||||||
|
- '.github/templates/claude-plugin.json.tmpl'
|
||||||
|
- '.github/workflows/build-ports.yml'
|
||||||
|
- 'LICENSE'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: claude-code
|
||||||
|
runtime: python
|
||||||
|
branch: port-claude-code-py
|
||||||
|
label: Claude Code
|
||||||
|
target_dir: .claude/skills
|
||||||
|
- platform: cursor
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-cursor
|
||||||
|
label: Cursor
|
||||||
|
target_dir: .cursor/skills
|
||||||
|
- platform: cursor
|
||||||
|
runtime: python
|
||||||
|
branch: port-cursor-py
|
||||||
|
label: Cursor
|
||||||
|
target_dir: .cursor/skills
|
||||||
|
- platform: codex
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-codex
|
||||||
|
label: Codex
|
||||||
|
target_dir: .codex/skills
|
||||||
|
- platform: codex
|
||||||
|
runtime: python
|
||||||
|
branch: port-codex-py
|
||||||
|
label: Codex
|
||||||
|
target_dir: .codex/skills
|
||||||
|
- platform: copilot
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-copilot
|
||||||
|
label: GitHub Copilot
|
||||||
|
target_dir: .github/skills
|
||||||
|
- platform: copilot
|
||||||
|
runtime: python
|
||||||
|
branch: port-copilot-py
|
||||||
|
label: GitHub Copilot
|
||||||
|
target_dir: .github/skills
|
||||||
|
- platform: augment
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-augment
|
||||||
|
label: Augment
|
||||||
|
target_dir: .augment/skills
|
||||||
|
- platform: augment
|
||||||
|
runtime: python
|
||||||
|
branch: port-augment-py
|
||||||
|
label: Augment
|
||||||
|
target_dir: .augment/skills
|
||||||
|
- platform: cline
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-cline
|
||||||
|
label: Cline
|
||||||
|
target_dir: .cline/skills
|
||||||
|
- platform: cline
|
||||||
|
runtime: python
|
||||||
|
branch: port-cline-py
|
||||||
|
label: Cline
|
||||||
|
target_dir: .cline/skills
|
||||||
|
- platform: kilo
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-kilo
|
||||||
|
label: Kilo Code
|
||||||
|
target_dir: .kilocode/skills
|
||||||
|
- platform: kilo
|
||||||
|
runtime: python
|
||||||
|
branch: port-kilo-py
|
||||||
|
label: Kilo Code
|
||||||
|
target_dir: .kilocode/skills
|
||||||
|
- platform: kiro
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-kiro
|
||||||
|
label: Kiro
|
||||||
|
target_dir: .kiro/skills
|
||||||
|
- platform: kiro
|
||||||
|
runtime: python
|
||||||
|
branch: port-kiro-py
|
||||||
|
label: Kiro
|
||||||
|
target_dir: .kiro/skills
|
||||||
|
- platform: gemini
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-gemini
|
||||||
|
label: Gemini CLI
|
||||||
|
target_dir: .gemini/skills
|
||||||
|
- platform: gemini
|
||||||
|
runtime: python
|
||||||
|
branch: port-gemini-py
|
||||||
|
label: Gemini CLI
|
||||||
|
target_dir: .gemini/skills
|
||||||
|
- platform: opencode
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-opencode
|
||||||
|
label: OpenCode
|
||||||
|
target_dir: .opencode/skills
|
||||||
|
- platform: opencode
|
||||||
|
runtime: python
|
||||||
|
branch: port-opencode-py
|
||||||
|
label: OpenCode
|
||||||
|
target_dir: .opencode/skills
|
||||||
|
- platform: roo
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-roo
|
||||||
|
label: Roo Code
|
||||||
|
target_dir: .roo/skills
|
||||||
|
- platform: roo
|
||||||
|
runtime: python
|
||||||
|
branch: port-roo-py
|
||||||
|
label: Roo Code
|
||||||
|
target_dir: .roo/skills
|
||||||
|
- platform: windsurf
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-windsurf
|
||||||
|
label: Windsurf
|
||||||
|
target_dir: .windsurf/skills
|
||||||
|
- platform: windsurf
|
||||||
|
runtime: python
|
||||||
|
branch: port-windsurf-py
|
||||||
|
label: Windsurf
|
||||||
|
target_dir: .windsurf/skills
|
||||||
|
- platform: agents
|
||||||
|
runtime: powershell
|
||||||
|
branch: port-agents
|
||||||
|
label: Agent Skills
|
||||||
|
target_dir: .agents/skills
|
||||||
|
- platform: agents
|
||||||
|
runtime: python
|
||||||
|
branch: port-agents-py
|
||||||
|
label: Agent Skills
|
||||||
|
target_dir: .agents/skills
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout main
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Build skills tree for ${{ matrix.platform }} (${{ matrix.runtime }})
|
||||||
|
run: |
|
||||||
|
python scripts/switch.py "${{ matrix.platform }}" \
|
||||||
|
--project-dir build \
|
||||||
|
--runtime "${{ matrix.runtime }}"
|
||||||
|
|
||||||
|
- name: Render port README
|
||||||
|
env:
|
||||||
|
PLATFORM_LABEL: ${{ matrix.label }}
|
||||||
|
PLATFORM_DIR: ${{ matrix.target_dir }}
|
||||||
|
RUNTIME_LABEL: ${{ matrix.runtime == 'powershell' && 'PowerShell' || 'Python' }}
|
||||||
|
COMMIT_SHA: ${{ github.sha }}
|
||||||
|
MAIN_REPO_URL: https://github.com/${{ github.repository }}
|
||||||
|
run: |
|
||||||
|
sed \
|
||||||
|
-e "s|{{PLATFORM_LABEL}}|${PLATFORM_LABEL}|g" \
|
||||||
|
-e "s|{{PLATFORM_DIR}}|${PLATFORM_DIR}|g" \
|
||||||
|
-e "s|{{RUNTIME_LABEL}}|${RUNTIME_LABEL}|g" \
|
||||||
|
-e "s|{{COMMIT_SHA}}|${COMMIT_SHA}|g" \
|
||||||
|
-e "s|{{MAIN_REPO_URL}}|${MAIN_REPO_URL}|g" \
|
||||||
|
.github/templates/README.port.md.tmpl > build/README.md
|
||||||
|
|
||||||
|
- name: Render Codex plugin manifest
|
||||||
|
if: matrix.platform == 'codex'
|
||||||
|
env:
|
||||||
|
PLUGIN_NAME: ${{ matrix.runtime == 'python' && '1c-skills-py' || '1c-skills' }}
|
||||||
|
RUNTIME_LABEL: ${{ matrix.runtime == 'powershell' && 'PowerShell' || 'Python' }}
|
||||||
|
SHORT_DESCRIPTION: ${{ matrix.runtime == 'python' && 'Python runtime (Linux/Mac/Windows)' || 'PowerShell runtime (Windows-first)' }}
|
||||||
|
COMMIT_SHA: ${{ github.sha }}
|
||||||
|
run: |
|
||||||
|
VERSION="$(date -u +%Y.%-m.%-d)+${COMMIT_SHA::7}"
|
||||||
|
mkdir -p build/.codex-plugin
|
||||||
|
sed \
|
||||||
|
-e "s|{{PLUGIN_NAME}}|${PLUGIN_NAME}|g" \
|
||||||
|
-e "s|{{VERSION}}|${VERSION}|g" \
|
||||||
|
-e "s|{{RUNTIME_LABEL}}|${RUNTIME_LABEL}|g" \
|
||||||
|
-e "s|{{SHORT_DESCRIPTION}}|${SHORT_DESCRIPTION}|g" \
|
||||||
|
.github/templates/codex-plugin.json.tmpl > build/.codex-plugin/plugin.json
|
||||||
|
|
||||||
|
- name: Render Claude plugin manifest (Py variant)
|
||||||
|
if: matrix.platform == 'claude-code' && matrix.runtime == 'python'
|
||||||
|
env:
|
||||||
|
PLUGIN_NAME: 1c-skills-py
|
||||||
|
run: |
|
||||||
|
mkdir -p build/.claude-plugin
|
||||||
|
sed -e "s|{{PLUGIN_NAME}}|${PLUGIN_NAME}|g" \
|
||||||
|
.github/templates/claude-plugin.json.tmpl > build/.claude-plugin/plugin.json
|
||||||
|
|
||||||
|
- name: Copy LICENSE
|
||||||
|
run: cp LICENSE build/LICENSE
|
||||||
|
|
||||||
|
- name: Force-push orphan snapshot to ${{ matrix.branch }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
git init -q -b master
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add -A
|
||||||
|
git commit -q -m "Auto-build: ${{ matrix.platform }} (${{ matrix.runtime }}) from ${GITHUB_SHA::7}"
|
||||||
|
git push --force \
|
||||||
|
"https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" \
|
||||||
|
"master:${{ matrix.branch }}"
|
||||||
+1
-1
@@ -37,7 +37,7 @@ __pycache__/
|
|||||||
*.mp4
|
*.mp4
|
||||||
|
|
||||||
# Навыки, скопированные для других AI-платформ (генерируются scripts/switch.py)
|
# Навыки, скопированные для других AI-платформ (генерируются scripts/switch.py)
|
||||||
.agents/
|
.agents/skills/
|
||||||
.augment/
|
.augment/
|
||||||
.cline/
|
.cline/
|
||||||
.codex/
|
.codex/
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
# 1C Skills for Claude Code
|
# 1C Skills for Claude Code
|
||||||
|
|
||||||
> **Work in progress** — навыки находятся в стадии тестирования, отладки и оптимизации.
|
> **Проект живой, активно развивается** — добавляются новые возможности, отлавливаются и исправляются баги, производится оптимизация. Следите за обновлениями.
|
||||||
|
|
||||||
Набор навыков для AI-агентов (в первую очередь для [Claude Code](https://docs.anthropic.com/en/docs/claude-code/skills)), помогающий охватить полный цикл разработки на платформе 1С:Предприятие 8.3 — от создания конфигураций, расширений, внешних обработок и отчётов до загрузки изменений в информационную базу, обновления, запуска, публикации на веб-сервере (портативная версия Apache), тестирования через веб-клиент и записи видеоинструкций.
|
Набор навыков для AI-агентов (в первую очередь для [Claude Code](https://docs.anthropic.com/en/docs/claude-code/skills)), помогающий охватить полный цикл разработки на платформе 1С:Предприятие 8.3 — от создания конфигураций, расширений, внешних обработок и отчётов до загрузки изменений в информационную базу, обновления, запуска, публикации на веб-сервере (портативная версия Apache), тестирования через веб-клиент и записи видеоинструкций.
|
||||||
|
|
||||||
Навыки дают модели готовые абстракции над XML-форматами и CLI конфигуратора — чтобы работать с сутью задачи, а не с деталями реализации. А веб-тестирование даёт ей глаза и руки для взаимодействия с интерфейсом 1С.
|
Навыки дают модели готовые абстракции над XML-форматами и CLI конфигуратора — чтобы работать с сутью задачи, а не с деталями реализации. А веб-тестирование даёт ей глаза и руки для взаимодействия с интерфейсом 1С.
|
||||||
|
|
||||||
|
## Версии навыков для разных платформ
|
||||||
|
|
||||||
|
> **PS** — версия со скриптами на PowerShell (стандартная, для Windows). **Py** — версия со скриптами на Python (если PowerShell не подходит). Можно начать с **PS** — это основной вариант.
|
||||||
|
|
||||||
|
**Claude Code** [PS](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/main) · [Py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-claude-code-py) — **Cursor** [PS](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-cursor) · [Py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-cursor-py) — **Codex** [PS](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-codex) · [Py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-codex-py) — [Другие платформы →](#поддерживаемые-платформы)
|
||||||
|
|
||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
Скопируйте каталог `.claude/skills/` из этого репозитория в корень вашего проекта. Навыки станут доступны при запуске Claude Code из этого каталога.
|
Скопируйте каталог `.claude/skills/` из этого репозитория в корень вашего проекта. Навыки станут доступны при запуске Claude Code из этого каталога.
|
||||||
@@ -16,6 +22,21 @@
|
|||||||
└── ...
|
└── ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Или установите как плагин Claude Code:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin marketplace add https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
/plugin install 1c-skills@cc-1c-skills # PowerShell (Windows)
|
||||||
|
/plugin install 1c-skills-py@cc-1c-skills # Python (Linux/Mac или если PS недоступен)
|
||||||
|
```
|
||||||
|
|
||||||
|
Или установите как плагин OpenAI Codex:
|
||||||
|
|
||||||
|
```
|
||||||
|
codex plugin marketplace add Nikolay-Shirokov/cc-1c-skills
|
||||||
|
codex /plugins # выберите 1c-skills (PowerShell) или 1c-skills-py (Python) и нажмите Install
|
||||||
|
```
|
||||||
|
|
||||||
Или используйте скрипт установки:
|
Или используйте скрипт установки:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -61,9 +82,37 @@ python tools/cc-1c-skills/scripts/switch.py
|
|||||||
- **1С:Предприятие 8.3** — для сборки/разборки EPF/ERF (навыки генерации XML работают без платформы)
|
- **1С:Предприятие 8.3** — для сборки/разборки EPF/ERF (навыки генерации XML работают без платформы)
|
||||||
- **Node.js 18+** — для `/web-test` (тестирование через браузер)
|
- **Node.js 18+** — для `/web-test` (тестирование через браузер)
|
||||||
|
|
||||||
|
<a id="поддерживаемые-платформы"></a>
|
||||||
### Другие AI-платформы
|
### Другие AI-платформы
|
||||||
|
|
||||||
Навыки построены на открытом стандарте [Agent Skills](https://agentskills.io/specification) и совместимы с любой платформой, поддерживающей этот формат. Скрипт `switch.py` копирует навыки в нужный каталог с перезаписью путей:
|
Навыки построены на открытом стандарте [Agent Skills](https://agentskills.io/specification) и совместимы с любой платформой, поддерживающей этот формат. Самый быстрый путь — скачать готовую сборку под нужную платформу из ветки ниже (**Code → Download ZIP**) и распаковать в корень своего проекта.
|
||||||
|
|
||||||
|
#### Поддерживаемые платформы
|
||||||
|
|
||||||
|
| Платформа | Целевой каталог | PowerShell | Python |
|
||||||
|
|-----------|----------------|------------|--------|
|
||||||
|
| Claude Code | `.claude/skills/` | [main](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/main) | [port-claude-code-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-claude-code-py) |
|
||||||
|
| Cursor | `.cursor/skills/` | [port-cursor](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-cursor) | [port-cursor-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-cursor-py) |
|
||||||
|
| OpenAI Codex | `.codex/skills/` | [port-codex](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-codex) | [port-codex-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-codex-py) |
|
||||||
|
| GitHub Copilot | `.github/skills/` | [port-copilot](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-copilot) | [port-copilot-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-copilot-py) |
|
||||||
|
| Augment | `.augment/skills/` | [port-augment](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-augment) | [port-augment-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-augment-py) |
|
||||||
|
| Cline | `.cline/skills/` | [port-cline](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-cline) | [port-cline-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-cline-py) |
|
||||||
|
| Kilo Code | `.kilocode/skills/` | [port-kilo](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-kilo) | [port-kilo-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-kilo-py) |
|
||||||
|
| Kiro | `.kiro/skills/` | [port-kiro](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-kiro) | [port-kiro-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-kiro-py) |
|
||||||
|
| Gemini CLI | `.gemini/skills/` | [port-gemini](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-gemini) | [port-gemini-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-gemini-py) |
|
||||||
|
| OpenCode | `.opencode/skills/` | [port-opencode](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-opencode) | [port-opencode-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-opencode-py) |
|
||||||
|
| Roo Code | `.roo/skills/` | [port-roo](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-roo) | [port-roo-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-roo-py) |
|
||||||
|
| Windsurf | `.windsurf/skills/` | [port-windsurf](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-windsurf) | [port-windsurf-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-windsurf-py) |
|
||||||
|
| Agent Skills | `.agents/skills/` | [port-agents](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-agents) | [port-agents-py](https://github.com/Nikolay-Shirokov/cc-1c-skills/tree/port-agents-py) |
|
||||||
|
|
||||||
|
Готовые ветки `port-*` пересобираются автоматически на каждое изменение в навыках. Если нужна свежая сборка прямо сейчас — соберите [локально через `switch.py`](#альтернативный-способ--собрать-локально-через-switchpy).
|
||||||
|
|
||||||
|
Некоторые платформы (Augment, Cline, VS Code/Copilot) также сканируют `.claude/skills/` как fallback — для них достаточно `main`.
|
||||||
|
|
||||||
|
<a id="альтернативный-способ--собрать-локально-через-switchpy"></a>
|
||||||
|
#### Альтернативный способ — собрать локально через `switch.py`
|
||||||
|
|
||||||
|
Если нужна свежая сборка под свою платформу (или платформа ещё не в матрице port-веток):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/switch.py # интерактивный режим
|
python scripts/switch.py # интерактивный режим
|
||||||
@@ -80,26 +129,6 @@ python scripts/switch.py --undo cursor # удалить
|
|||||||
|
|
||||||
> ⚠ **Известные ограничения `--link`:** Node.js резолвит `__dirname` через junction к реальному пути источника, а не к каталогу проекта. Это может приводить к тому, что навыки с Node.js-скриптами (например, `/web-test`) будут записывать файлы в каталог репозитория навыков вместо каталога проекта. При возникновении проблем переключитесь на копирование (без `--link`).
|
> ⚠ **Известные ограничения `--link`:** Node.js резолвит `__dirname` через junction к реальному пути источника, а не к каталогу проекта. Это может приводить к тому, что навыки с Node.js-скриптами (например, `/web-test`) будут записывать файлы в каталог репозитория навыков вместо каталога проекта. При возникновении проблем переключитесь на копирование (без `--link`).
|
||||||
|
|
||||||
Поддерживаемые платформы:
|
|
||||||
|
|
||||||
| Платформа | Целевой каталог | `switch.py <platform>` |
|
|
||||||
|-----------|----------------|------------------------|
|
|
||||||
| Claude Code | `.claude/skills/` | `claude-code` |
|
|
||||||
| Augment | `.augment/skills/` | `augment` |
|
|
||||||
| Cline | `.cline/skills/` | `cline` |
|
|
||||||
| Cursor | `.cursor/skills/` | `cursor` |
|
|
||||||
| GitHub Copilot | `.github/skills/` | `copilot` |
|
|
||||||
| Kilo Code | `.kilocode/skills/` | `kilo` |
|
|
||||||
| Kiro | `.kiro/skills/` | `kiro` |
|
|
||||||
| OpenAI Codex | `.codex/skills/` | `codex` |
|
|
||||||
| Gemini CLI | `.gemini/skills/` | `gemini` |
|
|
||||||
| OpenCode | `.opencode/skills/` | `opencode` |
|
|
||||||
| Roo Code | `.roo/skills/` | `roo` |
|
|
||||||
| Windsurf | `.windsurf/skills/` | `windsurf` |
|
|
||||||
| Agent Skills | `.agents/skills/` | `agents` |
|
|
||||||
|
|
||||||
Некоторые платформы (Augment, Cline, VS Code/Copilot) также сканируют `.claude/skills/` как fallback — для них копирование необязательно, но `switch.py` даёт явный контроль над путями.
|
|
||||||
|
|
||||||
Автоактивация — основной режим: просто опишите задачу своими словами, ассистент сам подберёт нужный навык по `description` в SKILL.md. Слеш-команды (например `/epf-init`) — для точного контроля, когда нужно вызвать конкретный навык.
|
Автоактивация — основной режим: просто опишите задачу своими словами, ассистент сам подберёт нужный навык по `description` в SKILL.md. Слеш-команды (например `/epf-init`) — для точного контроля, когда нужно вызвать конкретный навык.
|
||||||
|
|
||||||
### Переключение рантайма (PowerShell ↔ Python)
|
### Переключение рантайма (PowerShell ↔ Python)
|
||||||
|
|||||||
@@ -1199,6 +1199,7 @@ ChildItems
|
|||||||
| Popup | ~40% |
|
| Popup | ~40% |
|
||||||
| PictureDecoration | ~40% |
|
| PictureDecoration | ~40% |
|
||||||
| PictureField | ~15% |
|
| PictureField | ~15% |
|
||||||
|
| RadioButtonField | ~8.5% |
|
||||||
| CalendarField | ~5% |
|
| CalendarField | ~5% |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -1207,7 +1208,6 @@ ChildItems
|
|||||||
|
|
||||||
Следующие элементы управления существуют в платформе, но не использованы в БП 3.0:
|
Следующие элементы управления существуют в платформе, но не использованы в БП 3.0:
|
||||||
|
|
||||||
- `RadioButtonField`
|
|
||||||
- `TrackBarField`
|
- `TrackBarField`
|
||||||
- `ProgressBarField`
|
- `ProgressBarField`
|
||||||
- `TextDocumentField`
|
- `TextDocumentField`
|
||||||
|
|||||||
+58
-1
@@ -199,6 +199,35 @@
|
|||||||
| `path` | string | DataPath |
|
| `path` | string | DataPath |
|
||||||
| `titleLocation` | string | Расположение заголовка |
|
| `titleLocation` | string | Расположение заголовка |
|
||||||
|
|
||||||
|
#### radio — RadioButtonField
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"radio": "СпособКурса",
|
||||||
|
"path": "Объект.СпособУстановкиКурса",
|
||||||
|
"radioButtonType": "Auto",
|
||||||
|
"choiceList": [
|
||||||
|
{ "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": "автоматически" },
|
||||||
|
{ "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": { "ru": "вручную", "en": "manual" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Свойство | Тип | Описание |
|
||||||
|
|----------|-----|----------|
|
||||||
|
| `path` | string | DataPath |
|
||||||
|
| `radioButtonType` | string | `Auto` (по умолчанию), `RadioButtons`, `Tumbler` |
|
||||||
|
| `columnsCount` | int | Число колонок раскладки |
|
||||||
|
| `titleLocation` | string | Расположение заголовка (компилятор подставляет `None`, если не задан) |
|
||||||
|
| `choiceList` | array | Варианты выбора: массив `{ value, presentation }` |
|
||||||
|
|
||||||
|
`choiceList[*]`:
|
||||||
|
|
||||||
|
| Свойство | Тип | Описание |
|
||||||
|
|----------|-----|----------|
|
||||||
|
| `value` | string/number/bool | Значение варианта. Для перечисления — `"Enum.ИмяТипа.EnumValue.ИмяЗначения"` (xsi:type автоматически: `xr:DesignTimeRef` / `xs:string` / `xs:decimal` / `xs:boolean`) |
|
||||||
|
| `presentation` | string или object | Текст рядом с переключателем. Строка → ru; объект `{ru, en, ...}` → мультиязык. Если не задано — выводится из имени значения |
|
||||||
|
|
||||||
#### label — LabelDecoration
|
#### label — LabelDecoration
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -239,7 +268,7 @@
|
|||||||
| Свойство | Тип | Описание |
|
| Свойство | Тип | Описание |
|
||||||
|----------|-----|----------|
|
|----------|-----|----------|
|
||||||
| `path` | string | DataPath |
|
| `path` | string | DataPath |
|
||||||
| `columns` | array | Колонки (элементы input/check/labelField/picField) |
|
| `columns` | array | Колонки (элементы input/check/labelField/picField, либо `columnGroup` для группировки) |
|
||||||
| `representation` | string | `List`, `Tree`, `HierarchicalList` |
|
| `representation` | string | `List`, `Tree`, `HierarchicalList` |
|
||||||
| `changeRowSet` | bool | Разрешить добавление/удаление строк |
|
| `changeRowSet` | bool | Разрешить добавление/удаление строк |
|
||||||
| `changeRowOrder` | bool | Разрешить перемещение строк |
|
| `changeRowOrder` | bool | Разрешить перемещение строк |
|
||||||
@@ -249,6 +278,33 @@
|
|||||||
| `commandBarLocation` | string | `None`, `Top`, `Bottom`, `Auto` |
|
| `commandBarLocation` | string | `None`, `Top`, `Bottom`, `Auto` |
|
||||||
| `searchStringLocation` | string | `None`, `Top`, `Bottom`, `CommandBar`, `Auto` |
|
| `searchStringLocation` | string | `None`, `Top`, `Bottom`, `CommandBar`, `Auto` |
|
||||||
|
|
||||||
|
#### columnGroup — ColumnGroup
|
||||||
|
|
||||||
|
Группа колонок таблицы. Используется только внутри `columns` таблицы. Допускается вложение `columnGroup` в `columnGroup`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "table": "Список", "path": "Список", "columns": [
|
||||||
|
{ "columnGroup": "horizontal", "name": "ГруппаДата", "title": "Срок", "children": [
|
||||||
|
{ "input": "ДатаНачала", "path": "Список.ДатаНачала" },
|
||||||
|
{ "input": "ДатаОкончания", "path": "Список.ДатаОкончания" }
|
||||||
|
]},
|
||||||
|
{ "columnGroup": "inCell", "name": "ГруппаИсполнитель", "showInHeader": true, "children": [
|
||||||
|
{ "input": "Исполнитель", "path": "Список.Исполнитель" }
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Свойство | Тип | Описание |
|
||||||
|
|----------|-----|----------|
|
||||||
|
| `columnGroup` | string | Ориентация: `horizontal`, `vertical`, `inCell` (склейка колонок в одной ячейке шапки) |
|
||||||
|
| `name` | string | Имя элемента (рекомендуется задавать явно) |
|
||||||
|
| `title` | string/object | Заголовок группы |
|
||||||
|
| `showTitle` | bool | Показывать заголовок |
|
||||||
|
| `showInHeader` | bool | Показывать в шапке таблицы |
|
||||||
|
| `width` | int | Ширина |
|
||||||
|
| `horizontalStretch` | bool | Растягивание |
|
||||||
|
| `children` | array | Колонки внутри группы |
|
||||||
|
|
||||||
#### pages / page — Pages / Page
|
#### pages / page — Pages / Page
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -437,6 +493,7 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs
|
|||||||
| UsualGroup | ExtendedTooltip |
|
| UsualGroup | ExtendedTooltip |
|
||||||
| InputField | ContextMenu, ExtendedTooltip |
|
| InputField | ContextMenu, ExtendedTooltip |
|
||||||
| CheckBoxField | ContextMenu, ExtendedTooltip |
|
| CheckBoxField | ContextMenu, ExtendedTooltip |
|
||||||
|
| RadioButtonField | ContextMenu, ExtendedTooltip |
|
||||||
| LabelDecoration | ContextMenu, ExtendedTooltip |
|
| LabelDecoration | ContextMenu, ExtendedTooltip |
|
||||||
| LabelField | ContextMenu, ExtendedTooltip |
|
| LabelField | ContextMenu, ExtendedTooltip |
|
||||||
| PictureDecoration | ContextMenu, ExtendedTooltip |
|
| PictureDecoration | ContextMenu, ExtendedTooltip |
|
||||||
|
|||||||
+98
-20
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# switch.py v1.3 — Переключение навыков 1С между AI-платформами и рантаймами
|
# switch.py v1.6 — Переключение навыков 1С между AI-платформами и рантаймами
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
"""
|
"""
|
||||||
Копирует (или создаёт ссылки на) навыки из .claude/skills/ на другие AI-платформы
|
Копирует (или создаёт ссылки на) навыки из .claude/skills/ на другие AI-платформы
|
||||||
@@ -43,6 +43,11 @@ PLATFORMS = {
|
|||||||
|
|
||||||
SOURCE_PREFIX = '.claude/skills'
|
SOURCE_PREFIX = '.claude/skills'
|
||||||
|
|
||||||
|
# ${CLAUDE_SKILL_DIR}/../<other>/<rest> — cross-skill reference (more specific, match first)
|
||||||
|
RX_SKILL_DIR_CROSS = re.compile(r'\$\{CLAUDE_SKILL_DIR\}/\.\./([a-z][a-z0-9-]+)/')
|
||||||
|
# ${CLAUDE_SKILL_DIR}/<rest> — same-skill reference
|
||||||
|
SKILL_DIR_VAR = '${CLAUDE_SKILL_DIR}/'
|
||||||
|
|
||||||
# Рекомендуемые записи для .gitignore целевого проекта
|
# Рекомендуемые записи для .gitignore целевого проекта
|
||||||
GITIGNORE_RECOMMENDATIONS = [
|
GITIGNORE_RECOMMENDATIONS = [
|
||||||
'.v8-project.json',
|
'.v8-project.json',
|
||||||
@@ -56,8 +61,36 @@ GITIGNORE_RECOMMENDATIONS = [
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Runtime regex patterns (from switch-to-python.py / switch-to-powershell.py)
|
# Runtime regex patterns (from switch-to-python.py / switch-to-powershell.py)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
RX_PS = re.compile(r'powershell\.exe\s+(?:-NoProfile\s+)?-File\s+(.+?)\.ps1')
|
# Capture optional surrounding quote (group 'q') and bare path (group 'path').
|
||||||
RX_PY = re.compile(r"python\s+('?[\w./_-]+?)\.py")
|
# Path matches non-whitespace non-quote chars to support ${CLAUDE_SKILL_DIR}/...
|
||||||
|
# Optional -ExecutionPolicy <value> between -NoProfile and -File (used for codex target).
|
||||||
|
RX_PS = re.compile(
|
||||||
|
r'powershell\.exe\s+'
|
||||||
|
r'(?:-NoProfile\s+)?'
|
||||||
|
r'(?:-ExecutionPolicy\s+\S+\s+)?'
|
||||||
|
r'-File\s+(?P<q>["\']?)(?P<path>[^"\s]+?)\.ps1(?P=q)?'
|
||||||
|
)
|
||||||
|
RX_PY = re.compile(r"python\s+(?P<q>[\"']?)(?P<path>[^\"\s]+?)\.py(?P=q)?")
|
||||||
|
|
||||||
|
# Платформы, требующие -ExecutionPolicy Bypass (Codex запускает powershell как
|
||||||
|
# login-shell, профиль грузится и упирается в Restricted policy).
|
||||||
|
PS_BYPASS_PLATFORMS = {'codex'}
|
||||||
|
|
||||||
|
|
||||||
|
def emit_ps_invocation(path, quote, platform):
|
||||||
|
"""Build canonical powershell.exe invocation for a target platform."""
|
||||||
|
ep = ' -ExecutionPolicy Bypass' if platform in PS_BYPASS_PLATFORMS else ''
|
||||||
|
return f"powershell.exe -NoProfile{ep} -File {quote}{path}.ps1{quote}"
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_ps_invocation(content, platform):
|
||||||
|
"""Re-emit existing powershell.exe ...ps1 invocations with platform flags.
|
||||||
|
|
||||||
|
Idempotent: matches both with and without -ExecutionPolicy in source.
|
||||||
|
"""
|
||||||
|
def repl(m):
|
||||||
|
return emit_ps_invocation(m.group('path'), m.group('q'), platform)
|
||||||
|
return RX_PS.sub(repl, content)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -148,23 +181,40 @@ def classify_skill_runtime(skill_dir):
|
|||||||
return 'ps' if has_ps else ('py' if has_py else 'none')
|
return 'ps' if has_ps else ('py' if has_py else 'none')
|
||||||
|
|
||||||
|
|
||||||
|
def expand_skill_path(path, skill_name, source_prefix=SOURCE_PREFIX):
|
||||||
|
"""Expand ${CLAUDE_SKILL_DIR} placeholder to a path relative to source_prefix.
|
||||||
|
|
||||||
|
${CLAUDE_SKILL_DIR}/<rest> -> <source_prefix>/<skill_name>/<rest>
|
||||||
|
${CLAUDE_SKILL_DIR}/../<other>/<rest> -> <source_prefix>/<other>/<rest>
|
||||||
|
Anything else returned as-is (legacy literal path).
|
||||||
|
"""
|
||||||
|
var = '${CLAUDE_SKILL_DIR}/'
|
||||||
|
if not path.startswith(var):
|
||||||
|
return path
|
||||||
|
rest = path[len(var):]
|
||||||
|
if rest.startswith('../'):
|
||||||
|
return f'{source_prefix}/{rest[3:]}'
|
||||||
|
return f'{source_prefix}/{skill_name}/{rest}'
|
||||||
|
|
||||||
|
|
||||||
def check_missing_files(skill_dir, target_runtime, root):
|
def check_missing_files(skill_dir, target_runtime, root):
|
||||||
"""Check if target runtime script files exist for a skill.
|
"""Check if target runtime script files exist for a skill.
|
||||||
|
|
||||||
Returns list of missing file paths (relative to root).
|
Returns list of missing file paths (relative to root).
|
||||||
"""
|
"""
|
||||||
missing = []
|
missing = []
|
||||||
|
skill_name = os.path.basename(os.path.normpath(skill_dir))
|
||||||
for md_path in collect_md_files(skill_dir):
|
for md_path in collect_md_files(skill_dir):
|
||||||
with open(md_path, 'r', encoding='utf-8') as f:
|
with open(md_path, 'r', encoding='utf-8') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
if target_runtime == 'python':
|
if target_runtime == 'python':
|
||||||
for m in RX_PS.findall(content):
|
for m in RX_PS.finditer(content):
|
||||||
py_path = m.lstrip("'") + '.py'
|
py_path = expand_skill_path(m.group('path'), skill_name) + '.py'
|
||||||
if not os.path.isfile(os.path.join(root, py_path)):
|
if not os.path.isfile(os.path.join(root, py_path)):
|
||||||
missing.append(py_path)
|
missing.append(py_path)
|
||||||
elif target_runtime == 'powershell':
|
elif target_runtime == 'powershell':
|
||||||
for m in RX_PY.findall(content):
|
for m in RX_PY.finditer(content):
|
||||||
ps1_path = m.lstrip("'") + '.ps1'
|
ps1_path = expand_skill_path(m.group('path'), skill_name) + '.ps1'
|
||||||
if not os.path.isfile(os.path.join(root, ps1_path)):
|
if not os.path.isfile(os.path.join(root, ps1_path)):
|
||||||
missing.append(ps1_path)
|
missing.append(ps1_path)
|
||||||
return missing
|
return missing
|
||||||
@@ -179,17 +229,39 @@ def is_different_dir(dir1, dir2):
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Transformations
|
# Transformations
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
def rewrite_paths(content, source_prefix, target_prefix):
|
def rewrite_paths(content, platform, target_prefix, skill_name):
|
||||||
"""Replace .claude/skills/ path prefix with target platform prefix."""
|
"""Resolve ${CLAUDE_SKILL_DIR} placeholders to target platform prefix.
|
||||||
return content.replace(source_prefix + '/', target_prefix + '/')
|
|
||||||
|
For claude-code target, leave ${CLAUDE_SKILL_DIR} untouched — Claude Code
|
||||||
|
substitutes it natively at invocation time. For all other targets,
|
||||||
|
expand to a literal path:
|
||||||
|
${CLAUDE_SKILL_DIR}/<rest> → <target_prefix>/<skill_name>/<rest>
|
||||||
|
${CLAUDE_SKILL_DIR}/../<other>/<rest> → <target_prefix>/<other>/<rest>
|
||||||
|
"""
|
||||||
|
if platform == 'claude-code':
|
||||||
|
return content
|
||||||
|
# Cross-skill first (more specific pattern)
|
||||||
|
content = RX_SKILL_DIR_CROSS.sub(f'{target_prefix}/\\1/', content)
|
||||||
|
# Then same-skill
|
||||||
|
content = content.replace(SKILL_DIR_VAR, f'{target_prefix}/{skill_name}/')
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
def switch_runtime_content(content, target_runtime):
|
def switch_runtime_content(content, target_runtime, platform='claude-code'):
|
||||||
"""Switch runtime invocations in .md content. Returns (new_content, switched)."""
|
"""Switch runtime invocations in .md content. Returns (new_content, switched).
|
||||||
|
|
||||||
|
Platform controls flags on emitted powershell invocations
|
||||||
|
(codex requires -ExecutionPolicy Bypass).
|
||||||
|
"""
|
||||||
if target_runtime == 'python':
|
if target_runtime == 'python':
|
||||||
new = RX_PS.sub(r'python \1.py', content)
|
def to_py(m):
|
||||||
|
q = m.group('q')
|
||||||
|
return f"python {q}{m.group('path')}.py{q}"
|
||||||
|
new = RX_PS.sub(to_py, content)
|
||||||
elif target_runtime == 'powershell':
|
elif target_runtime == 'powershell':
|
||||||
new = RX_PY.sub(r'powershell.exe -NoProfile -File \1.ps1', content)
|
def to_ps(m):
|
||||||
|
return emit_ps_invocation(m.group('path'), m.group('q'), platform)
|
||||||
|
new = RX_PY.sub(to_ps, content)
|
||||||
else:
|
else:
|
||||||
return content, False
|
return content, False
|
||||||
return new, new != content
|
return new, new != content
|
||||||
@@ -305,15 +377,19 @@ def cmd_install(platform, runtime, project_dir):
|
|||||||
with open(md_path, 'r', encoding='utf-8') as f:
|
with open(md_path, 'r', encoding='utf-8') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
new_content = rewrite_paths(content, SOURCE_PREFIX, target_prefix)
|
new_content = rewrite_paths(content, platform, target_prefix, skill_name)
|
||||||
|
|
||||||
# Apply runtime switch (skip for single-runtime skills
|
# Apply runtime switch (skip for single-runtime skills
|
||||||
# where target runtime is not available)
|
# where target runtime is not available)
|
||||||
if not skip_runtime:
|
if not skip_runtime:
|
||||||
if runtime == 'python':
|
if runtime == 'python':
|
||||||
new_content, _ = switch_runtime_content(new_content, 'python')
|
new_content, _ = switch_runtime_content(new_content, 'python', platform)
|
||||||
elif runtime == 'powershell':
|
elif runtime == 'powershell':
|
||||||
new_content, _ = switch_runtime_content(new_content, 'powershell')
|
new_content, _ = switch_runtime_content(new_content, 'powershell', platform)
|
||||||
|
|
||||||
|
# Normalize any remaining powershell invocations with platform flags
|
||||||
|
# (covers skip_runtime=True case where source PS commands stayed)
|
||||||
|
new_content = normalize_ps_invocation(new_content, platform)
|
||||||
|
|
||||||
if new_content != content:
|
if new_content != content:
|
||||||
with open(md_path, 'w', encoding='utf-8') as f:
|
with open(md_path, 'w', encoding='utf-8') as f:
|
||||||
@@ -448,14 +524,14 @@ def cmd_switch_runtime(runtime, project_dir):
|
|||||||
# Skip runtime conversion for single-runtime skills where
|
# Skip runtime conversion for single-runtime skills where
|
||||||
# target files don't exist (e.g. img-grid has only .py)
|
# target files don't exist (e.g. img-grid has only .py)
|
||||||
cur_rt = classify_skill_runtime(skill_path)
|
cur_rt = classify_skill_runtime(skill_path)
|
||||||
missing = check_missing_files(skill_path, runtime, repo_root())
|
missing = check_missing_files(skill_path, runtime, project_dir)
|
||||||
skip_runtime = bool(missing) and (
|
skip_runtime = bool(missing) and (
|
||||||
(runtime == 'python' and cur_rt in ('ps', 'none'))
|
(runtime == 'python' and cur_rt in ('ps', 'none'))
|
||||||
or (runtime == 'powershell' and cur_rt in ('py', 'none'))
|
or (runtime == 'powershell' and cur_rt in ('py', 'none'))
|
||||||
)
|
)
|
||||||
|
|
||||||
info, warnings = collect_runtime_messages(
|
info, warnings = collect_runtime_messages(
|
||||||
skill_name, skill_path, runtime, repo_root())
|
skill_name, skill_path, runtime, project_dir)
|
||||||
all_info.extend(info)
|
all_info.extend(info)
|
||||||
all_warnings.extend(warnings)
|
all_warnings.extend(warnings)
|
||||||
|
|
||||||
@@ -466,7 +542,9 @@ def cmd_switch_runtime(runtime, project_dir):
|
|||||||
with open(md_path, 'r', encoding='utf-8') as f:
|
with open(md_path, 'r', encoding='utf-8') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
new_content, changed = switch_runtime_content(content, runtime)
|
new_content, _ = switch_runtime_content(content, runtime, platform_name)
|
||||||
|
new_content = normalize_ps_invocation(new_content, platform_name)
|
||||||
|
changed = new_content != content
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
with open(md_path, 'w', encoding='utf-8') as f:
|
with open(md_path, 'w', encoding='utf-8') as f:
|
||||||
|
|||||||
+15
-1
@@ -14,10 +14,23 @@ node tests/skills/runner.mjs --verbose # подробн
|
|||||||
node tests/skills/runner.mjs --update-snapshots # обновить эталоны
|
node tests/skills/runner.mjs --update-snapshots # обновить эталоны
|
||||||
node tests/skills/runner.mjs --runtime python # запуск на PY-версиях
|
node tests/skills/runner.mjs --runtime python # запуск на PY-версиях
|
||||||
node tests/skills/runner.mjs --json report.json # JSON-отчёт
|
node tests/skills/runner.mjs --json report.json # JSON-отчёт
|
||||||
|
node tests/skills/runner.mjs --concurrency 4 # ограничить параллельность
|
||||||
|
node tests/skills/runner.mjs --with-validation # + платформенная валидация
|
||||||
|
node tests/skills/runner.mjs --help # полный список опций
|
||||||
```
|
```
|
||||||
|
|
||||||
Exit code: 0 = все прошли, 1 = есть падения.
|
Exit code: 0 = все прошли, 1 = есть падения.
|
||||||
|
|
||||||
|
### Платформенная верификация снапшотов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node tests/skills/verify-snapshots.mjs --skill form-compile # один навык
|
||||||
|
node tests/skills/verify-snapshots.mjs --case table # один кейс
|
||||||
|
node tests/skills/verify-snapshots.mjs --help # полный список опций
|
||||||
|
```
|
||||||
|
|
||||||
|
Перепрогоняет навык из DSL кейса и грузит результат в 1С — отлавливает случаи, когда снапшоты обновили, но платформа уже не принимает выход.
|
||||||
|
|
||||||
## Что делать при падении
|
## Что делать при падении
|
||||||
|
|
||||||
1. Смотри **case id** в выводе — это путь к файлу кейса (можно перезапустить: `node runner.mjs <case-id>`)
|
1. Смотри **case id** в выводе — это путь к файлу кейса (можно перезапустить: `node runner.mjs <case-id>`)
|
||||||
@@ -194,7 +207,8 @@ node tests/skills/runner.mjs cases/meta-compile/enum --update-snapshots # од
|
|||||||
|
|
||||||
```
|
```
|
||||||
tests/skills/
|
tests/skills/
|
||||||
runner.mjs # тест-раннер
|
runner.mjs # тест-раннер (snapshot-сравнение)
|
||||||
|
verify-snapshots.mjs # платформенная верификация снапшотов
|
||||||
README.md # этот файл
|
README.md # этот файл
|
||||||
.cache/ # кэш фикстур (в .gitignore)
|
.cache/ # кэш фикстур (в .gitignore)
|
||||||
cases/
|
cases/
|
||||||
|
|||||||
@@ -1,16 +1,63 @@
|
|||||||
{
|
{
|
||||||
"name": "Установить начальную страницу (template + left/right + visibility/roles)",
|
"name": "Установить начальную страницу (template + left/right + visibility/roles)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "Catalog", "name": "Товары" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/Catalogs/Товары", "-FormName": "ФормаСписка", "-Purpose": "List" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/Catalogs/Товары", "-FormName": "ФормаЭлемента", "-Purpose": "Object" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "Catalog", "name": "Контрагенты" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/Catalogs/Контрагенты", "-FormName": "ФормаСписка", "-Purpose": "List" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/Catalogs/Контрагенты", "-FormName": "ФормаОбъекта", "-Purpose": "Object" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": { "type": "DataProcessor", "name": "Поиск" },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "form-add/scripts/form-add",
|
||||||
|
"args": { "-ObjectPath": "{workDir}/DataProcessors/Поиск", "-FormName": "ФормаПоиска", "-Purpose": "Object" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "role-compile/scripts/role-compile",
|
||||||
|
"input": { "name": "Оператор", "objects": [] },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "role-compile/scripts/role-compile",
|
||||||
|
"input": { "name": "ПолныеПрава", "objects": [] },
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
}
|
||||||
|
],
|
||||||
"input": [
|
"input": [
|
||||||
{
|
{
|
||||||
"operation": "set-home-page",
|
"operation": "set-home-page",
|
||||||
"value": {
|
"value": {
|
||||||
"template": "TwoColumnsVariableWidth",
|
"template": "TwoColumnsVariableWidth",
|
||||||
"left": [
|
"left": [
|
||||||
"CommonForm.НачалоРаботы",
|
"Catalog.Товары.Form.ФормаСписка",
|
||||||
{ "form": "CommonForm.СписокЗадач", "height": 100, "visibility": false },
|
{ "form": "Catalog.Товары.Form.ФормаЭлемента", "height": 100, "visibility": false },
|
||||||
{ "form": "Справочник.Контрагенты.ФормаСписка", "height": 50 },
|
{ "form": "Справочник.Контрагенты.ФормаСписка", "height": 50 },
|
||||||
{
|
{
|
||||||
"form": "CommonForm.РабочийСтолОператора",
|
"form": "Catalog.Контрагенты.Form.ФормаОбъекта",
|
||||||
"visibility": false,
|
"visibility": false,
|
||||||
"roles": { "Role.Оператор": true, "ПолныеПрава": false }
|
"roles": { "Role.Оператор": true, "ПолныеПрава": false }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,7 @@
|
|||||||
<Characteristics/>
|
<Characteristics/>
|
||||||
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
||||||
<EditType>InDialog</EditType>
|
<EditType>InDialog</EditType>
|
||||||
<QuickChoice>true</QuickChoice>
|
<QuickChoice>false</QuickChoice>
|
||||||
<ChoiceMode>BothWays</ChoiceMode>
|
<ChoiceMode>BothWays</ChoiceMode>
|
||||||
<InputByString>
|
<InputByString>
|
||||||
<xr:Field>Catalog.Товары.StandardAttribute.Description</xr:Field>
|
<xr:Field>Catalog.Товары.StandardAttribute.Description</xr:Field>
|
||||||
|
|||||||
@@ -287,7 +287,7 @@
|
|||||||
<Characteristics/>
|
<Characteristics/>
|
||||||
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
||||||
<EditType>InDialog</EditType>
|
<EditType>InDialog</EditType>
|
||||||
<QuickChoice>true</QuickChoice>
|
<QuickChoice>false</QuickChoice>
|
||||||
<ChoiceMode>BothWays</ChoiceMode>
|
<ChoiceMode>BothWays</ChoiceMode>
|
||||||
<InputByString>
|
<InputByString>
|
||||||
<xr:Field>Catalog.Остающийся.StandardAttribute.Description</xr:Field>
|
<xr:Field>Catalog.Остающийся.StandardAttribute.Description</xr:Field>
|
||||||
|
|||||||
@@ -287,7 +287,7 @@
|
|||||||
<Characteristics/>
|
<Characteristics/>
|
||||||
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
||||||
<EditType>InDialog</EditType>
|
<EditType>InDialog</EditType>
|
||||||
<QuickChoice>true</QuickChoice>
|
<QuickChoice>false</QuickChoice>
|
||||||
<ChoiceMode>BothWays</ChoiceMode>
|
<ChoiceMode>BothWays</ChoiceMode>
|
||||||
<InputByString>
|
<InputByString>
|
||||||
<xr:Field>Catalog.Удаляемый.StandardAttribute.Description</xr:Field>
|
<xr:Field>Catalog.Удаляемый.StandardAttribute.Description</xr:Field>
|
||||||
|
|||||||
@@ -0,0 +1,330 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Catalog uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="CatalogObject.Контрагенты" category="Object">
|
||||||
|
<xr:TypeId>UUID-002</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-003</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="CatalogRef.Контрагенты" category="Ref">
|
||||||
|
<xr:TypeId>UUID-004</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-005</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="CatalogSelection.Контрагенты" category="Selection">
|
||||||
|
<xr:TypeId>UUID-006</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-007</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="CatalogList.Контрагенты" category="List">
|
||||||
|
<xr:TypeId>UUID-008</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-009</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="CatalogManager.Контрагенты" category="Manager">
|
||||||
|
<xr:TypeId>UUID-010</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-011</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>Контрагенты</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Контрагенты</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment />
|
||||||
|
<Hierarchical>false</Hierarchical>
|
||||||
|
<HierarchyType>HierarchyFoldersAndItems</HierarchyType>
|
||||||
|
<LimitLevelCount>false</LimitLevelCount>
|
||||||
|
<LevelCount>2</LevelCount>
|
||||||
|
<FoldersOnTop>true</FoldersOnTop>
|
||||||
|
<UseStandardCommands>true</UseStandardCommands>
|
||||||
|
<Owners />
|
||||||
|
<SubordinationUse>ToItems</SubordinationUse>
|
||||||
|
<CodeLength>9</CodeLength>
|
||||||
|
<DescriptionLength>25</DescriptionLength>
|
||||||
|
<CodeType>String</CodeType>
|
||||||
|
<CodeAllowedLength>Variable</CodeAllowedLength>
|
||||||
|
<CodeSeries>WholeCatalog</CodeSeries>
|
||||||
|
<CheckUnique>false</CheckUnique>
|
||||||
|
<Autonumbering>true</Autonumbering>
|
||||||
|
<DefaultPresentation>AsDescription</DefaultPresentation>
|
||||||
|
<StandardAttributes>
|
||||||
|
<xr:StandardAttribute name="PredefinedDataName">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="Predefined">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="Ref">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="DeletionMark">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="IsFolder">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="Owner">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="Parent">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="Description">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
<xr:StandardAttribute name="Code">
|
||||||
|
<xr:LinkByType />
|
||||||
|
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||||
|
<xr:MultiLine>false</xr:MultiLine>
|
||||||
|
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||||
|
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||||
|
<xr:MaxValue xsi:nil="true" />
|
||||||
|
<xr:ToolTip />
|
||||||
|
<xr:ExtendedEdit>false</xr:ExtendedEdit>
|
||||||
|
<xr:Format />
|
||||||
|
<xr:ChoiceForm />
|
||||||
|
<xr:QuickChoice>Auto</xr:QuickChoice>
|
||||||
|
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
|
||||||
|
<xr:EditFormat />
|
||||||
|
<xr:PasswordMode>false</xr:PasswordMode>
|
||||||
|
<xr:DataHistory>Use</xr:DataHistory>
|
||||||
|
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||||
|
<xr:MinValue xsi:nil="true" />
|
||||||
|
<xr:Synonym />
|
||||||
|
<xr:Comment />
|
||||||
|
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||||
|
<xr:ChoiceParameterLinks />
|
||||||
|
<xr:FillValue xsi:nil="true" />
|
||||||
|
<xr:Mask />
|
||||||
|
<xr:ChoiceParameters />
|
||||||
|
</xr:StandardAttribute>
|
||||||
|
</StandardAttributes>
|
||||||
|
<Characteristics />
|
||||||
|
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
|
||||||
|
<EditType>InDialog</EditType>
|
||||||
|
<QuickChoice>false</QuickChoice>
|
||||||
|
<ChoiceMode>BothWays</ChoiceMode>
|
||||||
|
<InputByString>
|
||||||
|
<xr:Field>Catalog.Контрагенты.StandardAttribute.Description</xr:Field>
|
||||||
|
<xr:Field>Catalog.Контрагенты.StandardAttribute.Code</xr:Field>
|
||||||
|
</InputByString>
|
||||||
|
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
|
||||||
|
<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>
|
||||||
|
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
|
||||||
|
<DefaultObjectForm>Catalog.Контрагенты.Form.ФормаОбъекта</DefaultObjectForm>
|
||||||
|
<DefaultFolderForm />
|
||||||
|
<DefaultListForm>Catalog.Контрагенты.Form.ФормаСписка</DefaultListForm>
|
||||||
|
<DefaultChoiceForm />
|
||||||
|
<DefaultFolderChoiceForm />
|
||||||
|
<AuxiliaryObjectForm />
|
||||||
|
<AuxiliaryFolderForm />
|
||||||
|
<AuxiliaryListForm />
|
||||||
|
<AuxiliaryChoiceForm />
|
||||||
|
<AuxiliaryFolderChoiceForm />
|
||||||
|
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||||
|
<BasedOn />
|
||||||
|
<DataLockFields />
|
||||||
|
<DataLockControlMode>Automatic</DataLockControlMode>
|
||||||
|
<FullTextSearch>Use</FullTextSearch>
|
||||||
|
<ObjectPresentation />
|
||||||
|
<ExtendedObjectPresentation />
|
||||||
|
<ListPresentation />
|
||||||
|
<ExtendedListPresentation />
|
||||||
|
<Explanation />
|
||||||
|
<CreateOnInput>DontUse</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<DataHistory>DontUse</DataHistory>
|
||||||
|
<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>
|
||||||
|
<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Form>ФормаСписка</Form>
|
||||||
|
<Form>ФормаОбъекта</Form>
|
||||||
|
</ChildObjects>
|
||||||
|
</Catalog>
|
||||||
|
</MetaDataObject>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user