qdd-framework 2.10.0-rc.3 → 2.10.0-rc.31

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/README.md CHANGED
@@ -10,9 +10,12 @@
10
10
  ## 🚀 Instalación Rápida
11
11
 
12
12
  ```bash
13
- npm install -g qdd-framework
13
+ npm install -g qdd-framework --allow-scripts=qdd-framework
14
14
  ```
15
15
 
16
+ npm 12 no corre los scripts de instalación sin esa bandera. Si instalas sin ella, la primera vez que uses `qdd` se baja su
17
+ binario desde el release de GitHub de esa versión, fuera del bloqueo de npm.
18
+
16
19
  > **Conflicto con el paquete `qdd` de npm:** existe un paquete ajeno llamado `qdd` (no pertenece a QDD Framework) que también instala un comando `qdd`. Si lo tienes instalado globalmente, desinstálalo antes (`npm uninstall -g qdd`) para que `qdd` apunte a QDD Framework. Desde v1.9.22 su presencia ya no rompe la instalación (antes fallaba con `EISDIR`).
17
20
 
18
21
  ---
@@ -33,7 +36,7 @@ qdd audit # corre las pruebas y las reglas de QDD; funciona desde cualquier
33
36
  - `qdd doctor`: Diagnóstico determinista de salud del entorno.
34
37
  - `qdd report`: Reporte ejecutivo consolidado en formato Texto, Markdown o JSON para CI/CD.
35
38
  - `qdd evolution`: Recomienda la siguiente mejora del proyecto.
36
- - `qdd dashboard`: Centro de Comando Web interactivo con streaming en tiempo real (SSE) y ejecución de agentes.
39
+ - `qdd dashboard` (obsoleto; el panel que sigue es `qdd-tareas`): Centro de Comando Web interactivo con streaming en tiempo real (SSE) y ejecución de agentes.
37
40
  - `qdd run`: Pipeline secuencial de comandos con rollback, o modo supervisor con auto-reparación (`qdd run --keep-alive`).
38
41
 
39
42
  ---
package/bin/qdd.js CHANGED
@@ -24,8 +24,24 @@ function versionDelPaquete() {
24
24
  }
25
25
  }
26
26
 
