@archznn/xavva 2.0.3 → 2.2.0

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
@@ -1,78 +1 @@
1
- # XAVVA 🚀 (Windows Only) `v2.0.3`
2
-
3
- Xavva é uma CLI de alto desempenho construída com **Bun** para automatizar o ciclo de desenvolvimento de aplicações Java (Maven/Gradle) rodando no Apache Tomcat. Ela foi desenhada especificamente para desenvolvedores que buscam a velocidade de ambientes modernos (como Node.js/Vite) dentro do ecossistema Java Enterprise.
4
-
5
- ---
6
-
7
- ## 🛠️ Por que Xavva?
8
-
9
- Desenvolver para Java/Tomcat tradicionalmente envolve ciclos lentos de `clean install`, `war deploy` e restarts de servidor. O Xavva quebra esse paradigma ao introduzir um fluxo de **Hot-Reload incremental**, onde apenas o que mudou é enviado ao servidor.
10
-
11
- ### ⚡ Funcionalidades de Elite
12
-
13
- - **Interactive Dashboard (TUI)**: Um painel em tempo real (`--tui`) com métricas de sistema, status do servidor e atalhos rápidos (Restart, Clear, Quit).
14
- - **Smart Log Analyzer**: Logs inteligentes que escondem ruídos do framework (Stack Folding) e destacam a causa raiz de erros Java.
15
- - **Ultra-Fast Hot Swap**: Compilação incremental e injeção direta de arquivos `.class` e recursos (JSP, HTML, CSS, JS) no Tomcat em execução sem restart.
16
- - **Gradle & Maven Native**: Suporte robusto para ambos os ecossistemas, incluindo extração automática de classpath para execução de classes standalone (`run`/`debug`).
17
- - **Segurança & Robustez**: Auditoria de dependências (`.jar`) e execução protegida contra *Command Injection* no PowerShell.
18
- - **Pathing JAR (Windows)**: Contorna limites de caracteres do Windows em classpaths gigantes.
19
- - **Auto-Healing**: Diagnóstico e reparo automático de problemas comuns de ambiente.
20
-
21
- ---
22
-
23
- ## 🚀 Começo Rápido
24
-
25
- ### Instalação
26
- ```powershell
27
- # Instalação global via NPM
28
- npm install -g @archznn/xavva
29
-
30
- # Iniciar em modo Dashboard (TUI)
31
- xavva dev --tui
32
- ```
33
-
34
- ---
35
-
36
- ## 📖 Referência de Comandos
37
-
38
- O Xavva 2.0 utiliza uma arquitetura modular de comandos e serviços.
39
-
40
- ### 1. Modo Desenvolvimento (`xavva dev`)
41
- O comando principal para o dia a dia. Ativa o monitoramento de arquivos e o Hot-Reload.
42
- - **Flags úteis**:
43
- - `--tui`: Ativa o Dashboard interativo no terminal.
44
- - `--no-build`: Pula o build inicial.
45
- - `--watch`: Ativa o modo de observação de arquivos (padrão em `dev`).
46
- - `--port 8081`: Define uma porta específica para o Tomcat.
47
-
48
- ### 2. Configuração de Projeto (`xavva.json`)
49
- Crie um arquivo `xavva.json` na raiz do seu projeto para salvar suas configurações:
50
- ```json
51
- {
52
- "project": {
53
- "appName": "meu-app",
54
- "buildTool": "maven",
55
- "tui": true
56
- },
57
- "tomcat": {
58
- "port": 8080
59
- }
60
- }
61
- ```
62
-
63
- ### 3. Execução de Classes (`xavva run` / `xavva debug`)
64
- Executa classes Java standalone (`public static void main`) com resolução automática de dependências.
65
-
66
- ---
67
-
68
- ## 🏗️ Arquitetura Xavva 2.0
69
-
70
- O Xavva foi refatorado para uma arquitetura de **Injeção de Dependências** e **Serviços Centralizados**:
71
-
72
- - **DashboardService**: Gerenciamento de interface TUI e interatividade.
73
- - **LogAnalyzer**: Processamento inteligente de logs e stack traces.
74
- - **ProjectService**: Inteligência centralizada para descoberta de diretórios e artefatos.
75
- - **CommandRegistry**: Despacho modular de comandos.
76
-
77
- ---
78
- *Desenvolvido para transformar o legado em produtivo. 🚀*
1
+ # XAVVA CLI 🚀> Ultra-fast development toolkit for Java Enterprise (Tomcat) on Windows[![Version](https://img.shields.io/badge/version-2.2.0-blue.svg)](https://github.com/leorsousa05/Xavva)[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)Xavva is a high-performance CLI built with **Bun** that transforms the Java/Tomcat development experience. It brings modern development workflows (like Node.js/Vite) to the Java Enterprise ecosystem with hot-reload, smart logging, and automated deployment.---## ✨ Features- ⚡ **Hot Reload** — Incremental compilation and class injection without server restart- 📊 **Interactive Dashboard** — Real-time TUI with system metrics and shortcuts- 🧠 **Smart Log Analyzer** — Stack trace folding and root cause highlighting- 🔒 **Security Audit** — Automated vulnerability scanning via OSV.dev- 📦 **Dependency Analysis** — Detect conflicts and outdated dependencies- 🎯 **Maven & Gradle** — Native support for both build tools- 🔧 **Auto-Healing** — Automatic diagnosis and repair of common issues---## 📦 Installation```powershell# Via NPMnpm install -g @archznn/xavva# Or run directly with Bunbunx @archznn/xavva dev```---## 🚀 Quick Start```bash# Start development mode with dashboardxavva dev --tui# Deploy to Tomcatxavva deploy# Analyze dependencies for issuesxavva deps# Check for security vulnerabilitiesxavva audit```---## 📖 Commands### Core Development| Command | Description ||---------|-------------|| `xavva dev` | Full development mode (build + deploy + watch + debug) || `xavva deploy` | Build and deploy application to Tomcat || `xavva build` | Compile project only || `xavva start` | Start Tomcat server only |### Code Execution| Command | Description ||---------|-------------|| `xavva run <class>` | Execute a Java class with automatic classpath || `xavva debug <class>` | Debug a Java class (port 5005) |### Analysis & Monitoring| Command | Description ||---------|-------------|| `xavva logs` | Stream and analyze Tomcat logs in real-time || `xavva deps` | **Analyze dependencies** — detect conflicts, find updates || `xavva audit` | Security audit of JAR files via OSV.dev || `xavva doctor` | Diagnose environment issues (JAVA_HOME, DCEVM) || `xavva profiles` | List available Maven/Gradle profiles || `xavva docs` | Generate endpoint documentation |---## 🔍 Dependency AnalysisThe `xavva deps` command provides comprehensive dependency analysis:```bash# Basic analysisxavva deps# With verbose output for debuggingxavva deps --verbose# Show fix suggestions for conflictsxavva deps --fix# Export report as JSONxavva deps --output report.json# Fail on critical conflicts (useful in CI/CD)xavva deps --strict```### What it detects:- ⚠️ **Version Conflicts** — Same dependency with different versions- ⬆️ **Available Updates** — Newer versions in Maven Central- 🔴 **Major Updates** — Breaking changes that need attention- 📊 **Statistics** — Direct vs transitive dependencies### Sample output:```══════════════════════════════════════════════════════════📊 DEPENDENCY ANALYSIS══════════════════════════════════════════════════════════Statistics: Total: 183 dependencies Direct: 45 | Transitive: 138⚠️ VERSION CONFLICTS (2) ✖ com.fasterxml.jackson.core:jackson-databind Versions: 2.13.0, 2.12.6⬆️ UPDATES AVAILABLE (5) ↑ org.postgresql:postgresql 42.2.5 → 42.7.1⚠️ MAJOR UPDATES (1) ! org.springframework.boot:spring-boot-starter 2.5.0 → 3.1.0```---## ⚙️ ConfigurationCreate `xavva.json` in your project root:```json{ "project": { "appName": "my-application", "buildTool": "maven", "profile": "dev", "tui": false }, "tomcat": { "path": "C:/apache-tomcat", "port": 8080 }}```### CLI Options| Option | Description ||--------|-------------|| `-p, --path <path>` | Tomcat installation path || `-t, --tool <tool>` | Build tool: `maven` or `gradle` || `-n, --name <name>` | Application name (WAR context) || `--port <port>` | Tomcat port (default: 8080) || `-P, --profile <prof>` | Maven/Gradle profile || `-e, --encoding <enc>` | Source encoding (utf8, cp1252) || `-w, --watch` | Enable file watching || `--tui` | Interactive dashboard mode || `-d, --debug` | Enable JPDA debugger || `-c, --clean` | Clean logs before start || `-s, --no-build` | Skip initial build || `-V, --verbose` | Detailed output |---## 🏗️ ArchitectureXavva uses a modular service-oriented architecture:- **DashboardService** — TUI management and interactivity- **LogAnalyzer** — Intelligent log processing- **DependencyAnalyzerService** — Dependency conflict detection- **ProjectService** — Project structure discovery- **BuildService** — Maven/Gradle integration- **TomcatService** — Server lifecycle management---## 🤝 ContributingContributions are welcome! Please feel free to submit a Pull Request.---## 📄 LicenseMIT License — see [LICENSE](LICENSE) for details.---<p align="center"> <sub>Built with ❤️ for Java developers who miss modern tooling</sub></p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archznn/xavva",
3
- "version": "2.0.3",
3
+ "version": "2.2.0",
4
4
  "description": "Ultra-fast CLI tool for Java/Tomcat development on Windows with Hot-Reload and Zero Config.",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
