@ingcrea/aumic-tailwind-killer 4.1.4 → 4.1.6

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.
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ /**
8
+ * @file 6_galaxies/index.ts
9
+ *
10
+ * [EN] Galaxy Layer — the outermost shell of the AUM-IC Tailwind Killer.
11
+ * Responsibilities:
12
+ * 1. Parse CLI flags via Commander.js
13
+ * 2. If no flags provided, launch the interactive Inquirer prompt sequence
14
+ * 3. Validate and normalize all user options into a ResolvedOptions object
15
+ * 4. Dispatch to the correct Ecosystem (Transmutation or Restore)
16
+ * This file contains ZERO business logic. It is a pure coordinator.
17
+ *
18
+ * [ES] Capa Galaxia — la capa más externa del AUM-IC Tailwind Killer.
19
+ * Responsabilidades:
20
+ * 1. Parsear flags CLI vía Commander.js
21
+ * 2. Si no hay flags, lanzar la secuencia interactiva de prompts Inquirer
22
+ * 3. Validar y normalizar todas las opciones del usuario en un objeto ResolvedOptions
23
+ * 4. Despachar al Ecosistema correcto (Transmutación o Restauración)
24
+ * Este archivo contiene CERO lógica de negocio. Es un coordinador puro.
25
+ */
26
+ const picocolors_1 = __importDefault(require("picocolors"));
27
+ const inquirer_1 = __importDefault(require("inquirer"));
28
+ const commander_1 = require("commander");
29
+ const path_1 = __importDefault(require("path"));
30
+ const fs_extra_1 = __importDefault(require("fs-extra"));
31
+ const TransmutationEcosystem_1 = require("../5_ecosystems/TransmutationEcosystem");
32
+ const RestoreEcosystem_1 = require("../5_ecosystems/RestoreEcosystem");
33
+ // [EN] Dynamic version read from package.json at startup. [ES] Versión dinámica leída del package.json al arrancar.
34
+ let pkgVersion = '4.1.5';
35
+ try {
36
+ pkgVersion = JSON.parse(fs_extra_1.default.readFileSync(path_1.default.join(__dirname, '../../package.json'), 'utf-8').replace(/^\uFEFF/, '')).version;
37
+ }
38
+ catch { }
39
+ const aumicLink = `\x1b]8;;https://github.com/ingcrea/aum-ic\x07AUM-IC\x1b]8;;\x07`;
40
+ /**
41
+ * [EN] CLI entry point. Parses args, resolves options interactively or from flags,
42
+ * validates output mode, and dispatches to the appropriate ecosystem.
43
+ * [ES] Punto de entrada del CLI. Parsea args, resuelve opciones interactivamente o desde flags,
44
+ * valida el modo de salida, y despacha al ecosistema apropiado.
45
+ */
46
+ async function run() {
47
+ const program = new commander_1.Command();
48
+ program
49
+ .name('aumic-tailwind-killer')
50
+ .description(picocolors_1.default.cyan(`Motor de transmutación Tailwind → CSS puro (${aumicLink})`))
51
+ .version(pkgVersion)
52
+ .option('-m, --mode <type>', 'Vector de ataque: "local", "clone" o "restore"')
53
+ .option('-u, --url <url>', 'URL objetivo (Modo Forense)')
54
+ .option('-d, --depth <depth>', 'Profundidad de clonación: "page" o "site"')
55
+ .option('-t, --target <dir>', 'Directorio objetivo (por defecto: cwd)')
56
+ .option('-s, --scope <path>', 'Ataque Quirúrgico (ej. src/components/**/*.tsx)')
57
+ .option('-o, --output <type>', 'Arquitectura de salida: "aumic" o "global"')
58
+ .option('--ai <provider>', 'Proveedor IA para nombrado semántico')
59
+ .option('--key <token>', 'API Key del proveedor IA')
60
+ .option('-c, --concurrency <n>', 'Hilos concurrentes (Defecto: 2× núcleos CPU)')
61
+ .option('--simulate', 'Dry-Run: genera reporte sin mutar archivos')
62
+ .option('--no-eradicate', 'Omitir la erradicación de Tailwind al finalizar')
63
+ .option('--interactive', 'Forzar el modo interactivo (menú UI)')
64
+ .parse(process.argv);
65
+ const opts = program.opts();
66
+ const hasFlags = Object.keys(opts).some(k => !['interactive', 'eradicate'].includes(k));
67
+ // [EN] Print the banner on every invocation. [ES] Imprimir el banner en cada invocación.
68
+ console.log(picocolors_1.default.cyan(picocolors_1.default.bold(`\n⚔️ ${aumicLink} TAILWIND KILLER v${pkgVersion}`)));
69
+ let answers;
70
+ if (!hasFlags || opts.interactive) {
71
+ // ── Interactive Mode ────────────────────────────────────────────────────
72
+ console.log(picocolors_1.default.gray('Iniciando consola de mando interactiva...\n'));
73
+ const raw = await inquirer_1.default.prompt([
74
+ { type: 'list', name: 'mode', message: '¿Vector de Ataque?', choices: [
75
+ { name: 'Modo Local (proyecto en disco)', value: 'local' },
76
+ { name: 'Ataque Quirúrgico (migración incremental)', value: 'surgical' },
77
+ { name: 'Modo Forense (clonar web por URL)', value: 'clone' },
78
+ { name: 'Modo Restauración (rollback aumic-lock)', value: 'restore' },
79
+ ] },
80
+ { type: 'input', name: 'scope', message: 'Glob quirúrgico (ej. src/**/*.tsx):', when: (a) => a.mode === 'surgical' },
81
+ { type: 'input', name: 'targetUrl', message: 'URL objetivo:', when: (a) => a.mode === 'clone' },
82
+ { type: 'list', name: 'cloneDepth', message: '¿Alcance de clonación?', when: (a) => a.mode === 'clone', choices: [{ name: 'Solo esta página', value: 'page' }, { name: 'Sitio completo', value: 'site' }] },
83
+ { type: 'input', name: 'targetDir', message: (a) => a.mode === 'clone' ? 'Directorio para el clon:' : 'Directorio raíz del proyecto (Enter = actual):', default: (a) => a.mode === 'clone' ? path_1.default.join(process.cwd(), 'aumic-clone') : process.cwd() },
84
+ { type: 'list', name: 'outputMode', message: '¿Arquitectura de salida CSS?', when: (a) => a.mode !== 'restore', choices: [
85
+ { name: 'SCSS Modular AUM-IC (recomendado)', value: 'aumic' },
86
+ { name: 'CSS Global (1 solo archivo)', value: 'global' },
87
+ ] },
88
+ { type: 'input', name: 'concurrency', message: picocolors_1.default.cyan('Hilos asíncronos (Enter = Auto):'), when: (a) => a.mode !== 'restore', default: '' },
89
+ { type: 'confirm', name: 'simulate', message: picocolors_1.default.yellow('¿Activar Simulador de Daños (Dry-Run)?'), when: (a) => a.mode !== 'restore', default: false },
90
+ { type: 'confirm', name: 'useAI', message: picocolors_1.default.magenta(`¿Activar Nombrado Semántico ${aumicLink} (IA)?`), when: (a) => a.mode !== 'restore', default: false },
91
+ { type: 'list', name: 'aiProvider', message: 'Proveedor de IA:', when: (a) => a.useAI, choices: ['openai', 'claude', 'gemini', 'deepseek', 'xai', 'alibaba', 'ollama'] },
92
+ { type: 'password', name: 'apiKey', message: 'API Key (no se guardará):', when: (a) => a.useAI && a.aiProvider !== 'ollama' },
93
+ { type: 'confirm', name: 'eradicate', message: picocolors_1.default.red('¿Ejecutar Protocolo de Erradicación de Tailwind?'), when: (a) => a.mode === 'local' && !a.simulate, default: true },
94
+ ]);
95
+ answers = {
96
+ mode: raw.mode, scope: raw.scope, targetUrl: raw.targetUrl,
97
+ cloneDepth: raw.cloneDepth || 'page', targetDir: raw.targetDir,
98
+ outputMode: raw.outputMode || 'aumic',
99
+ simulate: !!raw.simulate, useAI: !!raw.useAI,
100
+ aiProvider: raw.aiProvider, apiKey: raw.apiKey,
101
+ eradicate: raw.eradicate !== false, concurrency: raw.concurrency,
102
+ };
103
+ }
104
+ else {
105
+ // ── Flag Mode (CI / scripted) ───────────────────────────────────────────
106
+ answers = {
107
+ mode: opts.scope ? 'surgical' : (opts.mode || 'local'),
108
+ scope: opts.scope, targetUrl: opts.url, cloneDepth: opts.depth || 'page',
109
+ targetDir: opts.target || process.cwd(),
110
+ outputMode: opts.output || 'aumic',
111
+ simulate: !!opts.simulate, useAI: !!opts.ai,
112
+ aiProvider: opts.ai, apiKey: opts.key,
113
+ eradicate: opts.eradicate, concurrency: opts.concurrency,
114
+ };
115
+ }
116
+ // ── Beta Mode Guard ─────────────────────────────────────────────────────────
117
+ if (['css-modules', 'styled-components'].includes(answers.outputMode)) {
118
+ console.log(picocolors_1.default.yellow(`\n[!] El modo "${answers.outputMode}" está en fase Beta. Usa "aumic" o "global" por ahora.\n`));
119
+ process.exit(0);
120
+ }
121
+ // ── Dispatch ────────────────────────────────────────────────────────────────
122
+ if (answers.mode === 'restore') {
123
+ await (0, RestoreEcosystem_1.runRestoreEcosystem)(path_1.default.resolve(answers.targetDir));
124
+ }
125
+ else {
126
+ // [EN] Pass dist/ dir so ecosystems can locate worker.js and lexicon.
127
+ // [ES] Pasar directorio dist/ para que los ecosistemas localicen worker.js y el léxico.
128
+ await (0, TransmutationEcosystem_1.runTransmutationEcosystem)(answers, path_1.default.join(__dirname, '..'));
129
+ }
130
+ }
131
+ run().catch(console.error);