27
+ function binarioActual() {
28
+ return rutaDelBinario({ platform: process.platform, env: process.env, dir: __dirname, version: versionDelPaquete(), existe: fs.existsSync });
29
+ }
30
+
31
+ // Con npm 12, quien instala sin --allow-scripts=qdd-framework no corrió el postinstall (FND-143): el primer qdd baja el
32
+ // binario con el mismo instalador. Lo que escribe va a stderr: otro programa puede estar leyendo la salida de qdd.
33
+ function bajarAlPrimerUso() {
34
+ const instalador = path.join(__dirname, '..', 'install.js');
35
+ if (fs.existsSync(binarioActual()) || !fs.existsSync(instalador)) {
36
+ return;
37
+ }
38
+ console.error('[QDD] qdd no tiene su binario: lo bajo ahora, porque npm no corrió su instalación.');
39
+ spawnSync(process.execPath, [instalador, '--primer-uso'], { stdio: ['ignore', 2, 'inherit'] });
40
+ }
41
+
27
42
  function main() {
28
- const binaryPath = rutaDelBinario({ platform: process.platform, env: process.env, dir: __dirname, version: versionDelPaquete(), existe: fs.existsSync });
43
+ bajarAlPrimerUso();
44
+ const binaryPath = binarioActual();
29
45
 
30
46
  const result = spawnSync(binaryPath, process.argv.slice(2), {
31
47
  stdio: 'inherit'
@@ -33,14 +49,14 @@ function main() {
33
49
 
34
50
  // Sin binario, lo más probable es que npm esté reinstalando qdd: 75 es «todavía no» para los pedidos del panel (FND-135).
35
51
  if (result.error && result.error.code === 'ENOENT') {
36
- console.error('[QDD] qdd se está actualizando: inténtalo de nuevo en un momento.');
37
- console.error('[QDD] Si sigue así, reinstala el paquete con: npm install -g qdd-framework');
52
+ console.error('[QDD] qdd no tiene su binario: se está actualizando, o npm bloqueó su instalación (npm 12 lo hace por defecto).');
53
+ console.error('[QDD] Si sigue así, reinstala el paquete con: npm install -g qdd-framework --allow-scripts=qdd-framework');
38
54
  process.exit(75);
39
55
  }
40
56
 
41
57
  if (result.error) {
42
58
  console.error(`[QDD] No se pudo ejecutar el binario nativo ${binaryPath}: ${result.error.message}`);
43
- console.error('[QDD] Reinstala el paquete con: npm install -g qdd-framework');
59
+ console.error('[QDD] Reinstala el paquete con: npm install -g qdd-framework --allow-scripts=qdd-framework');
44
60
  process.exit(1);
45
61
  }
46
62
 
package/install.js CHANGED
@@ -9,6 +9,8 @@ const VERSION = 'v' + pkg.version;
9
9
  const REPO = 'trdago/qdd-framework';
10
10
  // TOPE_VERSION_MS: el antivirus puede demorar la primera ejecución de un binario recién descargado.
11
11
  const TOPE_VERSION_MS = 60000;
12
+ // TOPE_TURNO_MS: un turno más viejo que esto quedó abandonado; bajar el binario tarda mucho menos.
13
+ const TOPE_TURNO_MS = 5 * 60 * 1000;
12
14
 
13
15
  const platformMap = {
14
16
  win32: 'windows',
@@ -76,6 +78,10 @@ function main() {
76
78
  fs.mkdirSync(binDir, { recursive: true });
77
79
  }
78
80
 
81
+ if (process.argv.includes('--primer-uso')) {
82
+ pedirTurno(path.join(binDir, '.bajando'));
83
+ }
84
+
79
85
  const binarioLocal = resolverBinarioLocal(__dirname, binaryName);
80
86
  if (binarioLocal) {
81
87
  console.log(`[QDD] Binario local detectado en ${binarioLocal}. Usando copia local para desarrollo...`);
@@ -109,10 +115,52 @@ function instalarBinarioIndicado({ origen, destino, carpeta }) {
109
115
  }
110
116
  }
111
117
 
118
+ // tomarTurno: varios qdd sin binario a la vez (un panel, por ejemplo) no bajan cada uno el suyo.
119
+ function tomarTurno(ruta) {
120
+ try {
121
+ fs.closeSync(fs.openSync(ruta, 'wx'));
122
+ return true;
123
+ } catch (err) {
124
+ if (err.code !== 'EEXIST') {
125
+ throw err;
126
+ }
127
+ }
128
+ if (Date.now() - fs.statSync(ruta).mtimeMs < TOPE_TURNO_MS) {
129
+ return false;
130
+ }
131
+ fs.rmSync(ruta, { force: true });
132
+ return tomarTurno(ruta);
133
+ }
134
+
135
+ // pedirTurno sale con 75, el «todavía no» de los pedidos, si otro qdd ya lo está bajando.
136
+ function pedirTurno(ruta) {
137
+ try {
138
+ if (!tomarTurno(ruta)) {
139
+ console.error('[QDD] Otro proceso ya está bajando el binario.');
140
+ process.exit(75);
141
+ }
142
+ } catch (err) {
143
+ fallar(`no se pudo escribir en la carpeta del paquete: ${err.message}`);
144
+ }
145
+ process.on('exit', () => fs.rmSync(ruta, { force: true }));
146
+ }
147
+
148
+ // carpetaDeDescarga es propia de este proceso: un postinstall y un primer uso pueden correr a la vez.
149
+ function carpetaDeDescarga() {
150
+ try {
151
+ const carpeta = fs.mkdtempSync(path.join(__dirname, 'descarga-'));
152
+ process.on('exit', () => fs.rmSync(carpeta, { recursive: true, force: true }));
153
+ return carpeta;
154
+ } catch (err) {
155
+ return fallar(`no se pudo escribir en la carpeta del paquete: ${err.message}`);
156
+ }
157
+ }
158
+
112
159
  // 2. Descarga desde GitHub Releases
113
160
  function descargarDesdeRelease({ os, arch, ext, binaryName, binDir, destino, carpeta }) {
114
161
  const url = `https://github.com/${REPO}/releases/download/${VERSION}/qdd_${os}_${arch}.${ext}`;
115
- const downloadDest = path.join(__dirname, `qdd-download.${ext}`);
162
+ const descarga = carpetaDeDescarga();
163
+ const downloadDest = path.join(descarga, `qdd-download.${ext}`);
116
164
 
117
165
  console.log(`[QDD] Descargando binario nativo para ${os}-${arch}...`);
118
166
  console.log(`[QDD] URL: ${url}`);
@@ -145,7 +193,7 @@ function descargarDesdeRelease({ os, arch, ext, binaryName, binDir, destino, car
145
193
  function extractBinary() {
146
194
  console.log('[QDD] Extrayendo...');
147
195
  try {
148
- const bin = instalarDescarga({ os, paquete: downloadDest, carpeta: __dirname, binaryName, binDir, env: process.env, destino });
196
+ const bin = instalarDescarga({ os, paquete: downloadDest, carpeta: descarga, binaryName, binDir, env: process.env, destino });
149
197
  console.log('[QDD] ¡Instalación nativa completada exitosamente!');
150
198
  terminarInstalacion({ bin, carpeta });
151
199
  } catch (err) {
@@ -276,7 +324,7 @@ function codigoDeFalla(env) {
276
324
 
277
325
  function fallar(motivo) {
278
326
  console.error(`[QDD] La instalación falló: ${motivo}`);
279
- console.error('[QDD] Para reintentar: npm install -g qdd-framework');
327
+ console.error('[QDD] Para reintentar: npm install -g qdd-framework --allow-scripts=qdd-framework');
280
328
  process.exit(codigoDeFalla(process.env));
281
329
  }
282
330
 
@@ -290,7 +338,7 @@ function actualizarConsola(bin) {
290
338
  }
291
339
  }
292
340
 
293
- module.exports = { esArchivo, estaDentroDeNodeModules, resolverBinarioLocal, comandoExtraer, instalarDescarga, codigoDeFalla, carpetaDeVersiones, destinoDelBinario, respondeBinario, moverBinario, instalarCopia, registrarVersion };
341
+ module.exports = { esArchivo, estaDentroDeNodeModules, resolverBinarioLocal, comandoExtraer, instalarDescarga, codigoDeFalla, carpetaDeVersiones, destinoDelBinario, respondeBinario, moverBinario, instalarCopia, registrarVersion, tomarTurno };
294
342
 
295
343
  if (require.main === module) {
296
344
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qdd-framework",
3
- "version": "2.10.0-rc.3",
3
+ "version": "2.10.0-rc.31",
4
4
  "description": "Quality-Driven Development Framework",
5
5
  "bin": {
6
6
  "qdd": "bin/qdd.js"