@@ -60,8 +60,9 @@ export class AuditCommand implements Command {
60
60
  Logger.info("Total de Falhas", totalVulns);
61
61
  Logger.info("Relatório gerado via", "OSV.dev (Open Source Vulnerability Database)");
62
62
 
63
- } catch (e: any) {
64
- Logger.error(e.message);
63
+ } catch (e) {
64
+ const message = e instanceof Error ? e.message : String(e);
65
+ Logger.error(message);
65
66
  }
66
67
  }
67
68
 
@@ -2,6 +2,7 @@ import type { Command } from "./Command";
2
2
  import type { AppConfig } from "../types/config";
3
3
  import { BuildService } from "../services/BuildService";
4
4
  import { Logger } from "../utils/ui";
5
+ import { ProcessManager } from "../utils/processManager";
5
6
 
6
7
  export class BuildCommand implements Command {
7
8
  constructor(private buildService: BuildService) {}
@@ -14,9 +15,10 @@ export class BuildCommand implements Command {
14
15
  try {
15
16
  await this.buildService.runBuild();
16
17
  Logger.success("Build completed successfully!");
17
- } catch (error: any) {
18
- Logger.error(error.message);
19
- process.exit(1);
18
+ } catch (error) {
19
+ const message = error instanceof Error ? error.message : String(error);
20
+ Logger.error(message);
21
+ await ProcessManager.getInstance().shutdown(1);
20
22
  }
21
23
  }
22
24
  }
