diff --git a/.claude/skills/subsystem-compile/SKILL.md b/.claude/skills/subsystem-compile/SKILL.md
index ce9d4af5..8923a1ff 100644
--- a/.claude/skills/subsystem-compile/SKILL.md
+++ b/.claude/skills/subsystem-compile/SKILL.md
@@ -38,8 +38,7 @@ powershell.exe -NoProfile -File '.claude/skills/subsystem-compile/scripts/subsys
"useOneCommand": false,
"explanation": "Описание раздела",
"picture": "CommonPicture.МояКартинка",
- "content": ["Catalog.Товары", "Document.Заказ"],
- "children": ["ДочерняяА", "ДочерняяБ"]
+ "content": ["Catalog.Товары", "Document.Заказ"]
}
```
diff --git a/tests/skills/cases/subsystem-compile/_skill.json b/tests/skills/cases/subsystem-compile/_skill.json
index 5c9bf7a8..5db9ab8c 100644
--- a/tests/skills/cases/subsystem-compile/_skill.json
+++ b/tests/skills/cases/subsystem-compile/_skill.json
@@ -3,7 +3,8 @@
"setup": "empty-config",
"args": [
{ "flag": "-DefinitionFile", "from": "inputFile" },
- { "flag": "-OutputDir", "from": "workDir" }
+ { "flag": "-OutputDir", "from": "workDir" },
+ { "flag": "-Parent", "from": "workPath", "field": "parent", "optional": true }
],
"snapshot": {
"root": "workDir",
diff --git a/tests/skills/cases/subsystem-compile/nested-parent.json b/tests/skills/cases/subsystem-compile/nested-parent.json
new file mode 100644
index 00000000..d64e2d27
--- /dev/null
+++ b/tests/skills/cases/subsystem-compile/nested-parent.json
@@ -0,0 +1,24 @@
+{
+ "name": "Вложенная подсистема через -Parent (bottom-up flow)",
+ "preRun": [
+ {
+ "script": "subsystem-compile/scripts/subsystem-compile",
+ "input": { "name": "Продажи", "synonym": "Продажи" },
+ "args": { "-DefinitionFile": "{inputFile}", "-OutputDir": "{workDir}" }
+ }
+ ],
+ "params": { "parent": "Subsystems/Продажи.xml" },
+ "input": {
+ "name": "Настройки",
+ "synonym": "Настройки раздела",
+ "explanation": "Настройки подсистемы продаж",
+ "includeInCommandInterface": true
+ },
+ "validatePath": "Subsystems/Продажи/Subsystems/Настройки",
+ "expect": {
+ "files": [
+ "Subsystems/Продажи.xml",
+ "Subsystems/Продажи/Subsystems/Настройки.xml"
+ ]
+ }
+}
diff --git a/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Configuration.xml b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Configuration.xml
new file mode 100644
index 00000000..2e6aa527
--- /dev/null
+++ b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Configuration.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+ UUID-002
+ UUID-003
+
+
+ UUID-004
+ UUID-005
+
+
+ UUID-006
+ UUID-007
+
+
+ UUID-008
+ UUID-009
+
+
+ UUID-010
+ UUID-011
+
+
+ UUID-012
+ UUID-013
+
+
+ UUID-014
+ UUID-015
+
+
+
+ TestConfig
+
+
+ ru
+ TestConfig
+
+
+
+
+ Version8_3_24
+ ManagedApplication
+
+ PlatformApplication
+
+ Russian
+
+
+
+
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Biometrics
+ true
+
+
+ Location
+ false
+
+
+ BackgroundLocation
+ false
+
+
+ BluetoothPrinters
+ false
+
+
+ WiFiPrinters
+ false
+
+
+ Contacts
+ false
+
+
+ Calendars
+ false
+
+
+ PushNotifications
+ false
+
+
+ LocalNotifications
+ false
+
+
+ InAppPurchases
+ false
+
+
+ PersonalComputerFileExchange
+ false
+
+
+ Ads
+ false
+
+
+ NumberDialing
+ false
+
+
+ CallProcessing
+ false
+
+
+ CallLog
+ false
+
+
+ AutoSendSMS
+ false
+
+
+ ReceiveSMS
+ false
+
+
+ SMSLog
+ false
+
+
+ Camera
+ false
+
+
+ Microphone
+ false
+
+
+ MusicLibrary
+ false
+
+
+ PictureAndVideoLibraries
+ false
+
+
+ AudioPlaybackAndVibration
+ false
+
+
+ BackgroundAudioPlaybackAndVibration
+ false
+
+
+ InstallPackages
+ false
+
+
+ OSBackup
+ true
+
+
+ ApplicationUsageStatistics
+ false
+
+
+ BarcodeScanning
+ false
+
+
+ BackgroundAudioRecording
+ false
+
+
+ AllFilesAccess
+ false
+
+
+ Videoconferences
+ false
+
+
+ NFC
+ false
+
+
+ DocumentScanning
+ false
+
+
+ SpeechToText
+ false
+
+
+ Geofences
+ false
+
+
+ IncomingShareRequests
+ false
+
+
+ AllIncomingShareRequestsTypesProcessing
+ false
+
+
+
+
+
+ Normal
+
+
+ Language.Русский
+
+
+
+
+
+ Managed
+ NotAutoFree
+ DontUse
+ DontUse
+ TaxiEnableVersion8_2
+ DontUse
+ Version8_3_24
+
+
+
+ Русский
+ Продажи
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Languages/Русский.xml b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Languages/Русский.xml
new file mode 100644
index 00000000..37c60d78
--- /dev/null
+++ b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Languages/Русский.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Русский
+
+
+ ru
+ Русский
+
+
+
+ ru
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Subsystems/Продажи.xml b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Subsystems/Продажи.xml
new file mode 100644
index 00000000..e2384567
--- /dev/null
+++ b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Subsystems/Продажи.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ Продажи
+
+
+ ru
+ Продажи
+
+
+
+ true
+ true
+ false
+
+
+
+
+
+ Настройки
+
+
+
diff --git a/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Subsystems/Продажи/Subsystems/Настройки.xml b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Subsystems/Продажи/Subsystems/Настройки.xml
new file mode 100644
index 00000000..516eb081
--- /dev/null
+++ b/tests/skills/cases/subsystem-compile/snapshots/nested-parent/Subsystems/Продажи/Subsystems/Настройки.xml
@@ -0,0 +1,27 @@
+
+
+
+
+ Настройки
+
+
+ ru
+ Настройки раздела
+
+
+
+ true
+ true
+ false
+
+
+ ru
+ Настройки подсистемы продаж
+
+
+
+
+
+
+
+
diff --git a/tests/skills/runner.mjs b/tests/skills/runner.mjs
index 18ffec03..cafe95df 100644
--- a/tests/skills/runner.mjs
+++ b/tests/skills/runner.mjs
@@ -223,8 +223,16 @@ function buildArgs(skillConfig, caseData, workDir, inputFilePath, runtime) {
case 'workPath':
// workDir + value from case.params or case (specified in mapping.field)
const wpField = mapping.field || 'objectPath';
- const wpVal = caseData.params?.[wpField] ?? caseData[wpField] ?? '';
- args.push(join(workDir, wpVal));
+ const wpVal = caseData.params?.[wpField] ?? caseData[wpField];
+ if (wpVal === undefined || wpVal === null || wpVal === '') {
+ if (mapping.optional) {
+ args.pop(); // remove the flag we pushed at the top of the loop
+ break;
+ }
+ args.push(join(workDir, ''));
+ } else {
+ args.push(join(workDir, wpVal));
+ }
break;
case 'switch':
// flag already pushed, no value needed — remove the flag and re-push conditionally
diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs
index 87a9313f..9b459a17 100644
--- a/tests/skills/verify-snapshots.mjs
+++ b/tests/skills/verify-snapshots.mjs
@@ -250,8 +250,16 @@ function buildSkillArgs(skillConfig, caseData, workDir, inputFile, runtime) {
break;
case 'workPath': {
const field = mapping.field || 'objectPath';
- const val = caseData.params?.[field] ?? caseData[field] ?? '';
- args.push(join(workDir, val));
+ const val = caseData.params?.[field] ?? caseData[field];
+ if (val === undefined || val === null || val === '') {
+ if (mapping.optional) {
+ args.pop(); // remove flag pushed above
+ break;
+ }
+ args.push(join(workDir, ''));
+ } else {
+ args.push(join(workDir, val));
+ }
break;
}
case 'switch':