bmad-method 6.5.1-next.8 → 6.5.1-next.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -5,15 +5,11 @@ default_selected: true # This module will be selected by default for new install
|
|
|
5
5
|
|
|
6
6
|
# Variables from Core Config inserted:
|
|
7
7
|
## user_name
|
|
8
|
+
## project_name
|
|
8
9
|
## communication_language
|
|
9
10
|
## document_output_language
|
|
10
11
|
## output_folder
|
|
11
12
|
|
|
12
|
-
project_name:
|
|
13
|
-
prompt: "What is your project called?"
|
|
14
|
-
default: "{directory_name}"
|
|
15
|
-
result: "{value}"
|
|
16
|
-
|
|
17
13
|
user_skill_level:
|
|
18
14
|
prompt:
|
|
19
15
|
- "What is your development experience level?"
|
|
@@ -11,6 +11,11 @@ user_name:
|
|
|
11
11
|
default: "BMad"
|
|
12
12
|
result: "{value}"
|
|
13
13
|
|
|
14
|
+
project_name:
|
|
15
|
+
prompt: "What is your project called?"
|
|
16
|
+
default: "{directory_name}"
|
|
17
|
+
result: "{value}"
|
|
18
|
+
|
|
14
19
|
communication_language:
|
|
15
20
|
prompt: "What language should agents use when chatting with you?"
|
|
16
21
|
scope: user
|
|
@@ -903,7 +903,10 @@ class OfficialModules {
|
|
|
903
903
|
try {
|
|
904
904
|
const content = await fs.readFile(moduleConfigPath, 'utf8');
|
|
905
905
|
const moduleConfig = yaml.parse(content);
|
|
906
|
-
|
|
906
|
+
// Only keep plain object parses. A corrupt config.yaml that parses
|
|
907
|
+
// to a scalar or array would crash later code that does `key in cfg`
|
|
908
|
+
// / `Object.keys(cfg)`; treat it the same as a parse error.
|
|
909
|
+
if (moduleConfig && typeof moduleConfig === 'object' && !Array.isArray(moduleConfig)) {
|
|
907
910
|
this._existingConfig[entry.name] = moduleConfig;
|
|
908
911
|
foundAny = true;
|
|
909
912
|
}
|
|
@@ -914,9 +917,58 @@ class OfficialModules {
|
|
|
914
917
|
}
|
|
915
918
|
}
|
|
916
919
|
|
|
920
|
+
if (foundAny) {
|
|
921
|
+
await this._hoistCoreKeysFromLegacyModuleConfigs();
|
|
922
|
+
}
|
|
923
|
+
|
|
917
924
|
return foundAny;
|
|
918
925
|
}
|
|
919
926
|
|
|
927
|
+
/**
|
|
928
|
+
* Migrate prior answers when a key has moved from a non-core module to core
|
|
929
|
+
* (e.g. project_name moving from bmm to core in #2279). Without this, the
|
|
930
|
+
* partition logic in writeCentralConfig drops the value from the bmm bucket
|
|
931
|
+
* (because it's now a core key) without re-homing it under [core], so the
|
|
932
|
+
* user's prior answer silently disappears on the next install/quick-update.
|
|
933
|
+
*/
|
|
934
|
+
async _hoistCoreKeysFromLegacyModuleConfigs() {
|
|
935
|
+
const coreSchemaPath = path.join(getSourcePath(), 'core-skills', 'module.yaml');
|
|
936
|
+
if (!(await fs.pathExists(coreSchemaPath))) return;
|
|
937
|
+
|
|
938
|
+
let coreSchema;
|
|
939
|
+
try {
|
|
940
|
+
coreSchema = yaml.parse(await fs.readFile(coreSchemaPath, 'utf8'));
|
|
941
|
+
} catch {
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (!coreSchema || typeof coreSchema !== 'object') return;
|
|
945
|
+
|
|
946
|
+
const coreKeys = new Set(
|
|
947
|
+
Object.entries(coreSchema)
|
|
948
|
+
.filter(([, v]) => v && typeof v === 'object' && 'prompt' in v)
|
|
949
|
+
.map(([k]) => k),
|
|
950
|
+
);
|
|
951
|
+
if (coreKeys.size === 0) return;
|
|
952
|
+
|
|
953
|
+
// Belt-and-suspenders: loadExistingConfig already filters non-object parses,
|
|
954
|
+
// but anyone calling _hoistCoreKeysFromLegacyModuleConfigs in isolation (or
|
|
955
|
+
// future code paths populating _existingConfig directly) shouldn't be able
|
|
956
|
+
// to crash this with a scalar / array.
|
|
957
|
+
const existingCore = this._existingConfig.core;
|
|
958
|
+
this._existingConfig.core = existingCore && typeof existingCore === 'object' && !Array.isArray(existingCore) ? existingCore : {};
|
|
959
|
+
|
|
960
|
+
for (const [moduleName, cfg] of Object.entries(this._existingConfig)) {
|
|
961
|
+
if (moduleName === 'core' || !cfg || typeof cfg !== 'object' || Array.isArray(cfg)) continue;
|
|
962
|
+
for (const key of Object.keys(cfg)) {
|
|
963
|
+
if (!coreKeys.has(key)) continue;
|
|
964
|
+
if (!(key in this._existingConfig.core)) {
|
|
965
|
+
this._existingConfig.core[key] = cfg[key];
|
|
966
|
+
}
|
|
967
|
+
delete cfg[key];
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
920
972
|
/**
|
|
921
973
|
* Pre-scan module schemas to gather metadata for the configuration gateway prompt.
|
|
922
974
|
* Returns info about which modules have configurable options.
|
package/tools/installer/ui.js
CHANGED
|
@@ -758,6 +758,9 @@ class UI {
|
|
|
758
758
|
const defaultUsername = safeUsername.charAt(0).toUpperCase() + safeUsername.slice(1);
|
|
759
759
|
configCollector.collectedConfig.core = {
|
|
760
760
|
user_name: defaultUsername,
|
|
761
|
+
// {directory_name} default per src/core-skills/module.yaml — matches what the
|
|
762
|
+
// interactive flow resolves via buildQuestion()'s {directory_name} placeholder.
|
|
763
|
+
project_name: path.basename(directory),
|
|
761
764
|
communication_language: 'English',
|
|
762
765
|
document_output_language: 'English',
|
|
763
766
|
output_folder: '_bmad-output',
|