kaven-cli 0.4.0 → 0.4.2-alpha.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.
Files changed (57) hide show
  1. package/README.md +181 -207
  2. package/dist/EnvManager-NMS3NMIE.js +15 -0
  3. package/dist/MarketplaceClient-YCFH2VU4.js +1 -0
  4. package/dist/chunk-JHLQ46NG.js +1 -0
  5. package/dist/index.d.ts +4 -0
  6. package/dist/index.js +243 -289
  7. package/dist/tier-table-DQMPQSI2.js +6 -0
  8. package/package.json +26 -10
  9. package/dist/commands/auth/login.js +0 -122
  10. package/dist/commands/auth/logout.js +0 -23
  11. package/dist/commands/auth/whoami.js +0 -36
  12. package/dist/commands/cache/index.js +0 -43
  13. package/dist/commands/config/features.js +0 -1026
  14. package/dist/commands/config/index.js +0 -95
  15. package/dist/commands/index.js +0 -2
  16. package/dist/commands/init/index.js +0 -197
  17. package/dist/commands/init-ci/index.js +0 -153
  18. package/dist/commands/license/index.js +0 -10
  19. package/dist/commands/license/status.js +0 -44
  20. package/dist/commands/license/tier-table.js +0 -46
  21. package/dist/commands/marketplace/browse.js +0 -186
  22. package/dist/commands/marketplace/install.js +0 -263
  23. package/dist/commands/marketplace/list.js +0 -122
  24. package/dist/commands/module/activate.js +0 -206
  25. package/dist/commands/module/add.js +0 -69
  26. package/dist/commands/module/doctor.js +0 -175
  27. package/dist/commands/module/publish.js +0 -258
  28. package/dist/commands/module/remove.js +0 -58
  29. package/dist/commands/telemetry/view.js +0 -27
  30. package/dist/commands/upgrade/check.js +0 -162
  31. package/dist/commands/upgrade/index.js +0 -185
  32. package/dist/core/AuthService.js +0 -222
  33. package/dist/core/CacheManager.js +0 -154
  34. package/dist/core/ConfigManager.js +0 -166
  35. package/dist/core/EnvManager.js +0 -196
  36. package/dist/core/ErrorRecovery.js +0 -192
  37. package/dist/core/LicenseService.js +0 -83
  38. package/dist/core/ManifestParser.js +0 -52
  39. package/dist/core/MarkerService.js +0 -62
  40. package/dist/core/ModuleDoctor.js +0 -451
  41. package/dist/core/ModuleInstaller.js +0 -169
  42. package/dist/core/ProjectInitializer.js +0 -166
  43. package/dist/core/RegistryResolver.js +0 -95
  44. package/dist/core/SchemaActivator.js +0 -270
  45. package/dist/core/ScriptRunner.js +0 -73
  46. package/dist/core/SignatureVerifier.js +0 -75
  47. package/dist/core/index.js +0 -2
  48. package/dist/infrastructure/Container.js +0 -37
  49. package/dist/infrastructure/MarketplaceClient.js +0 -399
  50. package/dist/infrastructure/TelemetryBuffer.js +0 -73
  51. package/dist/infrastructure/TransactionalFileSystem.js +0 -77
  52. package/dist/infrastructure/errors.js +0 -63
  53. package/dist/infrastructure/index.js +0 -2
  54. package/dist/types/auth.js +0 -2
  55. package/dist/types/manifest.js +0 -45
  56. package/dist/types/markers.js +0 -10
  57. package/dist/types/marketplace.js +0 -2