@@ -2,6 +2,7 @@ import type { AppConfig, CLIArguments } from "../types/config";
2
2
  import type { Command } from "./Command";
3
3
  import { Logger } from "../utils/ui";
4
4
  import { HelpCommand } from "./HelpCommand";
5
+ import { ProcessManager } from "../utils/processManager";
5
6
 
6
7
  export class CommandRegistry {
7
8
  private commands = new Map<string, Command>();
@@ -18,19 +19,22 @@ export class CommandRegistry {
18
19
  return this.commands.get(name);
19
20
  }
20
21
 
21
- async execute(name: string, config: AppConfig, args: CLIArguments) {
22
+ async execute(name: string, config: AppConfig, args: CLIArguments): Promise<void> {
22
23
  const command = this.commands.get(name);
24
+ const processManager = ProcessManager.getInstance();
25
+
23
26
  if (!command) {
24
27
  Logger.error(`Comando desconhecido: ${name}`);
25
28
  await new HelpCommand().execute(config);
26
- process.exit(1);
29
+ await processManager.shutdown(2);
27
30
  }
28
31
 
29
32
  try {
30
33
  await command.execute(config, args);
31
- } catch (error: any) {
32
- Logger.error(`Erro ao executar comando '${name}': ${error.message}`);
33
- process.exit(1);
34
+ } catch (error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ Logger.error(`Erro ao executar comando '${name}': ${message}`);
37
+ await processManager.shutdown(1);
34
38
  }
35
39
  }
36
40
  }
@@ -20,7 +20,7 @@ export class DeployCommand implements Command {
20
20
  if (!incremental) {
21
21
  this.logConfiguration(config, isWatching);
22
22
  } else {
23
- Logger.watcher("Change detected", "change");
23
+ Logger.watch("Change detected");
24
24
  }
25
25
 
26
26
  try {
@@ -31,16 +31,16 @@ export class DeployCommand implements Command {
31
31
  await tomcat.clearWebapps();
32
32
 
33
33
  if (!config.project.skipBuild) {
34
- Logger.watcher("Building project", "start");
34
+ Logger.build("compiling...");
35
35
  await builder.runBuild(incremental);
36
36
  }
37
37
 
38
38
  if (!config.project.skipBuild) {
39
- Logger.build("Full project build and environment ready");
39
+ Logger.build("completed");
40
40
  }
41
41
  } else {
42
42
  if (!config.project.skipBuild) {
43
- Logger.watcher("Incremental compilation", "start");
43
+ Logger.build("incremental compile...");
44
44
  await builder.runBuild(incremental);
45
45
  }
46
46
  }
@@ -50,13 +50,13 @@ export class DeployCommand implements Command {
50
50
  const actualContextPath = contextPath || actualAppFolder || "";
51
51
  const actualAppUrl = `http://localhost:${config.tomcat.port}/${actualContextPath}`;
52
52
  await BrowserService.reload(actualAppUrl);
53
- Logger.watcher("Redeploy completed", "success");
53
+ Logger.success("redeploy completed");
54
54
  return;
55
55
  }
56
56
 
57
- Logger.build("Webapps cleaned");
57
+ Logger.server("cleaning webapps...");
58
58
  const artifactInfo = await builder.deployToWebapps();
59
- Logger.build("Artifacts generated");
59
+ Logger.server("artifacts ready");
60
60
 
61
61
  const finalContextPath = contextPath || artifactInfo.finalName.replace(".war", "");
62
62
  const appWebappPath = path.join(config.tomcat.path, "webapps", finalContextPath);
@@ -65,7 +65,7 @@ export class DeployCommand implements Command {
65
65
  // Se é um diretório (exploded), sincronizamos o conteúdo total para a pasta do webapps
66
66
  if (!fs.existsSync(appWebappPath)) fs.mkdirSync(appWebappPath, { recursive: true });
67
67
  await builder.syncExploded(artifactInfo.path, appWebappPath);
68
- Logger.build("Exploded directory synced to webapps");
68
+ Logger.server("synced exploded directory");
69
69
  } else {
70
70
  if (!fs.existsSync(appWebappPath)) fs.mkdirSync(appWebappPath, { recursive: true });
71
71
 
@@ -75,7 +75,7 @@ export class DeployCommand implements Command {
75
75
  if (!webappStat || artifactStat.mtimeMs > webappStat.mtimeMs) {
76
76
  try {
77
77
  Bun.spawnSync(["jar", "xf", artifactInfo.path], { cwd: appWebappPath });
78
- Logger.build("Artifacts deployed");
78
+ Logger.server("extracted WAR");
79
79
  } catch (e) {
80
80
  const extractCmd = `Expand-Archive -Path $env:ARTIFACT_PATH -DestinationPath $env:DEST_PATH -Force`;
81
81
  Bun.spawnSync(["powershell", "-command", extractCmd], {
@@ -85,10 +85,10 @@ export class DeployCommand implements Command {
85
85
  DEST_PATH: appWebappPath
86
86
  }
87
87
  });
88
- Logger.build("Artifacts deployed (legacy mode)");
88
+ Logger.server("extracted WAR (legacy)");
89
89
  }
90
90
  } else {
91
- Logger.build("Webapp already up to date, skipping extraction");
91
+ Logger.server("webapp up to date");
92
92
  }
93
93
  }
94
94
 
@@ -102,17 +102,19 @@ export class DeployCommand implements Command {
102
102
  };
103
103
 
104
104
  tomcat.start(config, isWatching);
105
- } catch (error: any) {
106
- Logger.error(error.message);
105
+ } catch (error) {
106
+ const message = error instanceof Error ? error.message : String(error);
107
+ Logger.error(message);
107
108
  throw error;
108
109
  }
109
110
  }
110
111
 
111
112
  private logConfiguration(config: AppConfig, isWatching: boolean) {
112
- Logger.config("Runtime", config.project.buildTool.toUpperCase());
113
- if (config.project.profile) Logger.config("Profile", config.project.profile.toUpperCase());
114
- Logger.config("Watch Mode", isWatching ? "ON" : "OFF");
115
- Logger.config("Debug", config.project.debug ? `ON (Port ${config.project.debugPort})` : "OFF");
113
+ Logger.section("Configuration");
114
+ Logger.config("runtime", config.project.buildTool.toLowerCase());
115
+ if (config.project.profile) Logger.config("profile", config.project.profile);
116
+ Logger.config("watch", isWatching);
117
+ Logger.config("debug", config.project.debug ? `port ${config.project.debugPort}` : false);
116
118
 
117
119
  let javaBin = "java";
118
120
  if (process.env.JAVA_HOME) {
@@ -125,9 +127,9 @@ export class DeployCommand implements Command {
125
127
  const hasDcevm = ["dcevm", "jetbrains", "trava", "jbr"].some(v => output.includes(v));
126
128
 
127
129
  if (!hasDcevm && isWatching) {
128
- Logger.config("Hot Reload", "Standard (No structural changes)");
130
+ Logger.config("hotswap", "standard");
129
131
  } else if (hasDcevm) {
130
- Logger.config("Hot Reload", "Advanced (DCEVM Active)");
132
+ Logger.config("hotswap", "dcevm");
131
133
  }
132
134
 
133
135
  const srcPath = path.join(process.cwd(), "src");
@@ -135,9 +137,10 @@ export class DeployCommand implements Command {
135
137
  const contextPath = (config.project.appName || "").replace(".war", "");
136
138
  const endpoints = EndpointService.scan(srcPath, contextPath);
137
139
  if (endpoints.length > 0) {
138
- Logger.config("Endpoints", endpoints.length);
140
+ Logger.config("endpoints", endpoints.length);
139
141
  }
140
142
  }
143
+ Logger.endSection();
141
144
  }
142
145
 
143
146
  private injectContextConfiguration(appPath: string) {
@@ -170,9 +173,12 @@ export class DeployCommand implements Command {
170
173
  const response = await fetch(url);
171
174
  if (response.status < 500) {
172
175
  const memory = await tomcat.getMemoryUsage();
173
- Logger.health(url, "success");
174
- Logger.health(`Status ${response.status}`, "success");
175
- Logger.health(`Memory ${memory}`, "success");
176
+ Logger.divider();
177
+ Logger.ready("Server ready");
178
+ Logger.url("Local", url);
179
+ Logger.info("Status", `${response.status}`);
180
+ Logger.info("Memory", memory);
181
+ Logger.done();
176
182
 
177
183
  if (!config.project.quiet) {
178
184
  this.showEndpointMap(config.tomcat.port, context);
@@ -184,32 +190,32 @@ export class DeployCommand implements Command {
184
190
  BrowserService.open(url);
185
191
  }
186
192
  } else {
187
- Logger.health(`App returned status ${response.status}`, "warn");
193
+ Logger.warn(`App returned status ${response.status}`);
188
194
  }
189
195
  } catch (e) {
190
- Logger.health(`Could not connect to ${url}`, "error");
196
+ Logger.error(`Could not connect to ${url}`);
191
197
  }
192
198
  }
193
199
 
194
200
  private showEndpointMap(port: number, context: string) {
195
201
  const endpoints = EndpointService.scan(path.join(process.cwd(), "src"), context);
196
202
  if (endpoints.length > 0) {
197
- Logger.newline();
198
- Logger.log(`${Logger.C.cyan}◈ ENDPOINT MAP:${Logger.C.reset}`);
203
+ Logger.section("Endpoints");
199
204
 
200
205
  const apis = endpoints.filter(e => e.className !== "JSP");
201
206
  const jsps = endpoints.filter(e => e.className === "JSP");
202
207
 
203
208
  if (apis.length > 0) {
204
209
  const uniqueApiUrls = [...new Set(apis.map(e => `http://localhost:${port}${e.fullPath}`))];
205
- uniqueApiUrls.forEach(url => Logger.log(`${Logger.C.dim}➜ ${Logger.C.reset}${url}`));
210
+ uniqueApiUrls.forEach(url => Logger.info("", url));
206
211
  }
207
212
 
208
213
  if (jsps.length > 0) {
209
- Logger.log(`${Logger.C.dim}--- JSPs ---${Logger.C.reset}`);
214
+ Logger.info("JSPs", "");
210
215
  const uniqueJspUrls = [...new Set(jsps.map(e => `http://localhost:${port}${e.fullPath}`))];
211
- uniqueJspUrls.forEach(url => Logger.log(`${Logger.C.dim}📄 ${Logger.C.reset}${url}`));
216
+ uniqueJspUrls.forEach(url => Logger.info("", ` ${url}`));
212
217
  }
218
+ Logger.endSection();
213
219
  }
214
220
  }
215
221
 
@@ -0,0 +1,123 @@
1
+ import type { Command } from "./Command";
2
+ import type { AppConfig, CLIArguments } from "../types/config";
3
+ import type { DependencyAnalysisResult } from "../services/DependencyAnalyzerService";
4
+ import { DependencyAnalyzerService } from "../services/DependencyAnalyzerService";
5
+ import { AuditService } from "../services/AuditService";
6
+ import { Logger } from "../utils/ui";
7
+ import { ProcessManager } from "../utils/processManager";
8
+ import fs from "fs";
9
+
10
+ export class DepsCommand implements Command {
11
+ private config!: AppConfig;
12
+
13
+ async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
14
+ this.config = config;
15
+ const analyzer = new DependencyAnalyzerService(config.project);
16
+ analyzer.setVerbose(!!args?.verbose);
17
+
18
+ Logger.section("Análise de Dependências");
19
+ Logger.info("Ferramenta", config.project.buildTool.toUpperCase());
20
+ Logger.info("Diretório", process.cwd());
21
+
22
+ const spinner = Logger.spinner("Analisando dependências...");
23
+
24
+ try {
25
+ const result = await analyzer.analyze();
26
+ spinner();
27
+
28
+ // Se não encontrou dependências, mostrar ajuda
29
+ if (result.dependencies.length === 0) {
30
+ Logger.warn("Nenhuma dependência encontrada!");
31
+ Logger.info("Possíveis causas:", "");
32
+ Logger.log(" • Projeto não foi compilado ainda (execute: mvn compile)");
33
+ Logger.log(" • Maven não está no PATH");
34
+ Logger.log(" • Arquivo pom.xml/build.gradle não encontrado");
35
+ Logger.log(" • Erro de parsing no arquivo de configuração");
36
+ Logger.newline();
37
+ Logger.log(`${Logger.C.cyan}Dica:${Logger.C.reset} Execute com --verbose para mais detalhes`);
38
+ return;
39
+ }
40
+
41
+ // Verificar vulnerabilidades se solicitado
42
+ if (args?.["scan"] !== false) {
43
+ Logger.step("Verificando vulnerabilidades");
44
+ // Integração com AuditService para check de vulnerabilidades
45
+ // nas dependências do projeto
46
+ }
47
+
48
+ // Exibir relatório
49
+ const report = analyzer.generateReport(result);
50
+ console.log(report);
51
+
52
+ // Ações adicionais baseadas em flags
53
+ if (args?.["fix"]) {
54
+ await this.suggestFixes(result, config.project.buildTool);
55
+ }
56
+
57
+ // Exportar resultado se solicitado
58
+ if (args?.["output"]) {
59
+ this.exportReport(result, args["output"] as string);
60
+ }
61
+
62
+ // Sair com erro se houver conflitos críticos
63
+ const hasErrors = result.conflicts.some(c => c.severity === "error");
64
+ if (hasErrors && args?.["strict"]) {
65
+ await ProcessManager.getInstance().shutdown(1);
66
+ }
67
+
68
+ } catch (error) {
69
+ spinner(false);
70
+ const message = error instanceof Error ? error.message : String(error);
71
+ Logger.error(`Falha na análise: ${message}`);
72
+ throw error;
73
+ }
74
+ }
75
+
76
+ private async suggestFixes(result: DependencyAnalysisResult, buildTool: string): Promise<void> {
77
+ if (result.conflicts.length === 0) {
78
+ Logger.success("Nenhum conflito para resolver!");
79
+ return;
80
+ }
81
+
82
+ Logger.newline();
83
+ Logger.section("Sugestões de Correção");
84
+
85
+ for (const conflict of result.conflicts) {
86
+ Logger.log(`\n${Logger.C.cyan}${conflict.groupId}:${conflict.artifactId}${Logger.C.reset}`);
87
+
88
+ if (buildTool === "maven") {
89
+ Logger.log(" Adicione ao pom.xml:");
90
+ Logger.log(` ${Logger.C.dim}<dependencyManagement>${Logger.C.reset}`);
91
+ Logger.log(` ${Logger.C.dim} <dependencies>${Logger.C.reset}`);
92
+ Logger.log(` ${Logger.C.dim} <dependency>${Logger.C.reset}`);
93
+ Logger.log(` ${Logger.C.dim} <groupId>${conflict.groupId}</groupId>${Logger.C.reset}`);
94
+ Logger.log(` ${Logger.C.dim} <artifactId>${conflict.artifactId}</artifactId>${Logger.C.reset}`);
95
+ Logger.log(` ${Logger.C.dim} <version>${conflict.versions[conflict.versions.length - 1]}</version>${Logger.C.reset}`);
96
+ Logger.log(` ${Logger.C.dim} </dependency>${Logger.C.reset}`);
97
+ Logger.log(` ${Logger.C.dim} </dependencies>${Logger.C.reset}`);
98
+ Logger.log(` ${Logger.C.dim}</dependencyManagement>${Logger.C.reset}`);
99
+ } else {
100
+ Logger.log(" Adicione ao build.gradle:");
101
+ Logger.log(` ${Logger.C.dim}implementation("${conflict.groupId}:${conflict.artifactId}:${conflict.versions[conflict.versions.length - 1]}")${Logger.C.reset}`);
102
+ }
103
+ }
104
+ }
105
+
106
+ private exportReport(
107
+ result: DependencyAnalysisResult,
108
+ outputPath: string
109
+ ): void {
110
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../../package.json"), "utf-8"));
111
+ const data = {
112
+ timestamp: new Date().toISOString(),
113
+ tool: "xavva",
114
+ version: pkg.version,
115
+ result
116
+ };
117
+
118
+ fs.writeFileSync(outputPath, JSON.stringify(data, null, 2));
119
+ Logger.success(`Relatório exportado para: ${outputPath}`);
120
+ }
121
+ }
122
+
123
+ import path from "path";
@@ -1,11 +1,12 @@
1
1
  import type { Command } from "./Command";
2
- import type { AppConfig } from "../types/config";
2
+ import type { AppConfig, CLIArguments } from "../types/config";
3
3
  import { Logger } from "../utils/ui";
4
4
  import fs from "fs";
5
5
  import path from "path";
6
+ import os from "os";
6
7
 
7
8
  export class DoctorCommand implements Command {
8
- async execute(config: AppConfig, values: any = {}): Promise<void> {
9
+ async execute(config: AppConfig, values: CLIArguments = {}): Promise<void> {
9
10
  Logger.section("Xavva Doctor - Ambiente");
10
11
 
11
12
  this.check(
@@ -252,7 +253,7 @@ export class DoctorCommand implements Command {
252
253
 
253
254
  // URL para o JetBrains Runtime 21 SDK Windows x64
254
255
  const url = "https://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.6-windows-x64-b895.97.tar.gz";
255
- const installDir = path.join(require("os").homedir(), ".xavva", "jdk-dcevm");
256
+ const installDir = path.join(os.homedir(), ".xavva", "jdk-dcevm");
256
257
 
257
258
  // Limpar instalação anterior se existir
258
259
  if (fs.existsSync(installDir)) {
@@ -344,7 +345,7 @@ export class DoctorCommand implements Command {
344
345
 
345
346
  Logger.newline();
346
347
  Logger.warn("IMPORTANTE: Reinicie seu terminal (ou o VS Code) para as mudanças surtirem efeito.");
347
- } catch (e: any) {
348
+ } catch (e) {
348
349
 
349
350
  Logger.error(`Falha na instalação: ${e.message}`);
350
351
  }
@@ -4,46 +4,100 @@ import pkg from "../../package.json";
4
4
 
5
5
  export class HelpCommand implements Command {
6
6
  async execute(_config: AppConfig, _args?: CLIArguments): Promise<void> {
7
+ const version = pkg.version;
8
+
7
9
  console.log(`
8
- 🛠️ XAVVA CLI v${pkg.version} 🚀
9
- ---------------------------------------
10
- Automatização de alta performance para Java Enterprise (Tomcat) no Windows.
11
- Detecta automaticamente Maven/Gradle e otimiza o ciclo de desenvolvimento.
12
-
13
- Comandos principais:
14
- dev 🚀 MODO COMPLETO: Build + Deploy + Watch + Debug.
15
- deploy (Padrão) Compila, sincroniza e inicia o servidor.
16
- logs 📋 Tail inteligente (catalina.out) com Smart Folding.
17
- run / debug 🚀 Executa classes standalone com Pathing JAR (Windows).
18
- doctor 🩺 Diagnóstico e reparo de ambiente (DCEVM, JAVA_HOME).
19
- audit 🛡️ Auditoria de segurança em JARs via OSV.dev.
20
- profiles 🏷️ Lista perfis de build disponíveis (Maven Profiles).
21
- docs 📖 Mapeamento estático de Endpoints e JSPs.
22
- build / start Comandos granulares de compilação ou startup.
23
-
24
- Opções de Interface:
25
- --tui 🖥️ Ativa o Dashboard Interativo (Interface TUI).
26
- No modo TUI use: [R] Restart, [L] Clear, [Q] Quit.
27
- -w, --watch 👀 Hot Reload: Redeploy incremental de classes e recursos.
28
- -c, --clean 🧹 Logs coloridos e simplificados (Recomendado).
29
- -V, --verbose 📣 Exibe logs completos do Maven/Gradle.
30
-
31
- Opções de Runtime:
32
- -d, --debug 🐞 Habilita JPDA Debugging (Porta 5005).
33
- -P, --profile Define o profile de build (ex: -P prod).
34
- -s, --no-build Pula o build inicial.
35
- --fix 🔧 Corrige problemas automaticamente (Doctor).
36
-
37
- Configuração:
38
- O Xavva prioriza o arquivo 'xavva.json' na raiz do projeto.
39
- Flags de linha de comando: -p (Tomcat Path), -t (Build Tool), -n (WAR Name).
40
-
41
- Exemplos:
42
- xavva dev --tui Experiência completa com Dashboard.
43
- xavva run MyClass Execução standalone com classpath automático.
44
- xavva audit Verifica vulnerabilidades conhecidas.
45
-
46
- *Transformando o legado em produtivo.*
47
- `);
10
+ ${this.c("cyan", "▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓")}
11
+ ${this.c("cyan", "▓")} ${this.c("cyan", "▓")}
12
+ ${this.c("cyan", "▓")} ${this.c("bold", "XAVVA")} ${this.c("dim", `v${version}`)} ${this.c("gray", "— Java/Tomcat Dev CLI")} ${this.c("cyan", "▓")}
13
+ ${this.c("cyan", "▓")} ${this.c("cyan", "▓")}
14
+ ${this.c("cyan", "▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓")}
15
+
16
+ ${this.c("yellow", "USAGE")}
17
+ xavva <command> [options]
18
+
19
+ ${this.c("yellow", "COMMANDS")}
20
+ ${this.c("green", "dev")} Start development mode (build + deploy + watch)
21
+ ${this.c("green", "deploy")} Build and deploy to Tomcat (default)
22
+ ${this.c("green", "build")} Compile project only
23
+ ${this.c("green", "start")} Start Tomcat server only
24
+ ${this.c("green", "run")} <class> Run a Java class with automatic classpath
25
+ ${this.c("green", "debug")} <class> Debug a Java class (port 5005)
26
+ ${this.c("green", "logs")} Stream and analyze Tomcat logs
27
+ ${this.c("green", "deps")} Analyze dependencies (conflicts, updates)
28
+ ${this.c("green", "audit")} Security audit of JAR files
29
+ ${this.c("green", "doctor")} Diagnose and fix environment issues
30
+ ${this.c("green", "profiles")} List available Maven/Gradle profiles
31
+ ${this.c("green", "docs")} Generate endpoint documentation
32
+
33
+ ${this.c("yellow", "OPTIONS")}
34
+ ${this.c("cyan", "-p, --path")} <path> Tomcat installation path
35
+ ${this.c("cyan", "-t, --tool")} <tool> Build tool: maven | gradle
36
+ ${this.c("cyan", "-n, --name")} <name> Application name (WAR context)
37
+ ${this.c("cyan", "--port")} <port> Tomcat port (default: 8080)
38
+ ${this.c("cyan", "-P, --profile")} <prof> Maven/Gradle profile
39
+ ${this.c("cyan", "-e, --encoding")} <enc> Source encoding (utf8, cp1252)
40
+
41
+ ${this.c("cyan", "-w, --watch")} Enable file watching (hot reload)
42
+ ${this.c("cyan", "--tui")} Interactive dashboard mode
43
+ ${this.c("cyan", "-d, --debug")} Enable JPDA debugger
44
+ ${this.c("cyan", "--dp")} <port> Debugger port (default: 5005)
45
+
46
+ ${this.c("cyan", "-c, --clean")} Clean logs before start
47
+ ${this.c("cyan", "-s, --no-build")} Skip initial build
48
+ ${this.c("cyan", "-q, --quiet")} Minimal output
49
+ ${this.c("cyan", "-V, --verbose")} Detailed output
50
+ ${this.c("cyan", "-h, --help")} Show this help
51
+ ${this.c("cyan", "-v, --version")} Show version
52
+
53
+ ${this.c("yellow", "EXAMPLES")}
54
+ ${this.c("dim", "# Development with hot reload and dashboard")}
55
+ xavva dev --tui --watch
56
+
57
+ ${this.c("dim", "# Quick deploy to specific Tomcat")}
58
+ xavva deploy -p /opt/tomcat --port 8081
59
+
60
+ ${this.c("dim", "# Run a class with debugging")}
61
+ xavva debug com.example.MyClass
62
+
63
+ ${this.c("dim", "# Analyze dependencies for conflicts")}
64
+ xavva deps --verbose
65
+
66
+ ${this.c("dim", "# Security audit with auto-fix suggestions")}
67
+ xavva audit --fix
68
+
69
+ ${this.c("yellow", "CONFIGURATION")}
70
+ Settings are loaded from ${this.c("cyan", "xavva.json")} in the project root:
71
+
72
+ ${this.c("dim", `{
73
+ "project": {
74
+ "appName": "my-app",
75
+ "buildTool": "maven",
76
+ "tui": true
77
+ },
78
+ "tomcat": {
79
+ "path": "C:/apache-tomcat",
80
+ "port": 8080
81
+ }
82
+ }`)}
83
+
84
+ ${this.c("gray", "────────────────────────────────────────────────────────────")}
85
+ ${this.c("gray", "Docs: github.com/leorsousa05/Xavva | License: MIT")}
86
+ `);
87
+ }
88
+
89
+ private c(color: string, text: string): string {
90
+ const colors: Record<string, string> = {
91
+ reset: "\x1b[0m",
92
+ bold: "\x1b[1m",
93
+ dim: "\x1b[2m",
94
+ gray: "\x1b[90m",
95
+ red: "\x1b[31m",
96
+ green: "\x1b[32m",
97
+ yellow: "\x1b[33m",
98
+ blue: "\x1b[34m",
99
+ cyan: "\x1b[36m",
100
+ };
101
+ return `${colors[color] || ""}${text}\x1b[0m`;
48
102
  }
49
103
  }