specatlas 0.1.38 → 0.1.39
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/dist/bin.js +231 -54
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -36820,6 +36820,103 @@ function msg(key, language) {
|
|
|
36820
36820
|
return dict[key] ?? key;
|
|
36821
36821
|
}
|
|
36822
36822
|
|
|
36823
|
+
// src/ui.ts
|
|
36824
|
+
var CODIGOS = {
|
|
36825
|
+
rojo: [31, 39],
|
|
36826
|
+
verde: [32, 39],
|
|
36827
|
+
amarillo: [33, 39],
|
|
36828
|
+
azul: [34, 39],
|
|
36829
|
+
morado: [35, 39],
|
|
36830
|
+
cian: [36, 39],
|
|
36831
|
+
gris: [90, 39],
|
|
36832
|
+
negrita: [1, 22],
|
|
36833
|
+
atenuado: [2, 22],
|
|
36834
|
+
subrayado: [4, 24],
|
|
36835
|
+
inverso: [7, 27]
|
|
36836
|
+
};
|
|
36837
|
+
function detectarTema(env = process.env, salida = process.stdout) {
|
|
36838
|
+
const forzado = env["FORCE_COLOR"];
|
|
36839
|
+
const color = forzado !== void 0 && forzado !== "0" ? true : env["NO_COLOR"] !== void 0 || env["TERM"] === "dumb" || salida.isTTY !== true ? false : true;
|
|
36840
|
+
const unicode = env["SPECATLAS_ASCII"] === "1" ? false : process.platform !== "win32" || Boolean(env["WT_SESSION"] || env["TERM_PROGRAM"] || env["ConEmuANSI"] || env["TERM"]);
|
|
36841
|
+
const ancho = Math.max(40, Math.min(salida.columns ?? 100, 120));
|
|
36842
|
+
return { color, unicode, ancho };
|
|
36843
|
+
}
|
|
36844
|
+
function pinta(tema, estilo, texto) {
|
|
36845
|
+
if (!tema.color || texto === "") return texto;
|
|
36846
|
+
const estilos = Array.isArray(estilo) ? estilo : [estilo];
|
|
36847
|
+
return estilos.reduce((acc, uno) => {
|
|
36848
|
+
const [abre, cierra] = CODIGOS[uno];
|
|
36849
|
+
return `\x1B[${abre}m${acc}\x1B[${cierra}m`;
|
|
36850
|
+
}, texto);
|
|
36851
|
+
}
|
|
36852
|
+
var UNICODE = { ok: "\u2713", error: "\u2716", aviso: "\u25B2", info: "\u2139", flecha: "\u2192", punto: "\u25CF", bloqueo: "\u2298", pausa: "\u23F8", lleno: "\u25B0", vacio: "\u25B1", separador: "\xB7" };
|
|
36853
|
+
var ASCII = { ok: "v", error: "x", aviso: "!", info: "i", flecha: "->", punto: "*", bloqueo: "o", pausa: "||", lleno: "#", vacio: "-", separador: "-" };
|
|
36854
|
+
function simbolos(tema) {
|
|
36855
|
+
return tema.unicode ? UNICODE : ASCII;
|
|
36856
|
+
}
|
|
36857
|
+
function anchoVisible(texto) {
|
|
36858
|
+
return texto.replace(/\u001b\[[0-9;]*m/g, "").length;
|
|
36859
|
+
}
|
|
36860
|
+
function rellenar(texto, ancho) {
|
|
36861
|
+
const falta = ancho - anchoVisible(texto);
|
|
36862
|
+
return falta > 0 ? texto + " ".repeat(falta) : texto;
|
|
36863
|
+
}
|
|
36864
|
+
function encabezado(tema, titulo, contexto) {
|
|
36865
|
+
const izquierda = pinta(tema, "negrita", titulo);
|
|
36866
|
+
if (!contexto) return [izquierda, ""];
|
|
36867
|
+
const hueco = tema.ancho - anchoVisible(izquierda) - anchoVisible(contexto);
|
|
36868
|
+
if (hueco < 2) return [izquierda, pinta(tema, "gris", contexto), ""];
|
|
36869
|
+
return [`${izquierda}${" ".repeat(hueco)}${pinta(tema, "gris", contexto)}`, ""];
|
|
36870
|
+
}
|
|
36871
|
+
function barraProgreso(tema, hecho, total, ancho = 8) {
|
|
36872
|
+
const s = simbolos(tema);
|
|
36873
|
+
if (total <= 0) return pinta(tema, "gris", `${s.vacio.repeat(ancho)} 0/0`);
|
|
36874
|
+
const llenos = Math.max(0, Math.min(ancho, Math.round(hecho / total * ancho)));
|
|
36875
|
+
const completo = hecho >= total;
|
|
36876
|
+
const barra = `${s.lleno.repeat(llenos)}${s.vacio.repeat(ancho - llenos)}`;
|
|
36877
|
+
return `${pinta(tema, completo ? "verde" : "azul", barra)} ${hecho}/${total}`;
|
|
36878
|
+
}
|
|
36879
|
+
function marcaSeveridad(tema, severidad) {
|
|
36880
|
+
const s = simbolos(tema);
|
|
36881
|
+
if (severidad === "error") return pinta(tema, "rojo", s.error);
|
|
36882
|
+
if (severidad === "warning") return pinta(tema, "amarillo", s.aviso);
|
|
36883
|
+
return pinta(tema, "azul", s.info);
|
|
36884
|
+
}
|
|
36885
|
+
function formatearDiagnostico(tema, d, rutaRelativa) {
|
|
36886
|
+
const s = simbolos(tema);
|
|
36887
|
+
const ubicacion = rutaRelativa ? pinta(tema, "gris", `${rutaRelativa}${d.line ? `:${d.line}` : ""}`) : "";
|
|
36888
|
+
const codigo = pinta(tema, d.severity === "error" ? ["rojo", "negrita"] : d.severity === "warning" ? ["amarillo", "negrita"] : ["azul", "negrita"], d.code);
|
|
36889
|
+
const cabeza = [` ${marcaSeveridad(tema, d.severity)} ${codigo}`, ubicacion].filter((parte) => parte !== "").join(" ");
|
|
36890
|
+
const lineas = [cabeza, ` ${d.message}`];
|
|
36891
|
+
if (d.suggestion) lineas.push(pinta(tema, "gris", ` ${s.flecha} ${d.suggestion}`));
|
|
36892
|
+
return lineas;
|
|
36893
|
+
}
|
|
36894
|
+
function resumenHallazgos(tema, counts) {
|
|
36895
|
+
const s = simbolos(tema);
|
|
36896
|
+
if (counts.errors === 0 && counts.warnings === 0 && counts.infos === 0) return "";
|
|
36897
|
+
const partes = [];
|
|
36898
|
+
if (counts.errors > 0) partes.push(pinta(tema, "rojo", `${s.error} ${counts.errors} ${counts.errors === 1 ? "error" : "errores"}`));
|
|
36899
|
+
if (counts.warnings > 0) partes.push(pinta(tema, "amarillo", `${s.aviso} ${counts.warnings} ${counts.warnings === 1 ? "aviso" : "avisos"}`));
|
|
36900
|
+
if (counts.infos > 0) partes.push(pinta(tema, "azul", `${s.info} ${counts.infos} ${counts.infos === 1 ? "nota" : "notas"}`));
|
|
36901
|
+
return ` ${partes.join(pinta(tema, "gris", ` ${s.separador} `))}`;
|
|
36902
|
+
}
|
|
36903
|
+
function exito(tema, texto) {
|
|
36904
|
+
return ` ${pinta(tema, "verde", simbolos(tema).ok)} ${texto}`;
|
|
36905
|
+
}
|
|
36906
|
+
function siguienteAccion(tema, comando, descripcion) {
|
|
36907
|
+
const s = simbolos(tema);
|
|
36908
|
+
const lineas = [` ${pinta(tema, "cian", s.flecha)} ${pinta(tema, ["cian", "negrita"], comando)}`];
|
|
36909
|
+
if (descripcion) lineas.push(pinta(tema, "gris", ` ${descripcion}`));
|
|
36910
|
+
return lineas;
|
|
36911
|
+
}
|
|
36912
|
+
function filaAlineada(columnas, separacion = 2) {
|
|
36913
|
+
return columnas.map((columna, indice) => indice === columnas.length - 1 || columna.ancho === void 0 ? columna.texto : rellenar(columna.texto, columna.ancho)).join(" ".repeat(separacion));
|
|
36914
|
+
}
|
|
36915
|
+
function seccion(tema, titulo, detalle) {
|
|
36916
|
+
const cabeza = pinta(tema, ["negrita"], titulo);
|
|
36917
|
+
return detalle ? `${cabeza} ${pinta(tema, "gris", detalle)}` : cabeza;
|
|
36918
|
+
}
|
|
36919
|
+
|
|
36823
36920
|
// src/version.ts
|
|
36824
36921
|
import { readFileSync } from "fs";
|
|
36825
36922
|
import { fileURLToPath } from "url";
|
|
@@ -37665,7 +37762,7 @@ async function runCi(ctx) {
|
|
|
37665
37762
|
}
|
|
37666
37763
|
const gate = await runCiGate({ root, strict, extra });
|
|
37667
37764
|
const diagnostics = [...gate.diagnostics];
|
|
37668
|
-
const lines =
|
|
37765
|
+
const lines = encabezado(detectarTema(), "Comprobaci\xF3n continua", strict ? "modo estricto" : void 0);
|
|
37669
37766
|
let sarifWritten;
|
|
37670
37767
|
if (sarifPath) {
|
|
37671
37768
|
const target = path38.resolve(ctx.cwd, sarifPath);
|
|
@@ -37681,13 +37778,18 @@ async function runCi(ctx) {
|
|
|
37681
37778
|
});
|
|
37682
37779
|
}
|
|
37683
37780
|
}
|
|
37781
|
+
const tema = detectarTema();
|
|
37782
|
+
const s = simbolos(tema);
|
|
37684
37783
|
for (const check of gate.checks) {
|
|
37685
|
-
const
|
|
37686
|
-
|
|
37784
|
+
const marca = check.errors > 0 ? pinta(tema, "rojo", s.error) : check.warnings > 0 ? pinta(tema, "amarillo", s.aviso) : pinta(tema, "verde", s.ok);
|
|
37785
|
+
const detalle = check.errors === 0 && check.warnings === 0 ? pinta(tema, "gris", "sin hallazgos") : [check.errors > 0 ? pinta(tema, "rojo", `${check.errors} ${check.errors === 1 ? "error" : "errores"}`) : "", check.warnings > 0 ? pinta(tema, "amarillo", `${check.warnings} ${check.warnings === 1 ? "aviso" : "avisos"}`) : ""].filter((parte) => parte !== "").join(pinta(tema, "gris", ` ${s.separador} `));
|
|
37786
|
+
lines.push(filaAlineada([{ texto: ` ${marca} ${check.name}`, ancho: 46 }, { texto: detalle }]));
|
|
37687
37787
|
}
|
|
37688
37788
|
lines.push("");
|
|
37689
|
-
lines.push(
|
|
37690
|
-
|
|
37789
|
+
lines.push(
|
|
37790
|
+
gate.failed ? ` ${pinta(tema, ["rojo", "negrita"], `${s.error} BLOQUEADO`)}${pinta(tema, "gris", " \u2014 resuelve los hallazgos antes de continuar")}` : ` ${pinta(tema, ["verde", "negrita"], `${s.ok} TODO EN ORDEN`)}`
|
|
37791
|
+
);
|
|
37792
|
+
if (strict) lines.push(pinta(tema, "gris", " (modo estricto: los avisos tambi\xE9n bloquean)"));
|
|
37691
37793
|
if (sarifPath) {
|
|
37692
37794
|
lines.push(sarifWritten ? `Informe SARIF: ${sarifWritten} (${gate.diagnostics.length} hallazgo(s))` : `Informe SARIF: no se pudo escribir en "${sarifPath}"`);
|
|
37693
37795
|
}
|
|
@@ -38072,7 +38174,7 @@ assumptions: []
|
|
|
38072
38174
|
}
|
|
38073
38175
|
|
|
38074
38176
|
// src/commands/doctor.ts
|
|
38075
|
-
import
|
|
38177
|
+
import "path";
|
|
38076
38178
|
async function runDoctorCommand(ctx) {
|
|
38077
38179
|
const { root, config } = await requireWorkspace(ctx);
|
|
38078
38180
|
const report = await runDoctor(root);
|
|
@@ -38092,17 +38194,10 @@ async function runDoctorCommand(ctx) {
|
|
|
38092
38194
|
const advisory = await upgradeAdvisory(root);
|
|
38093
38195
|
report.findings.push(...advisory.diagnostics);
|
|
38094
38196
|
report.summary = countBySeverity(report.findings);
|
|
38095
|
-
const
|
|
38197
|
+
const tema = detectarTema();
|
|
38198
|
+
const lines = encabezado(tema, msg("doctor.title", ctx.language));
|
|
38096
38199
|
if (report.findings.length === 0) {
|
|
38097
|
-
lines.push("
|
|
38098
|
-
} else {
|
|
38099
|
-
for (const finding of report.findings) {
|
|
38100
|
-
const location = finding.path ? ` ${path44.relative(ctx.cwd, finding.path)}${finding.line ? `:${finding.line}` : ""}` : "";
|
|
38101
|
-
lines.push(` ${finding.severity.toUpperCase()} ${finding.code}${location} \u2014 ${finding.message}`);
|
|
38102
|
-
if (finding.suggestion) lines.push(` \u21B3 ${finding.suggestion}`);
|
|
38103
|
-
}
|
|
38104
|
-
lines.push("");
|
|
38105
|
-
lines.push(`${report.summary.errors} errores, ${report.summary.warnings} avisos, ${report.summary.infos} notas`);
|
|
38200
|
+
lines.push(exito(tema, "El workspace est\xE1 sano."));
|
|
38106
38201
|
}
|
|
38107
38202
|
return {
|
|
38108
38203
|
exitCode: report.summary.errors > 0 ? 1 : 0,
|
|
@@ -39267,21 +39362,28 @@ async function runNext(ctx) {
|
|
|
39267
39362
|
text: [`\u25B6 ${action.command}`, "", ...outcome.result.text ?? []]
|
|
39268
39363
|
};
|
|
39269
39364
|
}
|
|
39270
|
-
const
|
|
39365
|
+
const tema = detectarTema();
|
|
39366
|
+
const s = simbolos(tema);
|
|
39367
|
+
const lines = encabezado(tema, msg("next.title", ctx.language));
|
|
39271
39368
|
const data = [];
|
|
39272
39369
|
let hasErrors2 = false;
|
|
39273
39370
|
for (const change of targets) {
|
|
39274
39371
|
const evaluation = await evaluateChange(workspace, config, change, approvals);
|
|
39275
39372
|
if (evaluation.blocking > 0) hasErrors2 = true;
|
|
39276
39373
|
const { state, nextAction, blockedBy } = evaluation.state;
|
|
39277
|
-
|
|
39278
|
-
lines.push(
|
|
39279
|
-
|
|
39280
|
-
|
|
39374
|
+
const actor = nextAction.requiresAgent ? pinta(tema, "azul", "con agente") : /^satlas (approve|archive|amend|pause|resume)/.test(nextAction.command) ? pinta(tema, "morado", "humana") : pinta(tema, "verde", "local");
|
|
39375
|
+
lines.push(
|
|
39376
|
+
filaAlineada([
|
|
39377
|
+
{ texto: ` ${pinta(tema, "negrita", change.slug)}`, ancho: 30 },
|
|
39378
|
+
{ texto: pinta(tema, "gris", stateLabel(state)) }
|
|
39379
|
+
])
|
|
39380
|
+
);
|
|
39381
|
+
lines.push(...siguienteAccion(tema, nextAction.command, `${nextAction.description} ${s.separador} ${actor}`));
|
|
39382
|
+
for (const block of blockedBy) lines.push(` ${pinta(tema, "amarillo", s.bloqueo)} ${pinta(tema, "gris", block)}`);
|
|
39281
39383
|
lines.push("");
|
|
39282
39384
|
data.push({ slug: change.slug, state, next: nextAction.command, blockedBy, requiresAgent: nextAction.requiresAgent });
|
|
39283
39385
|
}
|
|
39284
|
-
if (targets.length === 0) lines.push("Sin cambios activos.");
|
|
39386
|
+
if (targets.length === 0) lines.push(pinta(tema, "gris", " Sin cambios activos."));
|
|
39285
39387
|
return { exitCode: hasErrors2 ? 1 : 0, diagnostics: [], data: { changes: data }, text: lines };
|
|
39286
39388
|
}
|
|
39287
39389
|
|
|
@@ -39568,20 +39670,52 @@ async function avisoDeActualizacion(json2, cwd) {
|
|
|
39568
39670
|
}
|
|
39569
39671
|
|
|
39570
39672
|
// src/commands/status.ts
|
|
39673
|
+
var TONO_ESTADO = {
|
|
39674
|
+
draft: "gris",
|
|
39675
|
+
spec_draft: "amarillo",
|
|
39676
|
+
paused: "amarillo",
|
|
39677
|
+
awaiting_mockups: "morado",
|
|
39678
|
+
awaiting_approval: "morado",
|
|
39679
|
+
approved: "azul",
|
|
39680
|
+
planned: "azul",
|
|
39681
|
+
building: "azul",
|
|
39682
|
+
built: "amarillo",
|
|
39683
|
+
verified: "verde",
|
|
39684
|
+
reviewed: "verde",
|
|
39685
|
+
ready: "verde",
|
|
39686
|
+
archived: "gris"
|
|
39687
|
+
};
|
|
39688
|
+
function marcaDeEstado(tema, estado, bloqueado) {
|
|
39689
|
+
const s = simbolos(tema);
|
|
39690
|
+
if (bloqueado) return pinta(tema, "rojo", s.bloqueo);
|
|
39691
|
+
if (estado === "paused") return pinta(tema, "amarillo", s.pausa);
|
|
39692
|
+
if (estado === "ready") return pinta(tema, "verde", s.ok);
|
|
39693
|
+
return pinta(tema, TONO_ESTADO[estado] ?? "azul", s.punto);
|
|
39694
|
+
}
|
|
39571
39695
|
async function runStatus(ctx) {
|
|
39572
39696
|
const { root, workspace, config, approvals } = await requireWorkspace(ctx);
|
|
39573
39697
|
const advisory = await upgradeAdvisory(root);
|
|
39574
|
-
const
|
|
39698
|
+
const tema = detectarTema();
|
|
39699
|
+
const s = simbolos(tema);
|
|
39700
|
+
const fixes = await loadLivingFixes(root);
|
|
39701
|
+
const contexto = [
|
|
39702
|
+
`${workspace.specs.length} ${workspace.specs.length === 1 ? "spec viva" : "specs vivas"}`,
|
|
39703
|
+
`${workspace.changes.length} ${workspace.changes.length === 1 ? "cambio" : "cambios"}`,
|
|
39704
|
+
fixes.length > 0 ? `${fixes.length} ${fixes.length === 1 ? "fix" : "fixes"}` : ""
|
|
39705
|
+
].filter((parte) => parte !== "").join(` ${s.separador} `);
|
|
39706
|
+
const lines = encabezado(tema, msg("status.title", ctx.language), `${config.project.name} ${s.separador} ${contexto}`);
|
|
39575
39707
|
const changes = [];
|
|
39576
39708
|
if (workspace.changes.length === 0) {
|
|
39577
|
-
lines.push("Sin cambios activos. Crea uno con
|
|
39709
|
+
lines.push(pinta(tema, "gris", ` Sin cambios activos. Crea uno con \`satlas new <slug>\`.`));
|
|
39578
39710
|
}
|
|
39579
39711
|
for (const change of workspace.changes) {
|
|
39580
39712
|
const evaluation = await evaluateChange(workspace, config, change, approvals);
|
|
39581
|
-
const { state, progress, nextAction } = evaluation.state;
|
|
39713
|
+
const { state, progress, nextAction, blockedBy } = evaluation.state;
|
|
39714
|
+
const lane = change.meta?.lane ?? config.lanes.default;
|
|
39715
|
+
const bloqueado = blockedBy.length > 0 || evaluation.blocking > 0;
|
|
39582
39716
|
changes.push({
|
|
39583
39717
|
slug: change.slug,
|
|
39584
|
-
lane
|
|
39718
|
+
lane,
|
|
39585
39719
|
domain: change.meta?.domain,
|
|
39586
39720
|
state,
|
|
39587
39721
|
label: stateLabel(state),
|
|
@@ -39590,27 +39724,48 @@ async function runStatus(ctx) {
|
|
|
39590
39724
|
blocking: evaluation.blocking
|
|
39591
39725
|
});
|
|
39592
39726
|
lines.push(
|
|
39593
|
-
|
|
39594
|
-
|
|
39595
|
-
|
|
39596
|
-
|
|
39727
|
+
filaAlineada([
|
|
39728
|
+
{ texto: ` ${marcaDeEstado(tema, state, bloqueado)} ${pinta(tema, "negrita", change.slug)}`, ancho: 30 },
|
|
39729
|
+
{ texto: pinta(tema, TONO_ESTADO[state] ?? "azul", stateLabel(state)), ancho: 22 },
|
|
39730
|
+
{ texto: pinta(tema, "gris", `${change.meta?.domain ?? "\u2014"} ${s.separador} ${lane}`) }
|
|
39731
|
+
])
|
|
39597
39732
|
);
|
|
39598
|
-
|
|
39733
|
+
const medidas = [
|
|
39734
|
+
`${pinta(tema, "gris", "tareas")} ${barraProgreso(tema, progress.tasksDone, progress.tasksTotal)}`,
|
|
39735
|
+
`${pinta(tema, "gris", "evidencia")} ${barraProgreso(tema, progress.scenariosEvidenced, progress.scenariosTotal)}`
|
|
39736
|
+
];
|
|
39737
|
+
lines.push(` ${medidas.join(pinta(tema, "gris", ` ${s.separador} `))}`);
|
|
39738
|
+
for (const bloqueo of blockedBy) lines.push(` ${pinta(tema, "amarillo", s.bloqueo)} ${pinta(tema, "gris", bloqueo)}`);
|
|
39739
|
+
lines.push(...siguienteAccion(tema, nextAction.command, nextAction.description));
|
|
39740
|
+
lines.push("");
|
|
39599
39741
|
}
|
|
39600
|
-
|
|
39601
|
-
|
|
39602
|
-
|
|
39603
|
-
|
|
39742
|
+
if (workspace.specs.length > 0) {
|
|
39743
|
+
lines.push(seccion(tema, msg("status.specs", ctx.language), `${workspace.specs.length}`));
|
|
39744
|
+
const ancho = Math.max(...workspace.specs.map((spec) => spec.domain.length), 8);
|
|
39745
|
+
for (const spec of workspace.specs) {
|
|
39746
|
+
lines.push(
|
|
39747
|
+
filaAlineada([
|
|
39748
|
+
{ texto: ` ${pinta(tema, "morado", s.punto)} ${spec.domain}`, ancho: ancho + 6 },
|
|
39749
|
+
{ texto: pinta(tema, "gris", `${spec.spec.requirements.length} ${spec.spec.requirements.length === 1 ? "requisito" : "requisitos"}`) }
|
|
39750
|
+
])
|
|
39751
|
+
);
|
|
39752
|
+
}
|
|
39753
|
+
lines.push("");
|
|
39604
39754
|
}
|
|
39605
|
-
|
|
39606
|
-
lines.push("");
|
|
39607
|
-
lines.push(`${msg("status.fixes", ctx.language)}: ${fixes.length}`);
|
|
39755
|
+
lines.push(seccion(tema, msg("status.fixes", ctx.language), `${fixes.length}`));
|
|
39608
39756
|
if (fixes.length === 0) {
|
|
39609
|
-
lines.push(" (se llenan al archivar un fix)");
|
|
39757
|
+
lines.push(pinta(tema, "gris", " (se llenan al archivar un fix)"));
|
|
39610
39758
|
} else {
|
|
39611
39759
|
for (const fix of fixes) {
|
|
39612
|
-
const
|
|
39613
|
-
lines.push(
|
|
39760
|
+
const resultado = fix.result === "pass" ? pinta(tema, "verde", fix.result) : pinta(tema, "rojo", fix.result);
|
|
39761
|
+
lines.push(
|
|
39762
|
+
filaAlineada([
|
|
39763
|
+
{ texto: ` ${pinta(tema, "gris", fix.date || "\u2014")}`, ancho: 14 },
|
|
39764
|
+
{ texto: pinta(tema, "gris", fix.domain ?? "\u2014"), ancho: 14 },
|
|
39765
|
+
{ texto: fix.slug, ancho: 28 },
|
|
39766
|
+
{ texto: `${resultado}${fix.source === "archive" ? pinta(tema, "gris", " (hist\xF3rico)") : ""}` }
|
|
39767
|
+
])
|
|
39768
|
+
);
|
|
39614
39769
|
}
|
|
39615
39770
|
}
|
|
39616
39771
|
const diagnostics = [...workspace.diagnostics, ...advisory.diagnostics];
|
|
@@ -39620,7 +39775,7 @@ async function runStatus(ctx) {
|
|
|
39620
39775
|
diagnostics,
|
|
39621
39776
|
data: {
|
|
39622
39777
|
changes,
|
|
39623
|
-
specs: workspace.specs.map((
|
|
39778
|
+
specs: workspace.specs.map((spec) => ({ domain: spec.domain, requirements: spec.spec.requirements.length })),
|
|
39624
39779
|
fixes: fixes.map((fix) => ({
|
|
39625
39780
|
slug: fix.slug,
|
|
39626
39781
|
date: fix.date,
|
|
@@ -39794,8 +39949,10 @@ async function runValidate(ctx) {
|
|
|
39794
39949
|
const slug = flagString(ctx.flags, "change");
|
|
39795
39950
|
const strict = flagBool(ctx.flags, "strict");
|
|
39796
39951
|
const advisory = slug ? void 0 : await upgradeAdvisory(root);
|
|
39952
|
+
const tema = detectarTema();
|
|
39953
|
+
const s = simbolos(tema);
|
|
39797
39954
|
const diagnostics = [];
|
|
39798
|
-
const lines =
|
|
39955
|
+
const lines = encabezado(tema, msg("validate.title", ctx.language), slug ? slug : void 0);
|
|
39799
39956
|
for (const spec of workspace.specs) {
|
|
39800
39957
|
diagnostics.push(...lintSpec(spec.spec, { language: config.spec.language, businessOnly: config.spec.business_only }));
|
|
39801
39958
|
}
|
|
@@ -39811,11 +39968,15 @@ async function runValidate(ctx) {
|
|
|
39811
39968
|
const evaluation = await evaluateChange(workspace, config, change, approvals);
|
|
39812
39969
|
diagnostics.push(...evaluation.lintFindings);
|
|
39813
39970
|
changes.push({ slug: change.slug, blocking: evaluation.blocking, findings: evaluation.lintFindings.length });
|
|
39814
|
-
|
|
39815
|
-
|
|
39816
|
-
|
|
39817
|
-
|
|
39818
|
-
|
|
39971
|
+
const errores = evaluation.lintFindings.filter((finding) => finding.severity === "error").length;
|
|
39972
|
+
const marca = errores > 0 ? pinta(tema, "rojo", s.error) : evaluation.lintFindings.length > 0 ? pinta(tema, "amarillo", s.aviso) : pinta(tema, "verde", s.ok);
|
|
39973
|
+
lines.push(
|
|
39974
|
+
filaAlineada([
|
|
39975
|
+
{ texto: ` ${marca} ${pinta(tema, "negrita", change.slug)}`, ancho: 30 },
|
|
39976
|
+
{ texto: evaluation.lintFindings.length === 0 ? pinta(tema, "gris", "sin hallazgos") : `${evaluation.lintFindings.length} ${msg("summary.findings", ctx.language)}`, ancho: 20 },
|
|
39977
|
+
{ texto: pinta(tema, "gris", path59.relative(ctx.cwd, path59.join(change.dir, "spec.md"))) }
|
|
39978
|
+
])
|
|
39979
|
+
);
|
|
39819
39980
|
}
|
|
39820
39981
|
if (targets.length === 0) lines.push("Sin cambios activos.");
|
|
39821
39982
|
if (advisory && advisory.plan.pending.length > 0) {
|
|
@@ -39823,7 +39984,10 @@ async function runValidate(ctx) {
|
|
|
39823
39984
|
}
|
|
39824
39985
|
const errors = diagnostics.filter((d) => d.severity === "error").length;
|
|
39825
39986
|
const warnings = diagnostics.filter((d) => d.severity === "warning").length;
|
|
39826
|
-
if (errors === 0 && warnings === 0)
|
|
39987
|
+
if (errors === 0 && warnings === 0) {
|
|
39988
|
+
lines.push("");
|
|
39989
|
+
lines.push(exito(tema, msg("validate.ok", ctx.language)));
|
|
39990
|
+
}
|
|
39827
39991
|
return {
|
|
39828
39992
|
exitCode: errors > 0 || strict && warnings > 0 ? 1 : 0,
|
|
39829
39993
|
diagnostics: advisory ? [...diagnostics, ...advisory.diagnostics] : diagnostics,
|
|
@@ -40192,15 +40356,28 @@ function printResult(command, result, json2, language) {
|
|
|
40192
40356
|
`);
|
|
40193
40357
|
return;
|
|
40194
40358
|
}
|
|
40359
|
+
const tema = detectarTema();
|
|
40195
40360
|
const lines = [...result.text ?? []];
|
|
40361
|
+
if (result.diagnostics.length > 0) lines.push("");
|
|
40196
40362
|
for (const d of result.diagnostics) {
|
|
40197
|
-
const
|
|
40198
|
-
lines.push(
|
|
40199
|
-
|
|
40363
|
+
const ruta = d.path ? path62.relative(process.cwd(), d.path) : void 0;
|
|
40364
|
+
lines.push(
|
|
40365
|
+
...formatearDiagnostico(
|
|
40366
|
+
tema,
|
|
40367
|
+
{
|
|
40368
|
+
code: d.code,
|
|
40369
|
+
severity: d.severity,
|
|
40370
|
+
message: d.message,
|
|
40371
|
+
...d.line !== void 0 ? { line: d.line } : {},
|
|
40372
|
+
...d.suggestion !== void 0 ? { suggestion: d.suggestion } : {}
|
|
40373
|
+
},
|
|
40374
|
+
ruta
|
|
40375
|
+
)
|
|
40376
|
+
);
|
|
40200
40377
|
}
|
|
40201
|
-
const counts = countBySeverity(result.diagnostics);
|
|
40202
40378
|
if (result.diagnostics.length > 0) {
|
|
40203
|
-
lines.push(
|
|
40379
|
+
lines.push("");
|
|
40380
|
+
lines.push(resumenHallazgos(tema, countBySeverity(result.diagnostics)));
|
|
40204
40381
|
}
|
|
40205
40382
|
if (lines.length > 0) process.stdout.write(`${lines.join("\n")}
|
|
40206
40383
|
`);
|