qdd-framework 2.9.4-rc.1 → 2.9.5-rc.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.
Files changed (2) hide show
  1. package/install.js +47 -22
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -1,12 +1,14 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const https = require('https');
4
- const { execSync } = require('child_process');
4
+ const { execSync, execFileSync } = require('child_process');
5
5
 
6
6
  // Configuración del Release (Automático según tu GitHub)
7
7
  const pkg = require('./package.json');
8
8
  const VERSION = 'v' + pkg.version;
9
9
  const REPO = 'trdago/qdd-framework';
10
+ // TOPE_VERSION_MS: el antivirus puede demorar la primera ejecución de un binario recién descargado.
11
+ const TOPE_VERSION_MS = 60000;
10
12
 
11
13
  const platformMap = {
12
14
  win32: 'windows',
@@ -103,9 +105,8 @@ function descargarDesdeRelease({ os, arch, ext, binaryName, binDir }) {
103
105
  }
104
106
 
105
107
  if (response.statusCode !== 200) {
106
- console.error(`[QDD] Error: GitHub Release devolvió HTTP ${response.statusCode} para ${targetUrl}`);
107
108
  console.error('[QDD] Si estás instalando desde una versión no publicada aún, compila localmente con "make build"');
108
- process.exit(0); // Permitir que la instalación de npm continúe sin romper builds de CI
109
+ fallar(`GitHub Release devolvió HTTP ${response.statusCode} para ${targetUrl}`);
109
110
  }
110
111
 
111
112
  response.pipe(file);
@@ -113,36 +114,60 @@ function descargarDesdeRelease({ os, arch, ext, binaryName, binDir }) {
113
114
  file.close(extractBinary);
114
115
  });
115
116
  }).on('error', (err) => {
116
- console.error('[QDD] Error de red descargando el binario:', err.message);
117
- process.exit(0);
117
+ fallar(`error de red descargando el binario: ${err.message}`);
118
118
  });
119
119
  }
120
120
 
121
121
  function extractBinary() {
122
122
  console.log('[QDD] Extrayendo...');
123
123
  try {
124
- if (os === 'windows') {
125
- execSync(`tar -xf "${downloadDest}" -C "${__dirname}"`);
126
- }
127
- if (os !== 'windows') {
128
- execSync(`tar -xzf "${downloadDest}" -C "${__dirname}"`);
129
- }
130
- const extractedBin = path.join(__dirname, binaryName);
131
- if (fs.existsSync(extractedBin)) {
132
- fs.renameSync(extractedBin, path.join(binDir, binaryName));
133
- fs.chmodSync(path.join(binDir, binaryName), 0o755);
134
- }
135
- if (fs.existsSync(downloadDest)) {
136
- fs.unlinkSync(downloadDest);
137
- }
124
+ const bin = instalarDescarga({ os, paquete: downloadDest, carpeta: __dirname, binaryName, binDir, env: process.env });
138
125
  console.log('[QDD] ¡Instalación nativa completada exitosamente!');
139
- actualizarConsola(path.join(binDir, binaryName));
126
+ actualizarConsola(bin);
140
127
  } catch (err) {
141
- console.error('[QDD] Error al extraer el binario:', err.message);
128
+ fallar(`no se pudo instalar el binario: ${err.message}`);
142
129
  }
143
130
  }
144
131
  }
145
132
 
133
+ // comandoExtraer: en Windows, el tar del sistema con su ruta completa. En Git Bash, el primero del PATH es GNU tar, que no
134
+ // abre un zip y toma «C:» por un host remoto (MEJ-013).
135
+ function comandoExtraer(os, paquete, destino, env) {
136
+ if (os === 'windows') {
137
+ const programa = path.win32.join(env.SystemRoot || 'C:\\Windows', 'System32', 'tar.exe');
138
+ return { programa, args: ['-xf', paquete, '-C', destino] };
139
+ }
140
+ return { programa: 'tar', args: ['-xzf', paquete, '-C', destino] };
141
+ }
142
+
143
+ // instalarDescarga deja el binario en bin/ solo si responde; si algo falla, lanza el error y el binario anterior sigue ahí.
144
+ function instalarDescarga({ os, paquete, carpeta, binaryName, binDir, env }) {
145
+ const { programa, args } = comandoExtraer(os, paquete, carpeta, env);
146
+ execFileSync(programa, args, { stdio: 'pipe' });
147
+ const extraido = path.join(carpeta, binaryName);
148
+ if (!esArchivo(extraido)) {
149
+ throw new Error(`el paquete descargado no trae ${binaryName}`);
150
+ }
151
+ fs.chmodSync(extraido, 0o755);
152
+ execFileSync(extraido, ['--version'], { stdio: 'pipe', timeout: TOPE_VERSION_MS });
153
+ const destino = path.join(binDir, binaryName);
154
+ fs.renameSync(extraido, destino);
155
+ fs.rmSync(paquete, { force: true });
156
+ return destino;
157
+ }
158
+
159
+ // codigoDeFalla: sin binario, npm tiene que enterarse (y conservar la versión anterior). Quien necesite instalar sin
160
+ // binario a propósito, como un build de CI, lo pide con QDD_INSTALL_TOLERANTE=1.
161
+ function codigoDeFalla(env) {
162
+ return env.QDD_INSTALL_TOLERANTE === '1' ? 0 : 1;
163
+ }
164
+
165
+ function fallar(motivo) {
166
+ console.error(`[QDD] La instalación falló: ${motivo}`);
167
+ console.error('[QDD] Para reintentar: npm install -g qdd-framework');
168
+ process.exit(codigoDeFalla(process.env));
169
+ }
170
+
146
171
  // actualizarConsola deja el panel de Claude Code en la versión recién instalada si el usuario lo activó
147
172
  // ('qdd consola activar', RFC 0006 §3.6). Sin activar no hace nada; un error no rompe la instalación.
148
173
  function actualizarConsola(bin) {
@@ -153,7 +178,7 @@ function actualizarConsola(bin) {
153
178
  }
154
179
  }
155
180
 
156
- module.exports = { esArchivo, estaDentroDeNodeModules, resolverBinarioLocal };
181
+ module.exports = { esArchivo, estaDentroDeNodeModules, resolverBinarioLocal, comandoExtraer, instalarDescarga, codigoDeFalla };
157
182
 
158
183
  if (require.main === module) {
159
184
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qdd-framework",
3
- "version": "2.9.4-rc.1",
3
+ "version": "2.9.5-rc.1",
4
4
  "description": "Quality-Driven Development Framework",
5
5
  "bin": {
6
6
  "qdd": "bin/qdd.js"