wizz-method 2.20.0 → 2.20.1

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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "wizz-method",
4
- "version": "2.20.0",
4
+ "version": "2.20.1",
5
5
  "description": "Wizz Method: método de agência orientado por IA em PT-BR",
6
6
  "keywords": [
7
7
  "agile",
@@ -87,7 +87,10 @@ class Installer {
87
87
  await prompts.log.warn(`Warning: Could not check for legacy WIZZ entries: ${error.message}`);
88
88
  }
89
89
 
90
+ this._runtimeConfigValues = undefined;
90
91
  if (existingInstall.installed) {
92
+ // Antes de mexer em `_wizz/`: o sprint aberto e o layout que os hooks gravaram.
93
+ this._runtimeConfigValues = await moduleConfigWriter.captureRuntimeValues(realWizzDirCandidate);
91
94
  await this._removeDeselectedModules(existingInstall, config, paths, originalConfig._preserveModules || []);
92
95
  updateState = await this._prepareUpdateState(paths, config, existingInstall, officialModules);
93
96
  await this._removeDeselectedIdes(existingInstall, config, paths);
@@ -1412,7 +1415,10 @@ class Installer {
1412
1415
  * @param {Object} moduleConfigs - Collected configuration values
1413
1416
  */
1414
1417
  async generateModuleConfigs(wizzDir, moduleConfigs) {
1415
- return moduleConfigWriter.generateModuleConfigs(wizzDir, moduleConfigs, { trackFile: (p) => this.installedFiles.add(p) });
1418
+ return moduleConfigWriter.generateModuleConfigs(wizzDir, moduleConfigs, {
1419
+ trackFile: (p) => this.installedFiles.add(p),
1420
+ runtimeValues: this._runtimeConfigValues,
1421
+ });
1416
1422
  }
1417
1423
 
1418
1424
  /**
@@ -10,14 +10,71 @@ const path = require('node:path');
10
10
  const fs = require('../fs-native');
11
11
  const { getProjectRoot } = require('../project-root');
12
12
 
13
+ // Chaves que os hooks gravam no config.yaml em tempo de uso, não o installer:
14
+ // `active_feature` (wizz-feature.js definir: o sprint aberto) e `layout`
15
+ // (wizz-arrumar.js layout --gravar). O installer lê as respostas do
16
+ // config.toml, onde elas não existem ou ficaram vazias, e regenerava o yaml do
17
+ // zero: o update da 2.20.0 zerou o sprint aberto e o layout de todo projeto.
18
+ const RUNTIME_KEYS = ['active_feature', 'layout'];
19
+
20
+ const isEmpty = (value) => value === undefined || value === null || value === '';
21
+
22
+ const NON_MODULE_DIRS = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom', 'hooks']);
23
+
24
+ /** Os valores de tempo de uso de um config.yaml (vazio se ausente ou ilegível). */
25
+ async function readRuntimeValues(configPath, yaml) {
26
+ let previous;
27
+ try {
28
+ previous = yaml.parse(await fs.readFile(configPath, 'utf8'));
29
+ } catch {
30
+ return {};
31
+ }
32
+ if (!previous || typeof previous !== 'object' || Array.isArray(previous)) return {};
33
+ const kept = {};
34
+ for (const key of RUNTIME_KEYS) if (!isEmpty(previous[key])) kept[key] = previous[key];
35
+ return kept;
36
+ }
37
+
38
+ /**
39
+ * Lê os valores de tempo de uso de todo módulo instalado. O update chama ANTES
40
+ * de mexer em `_wizz/`: depois o yaml antigo já foi apagado junto com a pasta
41
+ * do módulo.
42
+ * @param {string} wizzDir
43
+ * @returns {Promise<Record<string, Record<string, unknown>>>} módulo → chave → valor
44
+ */
45
+ async function captureRuntimeValues(wizzDir) {
46
+ const yaml = require('yaml');
47
+ const out = {};
48
+ let entries = [];
49
+ try {
50
+ entries = await fs.readdir(wizzDir, { withFileTypes: true });
51
+ } catch {
52
+ return out;
53
+ }
54
+ for (const entry of entries) {
55
+ if (!entry.isDirectory() || NON_MODULE_DIRS.has(entry.name)) continue;
56
+ const values = await readRuntimeValues(path.join(wizzDir, entry.name, 'config.yaml'), yaml);
57
+ if (Object.keys(values).length > 0) out[entry.name] = values;
58
+ }
59
+ return out;
60
+ }
61
+
62
+ /** Resposta nova vence; o valor de tempo de uso só preenche o que ela deixaria vazio. */
63
+ function withRuntimeValues(answered, previous = {}) {
64
+ const config = { ...answered };
65
+ for (const [key, value] of Object.entries(previous)) if (isEmpty(config[key])) config[key] = value;
66
+ return config;
67
+ }
68
+
13
69
  /**
14
70
  * Generate clean config.yaml files for each installed module.
15
71
  * @param {string} wizzDir - WIZZ installation directory
16
72
  * @param {Object} moduleConfigs - Collected configuration values
17
73
  * @param {Object} deps - Injected dependencies
18
74
  * @param {(filePath: string) => void} deps.trackFile - Records a written file as installed
75
+ * @param {Record<string, Record<string, unknown>>} [deps.runtimeValues] - captureRuntimeValues() de antes do update
19
76
  */
20
- async function generateModuleConfigs(wizzDir, moduleConfigs, { trackFile }) {
77
+ async function generateModuleConfigs(wizzDir, moduleConfigs, { trackFile, runtimeValues }) {
21
78
  const yaml = require('yaml');
22
79
 
23
80
  // Extract core config values to share with other modules
@@ -28,18 +85,18 @@ async function generateModuleConfigs(wizzDir, moduleConfigs, { trackFile }) {
28
85
  // 'hooks' (RT-C1, tools/hooks/* copied here by Installer#_installHooks) is
29
86
  // infra, not a module — without this exclusion this scanner treated it as
30
87
  // one and wrote a spurious _wizz/hooks/config.yaml.
31
- const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom', 'hooks']);
32
- const installedModules = entries.filter((entry) => entry.isDirectory() && !nonModuleDirs.has(entry.name)).map((entry) => entry.name);
88
+ const installedModules = entries.filter((entry) => entry.isDirectory() && !NON_MODULE_DIRS.has(entry.name)).map((entry) => entry.name);
33
89
 
34
90
  // Generate config.yaml for each installed module
35
91
  for (const moduleName of installedModules) {
36
92
  const modulePath = path.join(wizzDir, moduleName);
37
93
 
38
- // Get module-specific config or use empty object if none
39
- const config = moduleConfigs[moduleName] || {};
40
-
41
94
  if (await fs.pathExists(modulePath)) {
42
95
  const configPath = path.join(modulePath, 'config.yaml');
96
+ // Module-specific answers, plus what the hooks wrote since the last install
97
+ const answered = moduleConfigs[moduleName] || {};
98
+ const previous = runtimeValues?.[moduleName] ?? (await readRuntimeValues(configPath, yaml));
99
+ const config = withRuntimeValues(answered, previous);
43
100
 
44
101
  // Create header
45
102
  const packageJson = require(path.join(getProjectRoot(), 'package.json'));
@@ -110,4 +167,4 @@ async function generateModuleConfigs(wizzDir, moduleConfigs, { trackFile }) {
110
167
  }
111
168
  }
112
169
 
113
- module.exports = { generateModuleConfigs };
170
+ module.exports = { generateModuleConfigs, captureRuntimeValues, RUNTIME_KEYS };