@@ -1,206 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.moduleActivate = moduleActivate;
7
- exports.moduleDeactivate = moduleDeactivate;
8
- exports.moduleListActivation = moduleListActivation;
9
- const chalk_1 = __importDefault(require("chalk"));
10
- const ora_1 = __importDefault(require("ora"));
11
- const node_path_1 = __importDefault(require("node:path"));
12
- const SchemaActivator_1 = require("../../core/SchemaActivator");
13
- const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
14
- // ============================================================
15
- // Helpers
16
- // ============================================================
17
- function findModuleDef(moduleId) {
18
- return SchemaActivator_1.KAVEN_MODULES.find((m) => m.id === moduleId.toLowerCase());
19
- }
20
- function assertSchemaExists(exists, root) {
21
- if (!exists) {
22
- const fullPath = node_path_1.default.join(root, "packages", "database", "prisma", "schema.extended.prisma");
23
- console.error(chalk_1.default.red(`\nErro: Schema não encontrado em: ${fullPath}`));
24
- console.error(chalk_1.default.gray("Certifique-se de que o caminho fornecido é a raiz de um projeto Kaven válido."));
25
- process.exit(1);
26
- }
27
- }
28
- // ============================================================
29
- // kaven module activate <name>
30
- // ============================================================
31
- async function moduleActivate(moduleName, projectRoot) {
32
- const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
33
- const startTime = Date.now();
34
- telemetry.capture("cli.module.activate.start", { moduleName });
35
- const root = projectRoot ?? process.cwd();
36
- const activator = new SchemaActivator_1.SchemaActivator(root);
37
- const spinner = (0, ora_1.default)(`Ativando módulo ${moduleName}...`).start();
38
- try {
39
- // 1. Validar que o schema existe
40
- const exists = await activator.exists();
41
- spinner.stop();
42
- assertSchemaExists(exists, root);
43
- // 2. Validar que o módulo é conhecido
44
- const def = findModuleDef(moduleName);
45
- if (!def) {
46
- console.error(chalk_1.default.red(`\nMódulo desconhecido: "${moduleName}".`));
47
- console.error(chalk_1.default.gray(`Módulos disponíveis: ${SchemaActivator_1.KAVEN_MODULES.map((m) => m.id).join(", ")}`));
48
- process.exit(1);
49
- }
50
- // 3. Verificar dependências
51
- if (def.dependsOn.length > 0) {
52
- spinner.start("Verificando dependências...");
53
- const depStatuses = [];
54
- for (const depId of def.dependsOn) {
55
- const depDef = findModuleDef(depId);
56
- if (!depDef)
57
- continue;
58
- const status = await activator.getModuleStatus(depDef);
59
- depStatuses.push(status);
60
- }
61
- const missing = depStatuses.filter((s) => !s.active);
62
- if (missing.length > 0) {
63
- spinner.stop();
64
- console.error(chalk_1.default.red(`\nDependências inativas para "${moduleName}": ${missing.map((m) => m.id).join(", ")}`));
65
- console.error(chalk_1.default.gray(`Ative as dependências primeiro:\n${missing.map((m) => ` kaven module activate ${m.id}`).join("\n")}`));
66
- process.exit(1);
67
- }
68
- spinner.stop();
69
- }
70
- // 4. Verificar se já está ativo
71
- const current = await activator.getModuleStatus(def);
72
- if (current.active) {
73
- console.log(chalk_1.default.yellow(`\nMódulo "${def.label}" já está ativo.`));
74
- return;
75
- }
76
- // 5. Ativar
77
- spinner.start(`Descomentando modelos de ${def.label} no schema...`);
78
- await activator.activateModule(def);
79
- spinner.succeed(chalk_1.default.green(`\nMódulo ${def.label} ativado. ${def.models.length} models adicionados: ${def.models.join(", ")}`));
80
- console.log(chalk_1.default.cyan("\nSugestão: Execute `pnpm db:generate && pnpm db:migrate` para aplicar as mudanças."));
81
- telemetry.capture("cli.module.activate.success", { moduleName: def.id, models: def.models.length }, Date.now() - startTime);
82
- await telemetry.flush();
83
- }
84
- catch (error) {
85
- spinner.fail(chalk_1.default.red(`Falha ao ativar módulo: ${error instanceof Error ? error.message : String(error)}`));
86
- telemetry.capture("cli.module.activate.error", { moduleName, error: error.message }, Date.now() - startTime);
87
- await telemetry.flush();
88
- process.exit(1);
89
- }
90
- }
91
- // ============================================================
92
- // kaven module deactivate <name>
93
- // ============================================================
94
- async function moduleDeactivate(moduleName, projectRoot) {
95
- const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
96
- const startTime = Date.now();
97
- telemetry.capture("cli.module.deactivate.start", { moduleName });
98
- const root = projectRoot ?? process.cwd();
99
- const activator = new SchemaActivator_1.SchemaActivator(root);
100
- const spinner = (0, ora_1.default)(`Desativando módulo ${moduleName}...`).start();
101
- try {
102
- // 1. Validar que o schema existe
103
- const exists = await activator.exists();
104
- spinner.stop();
105
- assertSchemaExists(exists, root);
106
- // 2. Validar módulo
107
- const def = findModuleDef(moduleName);
108
- if (!def) {
109
- console.error(chalk_1.default.red(`\nMódulo desconhecido: "${moduleName}".`));
110
- console.error(chalk_1.default.gray(`Módulos disponíveis: ${SchemaActivator_1.KAVEN_MODULES.map((m) => m.id).join(", ")}`));
111
- process.exit(1);
112
- }
113
- // 3. Verificar se outros módulos ativos dependem deste
114
- spinner.start("Verificando dependências reversas...");
115
- const dependents = [];
116
- for (const candidate of SchemaActivator_1.KAVEN_MODULES) {
117
- if (candidate.id === def.id)
118
- continue;
119
- if (!candidate.dependsOn.includes(def.id))
120
- continue;
121
- const status = await activator.getModuleStatus(candidate);
122
- if (status.active) {
123
- dependents.push(candidate.id);
124
- }
125
- }
126
- if (dependents.length > 0) {
127
- spinner.stop();
128
- console.error(chalk_1.default.red(`\nNão é possível desativar "${moduleName}": os seguintes módulos dependem dele e estão ativos:`));
129
- console.error(chalk_1.default.gray(` ${dependents.join(", ")}`));
130
- console.error(chalk_1.default.gray(`Desative-os primeiro:\n${dependents.map((d) => ` kaven module deactivate ${d}`).join("\n")}`));
131
- process.exit(1);
132
- }
133
- // 4. Verificar se já está inativo
134
- const current = await activator.getModuleStatus(def);
135
- if (!current.active) {
136
- spinner.stop();
137
- console.log(chalk_1.default.yellow(`\nMódulo "${def.label}" já está inativo.`));
138
- return;
139
- }
140
- // 5. Desativar
141
- spinner.start(`Comentando modelos de ${def.label} no schema...`);
142
- await activator.deactivateModule(def);
143
- spinner.succeed(chalk_1.default.green(`\nMódulo ${def.label} desativado com sucesso.`));
144
- console.log(chalk_1.default.cyan("\nSugestão: Execute `pnpm db:generate && pnpm db:migrate` para aplicar as mudanças."));
145
- telemetry.capture("cli.module.deactivate.success", { moduleName: def.id }, Date.now() - startTime);
146
- await telemetry.flush();
147
- }
148
- catch (error) {
149
- spinner.fail(chalk_1.default.red(`Falha ao desativar módulo: ${error instanceof Error ? error.message : String(error)}`));
150
- telemetry.capture("cli.module.deactivate.error", { moduleName, error: error.message }, Date.now() - startTime);
151
- await telemetry.flush();
152
- process.exit(1);
153
- }
154
- }
155
- // ============================================================
156
- // kaven module list
157
- // ============================================================
158
- async function moduleListActivation(projectRoot) {
159
- const root = projectRoot ?? process.cwd();
160
- const activator = new SchemaActivator_1.SchemaActivator(root);
161
- const schemaExists = await activator.exists();
162
- // Cabeçalho da tabela
163
- const COL = {
164
- module: 14,
165
- status: 10,
166
- models: 44,
167
- deps: 20,
168
- };
169
- const header = chalk_1.default.bold("Module".padEnd(COL.module)) +
170
- chalk_1.default.bold("Status".padEnd(COL.status)) +
171
- chalk_1.default.bold("Models".padEnd(COL.models)) +
172
- chalk_1.default.bold("Depends on");
173
- const divider = "─".repeat(COL.module + COL.status + COL.models + COL.deps);
174
- console.log();
175
- console.log(chalk_1.default.blue("Módulos Kaven disponíveis\n"));
176
- console.log(header);
177
- console.log(chalk_1.default.gray(divider));
178
- if (!schemaExists) {
179
- for (const def of SchemaActivator_1.KAVEN_MODULES) {
180
- const modCol = def.id.padEnd(COL.module);
181
- const statusCol = chalk_1.default.gray("unknown".padEnd(COL.status));
182
- const modelsCol = def.models.join(", ").padEnd(COL.models);
183
- const depsCol = def.dependsOn.length > 0 ? def.dependsOn.join(", ") : "—";
184
- console.log(`${modCol}${statusCol}${modelsCol}${depsCol}`);
185
- }
186
- console.log();
187
- console.log(chalk_1.default.yellow("Atenção: schema.extended.prisma não encontrado. Status não pode ser determinado."));
188
- console.log(chalk_1.default.gray("Execute este comando na raiz de um projeto Kaven para ver o status real."));
189
- return;
190
- }
191
- for (const def of SchemaActivator_1.KAVEN_MODULES) {
192
- const status = await activator.getModuleStatus(def);
193
- const modCol = def.id.padEnd(COL.module);
194
- const statusText = status.active ? "active" : "inactive";
195
- const statusColored = status.active
196
- ? chalk_1.default.green(statusText.padEnd(COL.status))
197
- : chalk_1.default.gray(statusText.padEnd(COL.status));
198
- const modelsCol = def.models.join(", ").padEnd(COL.models);
199
- const depsCol = def.dependsOn.length > 0 ? def.dependsOn.join(", ") : "—";
200
- console.log(`${modCol}${statusColored}${modelsCol}${depsCol}`);
201
- }
202
- console.log();
203
- console.log(chalk_1.default.gray("Core (sempre ativo): Tenant, User, Role, Capability, AuthSession, AuditLog"));
204
- console.log();
205
- console.log(chalk_1.default.gray("Para ativar: kaven module activate <name> | Para desativar: kaven module deactivate <name>"));
206
- }
@@ -1,69 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.moduleAdd = moduleAdd;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const ora_1 = __importDefault(require("ora"));
9
- const path_1 = __importDefault(require("path"));
10
- const fs_extra_1 = __importDefault(require("fs-extra"));
11
- const ModuleInstaller_1 = require("../../core/ModuleInstaller");
12
- const MarkerService_1 = require("../../core/MarkerService");
13
- const ManifestParser_1 = require("../../core/ManifestParser");
14
- const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
15
- async function moduleAdd(manifestPath, projectRoot) {
16
- const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
17
- const startTime = Date.now();
18
- telemetry.capture("cli.module.add.start", { manifestPath });
19
- const root = projectRoot || process.cwd();
20
- const spinner = (0, ora_1.default)("Preparando instalação do módulo...").start();
21
- try {
22
- const markerService = new MarkerService_1.MarkerService();
23
- const manifestParser = new ManifestParser_1.ManifestParser();
24
- const installer = new ModuleInstaller_1.ModuleInstaller(root, markerService);
25
- // 1. Resolver caminho do manifest
26
- const absolutePath = path_1.default.isAbsolute(manifestPath)
27
- ? manifestPath
28
- : path_1.default.join(root, manifestPath);
29
- if (!(await fs_extra_1.default.pathExists(absolutePath))) {
30
- throw new Error(`Arquivo de manifest não encontrado: ${manifestPath}`);
31
- }
32
- // 2. Parse do manifest
33
- spinner.text = "Validando manifest...";
34
- const manifest = await manifestParser.parse(absolutePath);
35
- // 3. Instalar
36
- spinner.text = `Instalando ${manifest.name}@${manifest.version}...`;
37
- await installer.install(manifest);
38
- // 4. Atualizar kaven.json
39
- spinner.text = "Atualizando configuração do projeto...";
40
- await updateKavenConfig(root, manifest.name, manifest.version);
41
- // 5. Cache do manifest para desinstalação futura
42
- spinner.text = "Salvando cache do manifest...";
43
- const cacheDir = path_1.default.join(root, ".kaven", "modules", manifest.name);
44
- await fs_extra_1.default.ensureDir(cacheDir);
45
- await fs_extra_1.default.writeJson(path_1.default.join(cacheDir, "module.json"), manifest, {
46
- spaces: 2,
47
- });
48
- spinner.succeed(chalk_1.default.green(`Módulo ${manifest.name} instalado com sucesso!`));
49
- telemetry.capture("cli.module.add.success", { name: manifest.name }, Date.now() - startTime);
50
- await telemetry.flush();
51
- }
52
- catch (error) {
53
- telemetry.capture("cli.module.add.error", { error: error.message }, Date.now() - startTime);
54
- await telemetry.flush();
55
- spinner.fail(chalk_1.default.red(`Falha na instalação: ${error instanceof Error ? error.message : String(error)}`));
56
- process.exit(1);
57
- }
58
- }
59
- async function updateKavenConfig(projectRoot, name, version) {
60
- const configPath = path_1.default.join(projectRoot, "kaven.json");
61
- let config = { modules: {} };
62
- if (await fs_extra_1.default.pathExists(configPath)) {
63
- config = await fs_extra_1.default.readJson(configPath);
64
- }
65
- if (!config.modules)
66
- config.modules = {};
67
- config.modules[name] = version;
68
- await fs_extra_1.default.writeJson(configPath, config, { spaces: 2 });
69
- }
@@ -1,175 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.moduleDoctor = moduleDoctor;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const child_process_1 = require("child_process");
9
- const path_1 = __importDefault(require("path"));
10
- const fs_extra_1 = __importDefault(require("fs-extra"));
11
- const ModuleDoctor_1 = require("../../core/ModuleDoctor");
12
- const MarkerService_1 = require("../../core/MarkerService");
13
- const ManifestParser_1 = require("../../core/ManifestParser");
14
- function severityPrefix(severity) {
15
- switch (severity) {
16
- case "error":
17
- return chalk_1.default.red("[ERROR]");
18
- case "warning":
19
- return chalk_1.default.yellow("[WARN] ");
20
- case "info":
21
- return chalk_1.default.cyan("[INFO] ");
22
- default:
23
- return chalk_1.default.green("[OK] ");
24
- }
25
- }
26
- /** Attempt auto-fixes for fixable issues. */
27
- async function applyFixes(results, projectRoot) {
28
- const fixable = results.filter((r) => r.fixable);
29
- if (fixable.length === 0) {
30
- console.log(chalk_1.default.gray(" No automatically fixable issues found."));
31
- return;
32
- }
33
- for (const result of fixable) {
34
- const msg = result.message.toLowerCase();
35
- // Missing npm deps: run pnpm install
36
- if (msg.includes("missing npm dependency") || msg.includes("pnpm install")) {
37
- console.log(chalk_1.default.blue(` Fixing: ${result.message}`));
38
- try {
39
- (0, child_process_1.execSync)("pnpm install", { cwd: projectRoot, stdio: "inherit" });
40
- console.log(chalk_1.default.green(" ✓ pnpm install completed"));
41
- }
42
- catch {
43
- console.log(chalk_1.default.red(" ✗ pnpm install failed"));
44
- }
45
- continue;
46
- }
47
- // Stale Prisma: run prisma generate
48
- if (msg.includes("prisma")) {
49
- console.log(chalk_1.default.blue(` Fixing: ${result.message}`));
50
- try {
51
- (0, child_process_1.execSync)("npx prisma generate", { cwd: projectRoot, stdio: "inherit" });
52
- console.log(chalk_1.default.green(" ✓ npx prisma generate completed"));
53
- }
54
- catch {
55
- console.log(chalk_1.default.red(" ✗ npx prisma generate failed"));
56
- }
57
- continue;
58
- }
59
- // Missing env vars: append placeholder
60
- if (msg.includes("missing env vars") && result.file === ".env") {
61
- const envPath = path_1.default.join(projectRoot, ".env");
62
- const envExamplePath = path_1.default.join(projectRoot, ".env.example");
63
- console.log(chalk_1.default.blue(` Fixing: ${result.message}`));
64
- try {
65
- const exampleContent = await fs_extra_1.default.readFile(envExamplePath, "utf-8");
66
- const envContent = (await fs_extra_1.default.pathExists(envPath))
67
- ? await fs_extra_1.default.readFile(envPath, "utf-8")
68
- : "";
69
- const parseKeys = (content) => {
70
- const keys = new Set();
71
- for (const line of content.split("\n")) {
72
- const trimmed = line.trim();
73
- if (trimmed.startsWith("#") || !trimmed.includes("="))
74
- continue;
75
- const key = trimmed.split("=")[0].trim();
76
- if (key)
77
- keys.add(key);
78
- }
79
- return keys;
80
- };
81
- const exampleKeys = parseKeys(exampleContent);
82
- const envKeys = parseKeys(envContent);
83
- let appendContent = "\n# Added by kaven doctor --fix\n";
84
- for (const key of exampleKeys) {
85
- if (!envKeys.has(key)) {
86
- appendContent += `${key}=PLACEHOLDER\n`;
87
- }
88
- }
89
- await fs_extra_1.default.appendFile(envPath, appendContent);
90
- console.log(chalk_1.default.green(" ✓ Placeholder env vars appended to .env"));
91
- }
92
- catch {
93
- console.log(chalk_1.default.red(" ✗ Could not append env vars"));
94
- }
95
- continue;
96
- }
97
- // Generic fallback
98
- console.log(chalk_1.default.yellow(` Manual action required: ${result.message}`));
99
- }
100
- }
101
- async function moduleDoctor(options) {
102
- if (!options.json) {
103
- console.log(chalk_1.default.blue("Running module doctor...\n"));
104
- }
105
- const markerService = new MarkerService_1.MarkerService();
106
- const manifestParser = new ManifestParser_1.ManifestParser();
107
- const doctor = new ModuleDoctor_1.ModuleDoctor(process.cwd(), markerService, manifestParser);
108
- let results = [];
109
- try {
110
- results = await doctor.checkAll();
111
- }
112
- catch (error) {
113
- if (options.json) {
114
- console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error), results: [] }));
115
- }
116
- else {
117
- console.error(chalk_1.default.red(`[ERROR] Heavy failure during doctor audit: ${error instanceof Error ? error.message : String(error)}`));
118
- }
119
- process.exit(1);
120
- return;
121
- }
122
- // JSON output mode
123
- if (options.json) {
124
- const errors = results.filter((r) => r.severity === "error");
125
- const warnings = results.filter((r) => r.severity === "warning");
126
- console.log(JSON.stringify({
127
- success: errors.length === 0,
128
- errors: errors.length,
129
- warnings: warnings.length,
130
- results,
131
- }, null, 2));
132
- process.exit(errors.length > 0 ? 1 : warnings.length > 0 ? 2 : 0);
133
- return;
134
- }
135
- // Human-readable output
136
- for (const result of results) {
137
- const prefix = severityPrefix(result.severity);
138
- console.log(`${prefix} ${result.message}`);
139
- if (result.file) {
140
- console.log(chalk_1.default.gray(` file: ${result.file}`));
141
- }
142
- if (result.fixable && !options.fix) {
143
- console.log(chalk_1.default.gray(` (fixable: run with --fix)`));
144
- }
145
- }
146
- const errors = results.filter((r) => r.severity === "error");
147
- const warnings = results.filter((r) => r.severity === "warning");
148
- console.log();
149
- if (errors.length === 0 && warnings.length === 0) {
150
- console.log(chalk_1.default.green("[OK] All checks passed! Your project is healthy."));
151
- }
152
- else {
153
- if (errors.length > 0) {
154
- console.log(chalk_1.default.red(`[ERROR] Found ${errors.length} error(s)`));
155
- }
156
- if (warnings.length > 0) {
157
- console.log(chalk_1.default.yellow(`[WARN] Found ${warnings.length} warning(s)`));
158
- }
159
- if (!options.fix) {
160
- console.log(chalk_1.default.gray("\nTip: Run with --fix to attempt automatic repairs"));
161
- console.log(chalk_1.default.gray("Try: kaven module doctor --fix"));
162
- }
163
- }
164
- if (options.fix) {
165
- console.log();
166
- console.log(chalk_1.default.blue("Applying auto-fixes...\n"));
167
- await applyFixes(results, process.cwd());
168
- console.log(chalk_1.default.green("\nAuto-fix completed."));
169
- }
170
- // Exit codes: 0=all pass, 1=errors, 2=warnings only
171
- if (errors.length > 0)
172
- process.exit(1);
173
- if (warnings.length > 0)
174
- process.exit(2);
175
- }