viberails 0.6.8 → 0.6.9
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/index.cjs +256 -219
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +256 -219
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -34,14 +34,14 @@ __export(index_exports, {
|
|
|
34
34
|
VERSION: () => VERSION
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
|
-
var
|
|
37
|
+
var import_chalk18 = __toESM(require("chalk"), 1);
|
|
38
38
|
var import_commander = require("commander");
|
|
39
39
|
|
|
40
40
|
// src/commands/boundaries.ts
|
|
41
41
|
var fs3 = __toESM(require("fs"), 1);
|
|
42
42
|
var path3 = __toESM(require("path"), 1);
|
|
43
43
|
var import_config = require("@viberails/config");
|
|
44
|
-
var
|
|
44
|
+
var import_chalk3 = __toESM(require("chalk"), 1);
|
|
45
45
|
|
|
46
46
|
// src/utils/find-project-root.ts
|
|
47
47
|
var fs = __toESM(require("fs"), 1);
|
|
@@ -76,6 +76,7 @@ var clack3 = __toESM(require("@clack/prompts"), 1);
|
|
|
76
76
|
|
|
77
77
|
// src/utils/prompt-package-overrides.ts
|
|
78
78
|
var clack2 = __toESM(require("@clack/prompts"), 1);
|
|
79
|
+
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
79
80
|
|
|
80
81
|
// src/utils/prompt-constants.ts
|
|
81
82
|
var SENTINEL_DONE = "__done__";
|
|
@@ -150,64 +151,56 @@ async function promptFileLimitsMenu(state) {
|
|
|
150
151
|
}
|
|
151
152
|
async function promptNamingMenu(state) {
|
|
152
153
|
while (true) {
|
|
154
|
+
const ok = import_chalk.default.green("\u2713");
|
|
155
|
+
const unset = import_chalk.default.dim("-");
|
|
156
|
+
const enforcementLabel = state.enforceNaming ? `enforced ${import_chalk.default.green("\u2713")}` : `not enforced ${import_chalk.default.dim("\u2717")}`;
|
|
153
157
|
const options = [
|
|
154
158
|
{
|
|
155
|
-
value: "enforceNaming",
|
|
156
|
-
label: "Enforce file naming",
|
|
157
|
-
hint: state.enforceNaming ? import_chalk.default.green("yes") : import_chalk.default.dim("no")
|
|
158
|
-
}
|
|
159
|
-
];
|
|
160
|
-
if (state.enforceNaming) {
|
|
161
|
-
options.push({
|
|
162
159
|
value: "fileNaming",
|
|
163
|
-
label:
|
|
160
|
+
label: `${state.fileNamingValue ? ok : unset} File naming convention`,
|
|
164
161
|
hint: state.fileNamingValue ?? HINT_NOT_SET
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
options.push(
|
|
162
|
+
},
|
|
168
163
|
{
|
|
169
164
|
value: "componentNaming",
|
|
170
|
-
label:
|
|
165
|
+
label: `${state.componentNaming ? ok : unset} Component naming`,
|
|
171
166
|
hint: state.componentNaming ?? HINT_NOT_SET
|
|
172
167
|
},
|
|
173
168
|
{
|
|
174
169
|
value: "hookNaming",
|
|
175
|
-
label:
|
|
170
|
+
label: `${state.hookNaming ? ok : unset} Hook naming`,
|
|
176
171
|
hint: state.hookNaming ?? HINT_NOT_SET
|
|
177
172
|
},
|
|
178
173
|
{
|
|
179
174
|
value: "importAlias",
|
|
180
|
-
label:
|
|
175
|
+
label: `${state.importAlias ? ok : unset} Import alias`,
|
|
181
176
|
hint: state.importAlias ?? HINT_NOT_SET
|
|
182
177
|
},
|
|
183
|
-
{
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
{
|
|
179
|
+
value: "toggleEnforcement",
|
|
180
|
+
label: state.enforceNaming ? " Turn off enforcement" : " Turn on enforcement"
|
|
181
|
+
},
|
|
182
|
+
{ value: "back", label: " Back" }
|
|
183
|
+
];
|
|
184
|
+
const choice = await clack.select({
|
|
185
|
+
message: `Naming conventions (${enforcementLabel})`,
|
|
186
|
+
options
|
|
187
|
+
});
|
|
186
188
|
if (isCancelled(choice) || choice === "back") return;
|
|
187
|
-
if (choice === "
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
initialValue: state.enforceNaming
|
|
191
|
-
});
|
|
192
|
-
if (isCancelled(result)) continue;
|
|
193
|
-
if (result && !state.fileNamingValue) {
|
|
194
|
-
const selected = await clack.select({
|
|
195
|
-
message: "Which file naming convention should be enforced?",
|
|
196
|
-
options: [...FILE_NAMING_OPTIONS]
|
|
197
|
-
});
|
|
198
|
-
if (isCancelled(selected)) continue;
|
|
199
|
-
state.fileNamingValue = selected;
|
|
200
|
-
}
|
|
201
|
-
state.enforceNaming = result;
|
|
189
|
+
if (choice === "toggleEnforcement") {
|
|
190
|
+
state.enforceNaming = !state.enforceNaming;
|
|
191
|
+
continue;
|
|
202
192
|
}
|
|
203
193
|
if (choice === "fileNaming") {
|
|
204
194
|
const selected = await clack.select({
|
|
205
|
-
message: "
|
|
206
|
-
options: [
|
|
207
|
-
|
|
195
|
+
message: "File naming convention",
|
|
196
|
+
options: [
|
|
197
|
+
...FILE_NAMING_OPTIONS,
|
|
198
|
+
{ value: SENTINEL_CLEAR, label: "Clear (no convention)" }
|
|
199
|
+
],
|
|
200
|
+
initialValue: state.fileNamingValue ?? SENTINEL_CLEAR
|
|
208
201
|
});
|
|
209
202
|
if (isCancelled(selected)) continue;
|
|
210
|
-
state.fileNamingValue = selected;
|
|
203
|
+
state.fileNamingValue = selected === SENTINEL_CLEAR ? void 0 : selected;
|
|
211
204
|
}
|
|
212
205
|
if (choice === "componentNaming") {
|
|
213
206
|
const selected = await clack.select({
|
|
@@ -272,7 +265,7 @@ async function promptTestingMenu(state) {
|
|
|
272
265
|
{
|
|
273
266
|
value: "enforceMissingTests",
|
|
274
267
|
label: "Enforce missing tests",
|
|
275
|
-
hint: state.enforceMissingTests ? import_chalk.default.green("
|
|
268
|
+
hint: state.enforceMissingTests ? import_chalk.default.green("\u2713") : import_chalk.default.dim("\u2717")
|
|
276
269
|
},
|
|
277
270
|
{
|
|
278
271
|
value: "testCoverage",
|
|
@@ -381,6 +374,19 @@ function packageOverrideHint(pkg, defaults) {
|
|
|
381
374
|
if (hasCommandOverride) tags.push("command override");
|
|
382
375
|
return tags.length > 0 ? tags.join(", ") : HINT_NO_OVERRIDES;
|
|
383
376
|
}
|
|
377
|
+
function packageOverrideIcon(pkg, defaults) {
|
|
378
|
+
const dc = defaults.coverageCommand ?? "";
|
|
379
|
+
const count = [
|
|
380
|
+
pkg.conventions?.fileNaming !== void 0 && pkg.conventions.fileNaming !== defaults.fileNamingValue,
|
|
381
|
+
pkg.rules?.maxFileLines !== void 0 && pkg.rules.maxFileLines !== defaults.maxFileLines,
|
|
382
|
+
pkg.rules?.testCoverage !== void 0 && pkg.rules.testCoverage !== defaults.testCoverage,
|
|
383
|
+
pkg.coverage?.summaryPath !== void 0 && pkg.coverage.summaryPath !== defaults.coverageSummaryPath,
|
|
384
|
+
pkg.coverage?.command !== void 0 && pkg.coverage.command !== dc
|
|
385
|
+
].filter(Boolean).length;
|
|
386
|
+
if (count === 5) return import_chalk2.default.green("\u2713");
|
|
387
|
+
if (count > 0) return import_chalk2.default.yellow("~");
|
|
388
|
+
return import_chalk2.default.dim("-");
|
|
389
|
+
}
|
|
384
390
|
async function promptPackageOverrides(packages, defaults) {
|
|
385
391
|
const editablePackages = packages.filter((pkg) => pkg.path !== ".");
|
|
386
392
|
if (editablePackages.length === 0) return packages;
|
|
@@ -388,12 +394,15 @@ async function promptPackageOverrides(packages, defaults) {
|
|
|
388
394
|
const selectedPath = await clack2.select({
|
|
389
395
|
message: "Select package to edit overrides",
|
|
390
396
|
options: [
|
|
391
|
-
...editablePackages.map((pkg) =>
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
+
...editablePackages.map((pkg) => {
|
|
398
|
+
const icon = packageOverrideIcon(pkg, defaults);
|
|
399
|
+
return {
|
|
400
|
+
value: pkg.path,
|
|
401
|
+
label: `${icon} ${pkg.path} (${pkg.name})`,
|
|
402
|
+
hint: packageOverrideHint(pkg, defaults)
|
|
403
|
+
};
|
|
404
|
+
}),
|
|
405
|
+
{ value: SENTINEL_DONE, label: " Done" }
|
|
397
406
|
]
|
|
398
407
|
});
|
|
399
408
|
if (isCancelled(selectedPath) || selectedPath === SENTINEL_DONE) break;
|
|
@@ -413,18 +422,47 @@ async function promptSinglePackageOverrides(target, defaults) {
|
|
|
413
422
|
const effectiveCommand = target.coverage?.command ?? defaults.coverageCommand ?? HINT_AUTO_DETECT;
|
|
414
423
|
const hasNamingOverride = target.conventions?.fileNaming !== void 0 && target.conventions.fileNaming !== defaults.fileNamingValue;
|
|
415
424
|
const hasMaxLinesOverride = target.rules?.maxFileLines !== void 0 && target.rules.maxFileLines !== defaults.maxFileLines;
|
|
425
|
+
const hasCoverageOverride = target.rules?.testCoverage !== void 0 && target.rules.testCoverage !== defaults.testCoverage;
|
|
426
|
+
const hasSummaryOverride = target.coverage?.summaryPath !== void 0 && target.coverage.summaryPath !== defaults.coverageSummaryPath;
|
|
427
|
+
const defaultCommand = defaults.coverageCommand ?? "";
|
|
428
|
+
const hasCommandOverride = target.coverage?.command !== void 0 && target.coverage.command !== defaultCommand;
|
|
429
|
+
const ok = import_chalk2.default.green("\u2713");
|
|
430
|
+
const unset = import_chalk2.default.dim("-");
|
|
416
431
|
const namingHint = hasNamingOverride ? String(effectiveNaming) : `inherits: ${effectiveNaming ?? "not set"}`;
|
|
417
432
|
const maxLinesHint = hasMaxLinesOverride ? String(effectiveMaxLines) : `inherits: ${effectiveMaxLines}`;
|
|
433
|
+
const coverageHint2 = hasCoverageOverride ? String(effectiveCoverage) : `inherits: ${effectiveCoverage}`;
|
|
434
|
+
const summaryHint = hasSummaryOverride ? effectiveSummary : `inherits: ${effectiveSummary}`;
|
|
435
|
+
const commandHint = hasCommandOverride ? effectiveCommand : `inherits: ${effectiveCommand}`;
|
|
418
436
|
const choice = await clack2.select({
|
|
419
437
|
message: `Edit overrides for ${target.path}`,
|
|
420
438
|
options: [
|
|
421
|
-
{
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
{
|
|
427
|
-
|
|
439
|
+
{
|
|
440
|
+
value: "fileNaming",
|
|
441
|
+
label: `${hasNamingOverride ? ok : unset} File naming`,
|
|
442
|
+
hint: namingHint
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
value: "maxFileLines",
|
|
446
|
+
label: `${hasMaxLinesOverride ? ok : unset} Max file lines`,
|
|
447
|
+
hint: maxLinesHint
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
value: "testCoverage",
|
|
451
|
+
label: `${hasCoverageOverride ? ok : unset} Test coverage`,
|
|
452
|
+
hint: coverageHint2
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
value: "summaryPath",
|
|
456
|
+
label: `${hasSummaryOverride ? ok : unset} Coverage summary path`,
|
|
457
|
+
hint: summaryHint
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
value: "command",
|
|
461
|
+
label: `${hasCommandOverride ? ok : unset} Coverage command`,
|
|
462
|
+
hint: commandHint
|
|
463
|
+
},
|
|
464
|
+
{ value: "reset", label: " Reset all overrides for this package" },
|
|
465
|
+
{ value: "back", label: " Back to package list" }
|
|
428
466
|
]
|
|
429
467
|
});
|
|
430
468
|
if (isCancelled(choice) || choice === "back") break;
|
|
@@ -504,8 +542,8 @@ async function promptSinglePackageOverrides(target, defaults) {
|
|
|
504
542
|
});
|
|
505
543
|
if (isCancelled(result)) continue;
|
|
506
544
|
const value = result.trim();
|
|
507
|
-
const
|
|
508
|
-
if (value.length === 0 || value ===
|
|
545
|
+
const defaultCommand2 = defaults.coverageCommand ?? "";
|
|
546
|
+
if (value.length === 0 || value === defaultCommand2) {
|
|
509
547
|
if (target.coverage) delete target.coverage.command;
|
|
510
548
|
} else {
|
|
511
549
|
target.coverage = { ...target.coverage ?? {}, command: value };
|
|
@@ -768,48 +806,48 @@ async function boundariesCommand(options, cwd) {
|
|
|
768
806
|
}
|
|
769
807
|
function displayRules(config) {
|
|
770
808
|
if (!config.boundaries || Object.keys(config.boundaries.deny).length === 0) {
|
|
771
|
-
console.log(
|
|
772
|
-
console.log(`Run ${
|
|
809
|
+
console.log(import_chalk3.default.yellow("No boundary rules configured."));
|
|
810
|
+
console.log(`Run ${import_chalk3.default.cyan("viberails boundaries --infer")} to generate rules.`);
|
|
773
811
|
return;
|
|
774
812
|
}
|
|
775
813
|
const { deny } = config.boundaries;
|
|
776
814
|
const sources = Object.keys(deny).filter((k) => deny[k].length > 0);
|
|
777
815
|
const totalRules = sources.reduce((sum, k) => sum + deny[k].length, 0);
|
|
778
816
|
console.log(`
|
|
779
|
-
${
|
|
817
|
+
${import_chalk3.default.bold(`Boundary rules (${totalRules} deny rules):`)}
|
|
780
818
|
`);
|
|
781
819
|
for (const source of sources) {
|
|
782
820
|
for (const target of deny[source]) {
|
|
783
|
-
console.log(` ${
|
|
821
|
+
console.log(` ${import_chalk3.default.red("\u2717")} ${source} \u2192 ${target}`);
|
|
784
822
|
}
|
|
785
823
|
}
|
|
786
824
|
console.log(
|
|
787
825
|
`
|
|
788
|
-
Enforcement: ${config.rules.enforceBoundaries ?
|
|
826
|
+
Enforcement: ${config.rules.enforceBoundaries ? import_chalk3.default.green("on") : import_chalk3.default.yellow("off")}`
|
|
789
827
|
);
|
|
790
828
|
}
|
|
791
829
|
async function inferAndDisplay(projectRoot, config, configPath) {
|
|
792
|
-
console.log(
|
|
830
|
+
console.log(import_chalk3.default.dim("Analyzing imports..."));
|
|
793
831
|
const { buildImportGraph, inferBoundaries } = await import("@viberails/graph");
|
|
794
832
|
const packages = config.packages.length > 1 ? resolveWorkspacePackages(projectRoot, config.packages) : void 0;
|
|
795
833
|
const graph = await buildImportGraph(projectRoot, {
|
|
796
834
|
packages,
|
|
797
835
|
ignore: config.ignore
|
|
798
836
|
});
|
|
799
|
-
console.log(
|
|
837
|
+
console.log(import_chalk3.default.dim(`${graph.nodes.length} files, ${graph.edges.length} edges`));
|
|
800
838
|
const inferred = inferBoundaries(graph);
|
|
801
839
|
const sources = Object.keys(inferred.deny).filter((k) => inferred.deny[k].length > 0);
|
|
802
840
|
const totalRules = sources.reduce((sum, k) => sum + inferred.deny[k].length, 0);
|
|
803
841
|
if (totalRules === 0) {
|
|
804
|
-
console.log(
|
|
842
|
+
console.log(import_chalk3.default.yellow("No boundary rules could be inferred."));
|
|
805
843
|
return;
|
|
806
844
|
}
|
|
807
845
|
console.log(`
|
|
808
|
-
${
|
|
846
|
+
${import_chalk3.default.bold("Inferred boundary rules:")}
|
|
809
847
|
`);
|
|
810
848
|
for (const source of sources) {
|
|
811
849
|
for (const target of inferred.deny[source]) {
|
|
812
|
-
console.log(` ${
|
|
850
|
+
console.log(` ${import_chalk3.default.red("\u2717")} ${source} \u2192 ${target}`);
|
|
813
851
|
}
|
|
814
852
|
}
|
|
815
853
|
console.log(`
|
|
@@ -821,11 +859,11 @@ ${import_chalk2.default.bold("Inferred boundary rules:")}
|
|
|
821
859
|
config.rules.enforceBoundaries = true;
|
|
822
860
|
fs3.writeFileSync(configPath, `${JSON.stringify((0, import_config.compactConfig)(config), null, 2)}
|
|
823
861
|
`);
|
|
824
|
-
console.log(`${
|
|
862
|
+
console.log(`${import_chalk3.default.green("\u2713")} Saved ${totalRules} rules`);
|
|
825
863
|
}
|
|
826
864
|
}
|
|
827
865
|
async function showGraph(projectRoot, config) {
|
|
828
|
-
console.log(
|
|
866
|
+
console.log(import_chalk3.default.dim("Building import graph..."));
|
|
829
867
|
const { buildImportGraph } = await import("@viberails/graph");
|
|
830
868
|
const packages = config.packages.length > 1 ? resolveWorkspacePackages(projectRoot, config.packages) : void 0;
|
|
831
869
|
const graph = await buildImportGraph(projectRoot, {
|
|
@@ -833,20 +871,20 @@ async function showGraph(projectRoot, config) {
|
|
|
833
871
|
ignore: config.ignore
|
|
834
872
|
});
|
|
835
873
|
console.log(`
|
|
836
|
-
${
|
|
874
|
+
${import_chalk3.default.bold("Import dependency graph:")}
|
|
837
875
|
`);
|
|
838
876
|
console.log(` ${graph.nodes.length} files, ${graph.edges.length} imports
|
|
839
877
|
`);
|
|
840
878
|
if (graph.packages.length > 0) {
|
|
841
879
|
for (const pkg of graph.packages) {
|
|
842
880
|
const deps = pkg.internalDeps.length > 0 ? `
|
|
843
|
-
${pkg.internalDeps.map((d) => ` \u2192 ${d}`).join("\n")}` :
|
|
881
|
+
${pkg.internalDeps.map((d) => ` \u2192 ${d}`).join("\n")}` : import_chalk3.default.dim(" (no internal deps)");
|
|
844
882
|
console.log(` ${pkg.name}${deps}`);
|
|
845
883
|
}
|
|
846
884
|
}
|
|
847
885
|
if (graph.cycles.length > 0) {
|
|
848
886
|
console.log(`
|
|
849
|
-
${
|
|
887
|
+
${import_chalk3.default.yellow("Cycles detected:")}`);
|
|
850
888
|
for (const cycle of graph.cycles) {
|
|
851
889
|
const paths = cycle.map((f) => path3.relative(projectRoot, f));
|
|
852
890
|
console.log(` ${paths.join(" \u2192 ")}`);
|
|
@@ -858,7 +896,7 @@ ${import_chalk2.default.yellow("Cycles detected:")}`);
|
|
|
858
896
|
var fs7 = __toESM(require("fs"), 1);
|
|
859
897
|
var path7 = __toESM(require("path"), 1);
|
|
860
898
|
var import_config5 = require("@viberails/config");
|
|
861
|
-
var
|
|
899
|
+
var import_chalk5 = __toESM(require("chalk"), 1);
|
|
862
900
|
|
|
863
901
|
// src/commands/check-config.ts
|
|
864
902
|
var import_config2 = require("@viberails/config");
|
|
@@ -1250,7 +1288,7 @@ function collectSourceFiles(dir, projectRoot) {
|
|
|
1250
1288
|
}
|
|
1251
1289
|
|
|
1252
1290
|
// src/commands/check-print.ts
|
|
1253
|
-
var
|
|
1291
|
+
var import_chalk4 = __toESM(require("chalk"), 1);
|
|
1254
1292
|
function printGroupedViolations(violations, limit) {
|
|
1255
1293
|
const groups = /* @__PURE__ */ new Map();
|
|
1256
1294
|
for (const v of violations) {
|
|
@@ -1278,12 +1316,12 @@ function printGroupedViolations(violations, limit) {
|
|
|
1278
1316
|
const toShow = group.slice(0, remaining);
|
|
1279
1317
|
const hidden = group.length - toShow.length;
|
|
1280
1318
|
for (const v of toShow) {
|
|
1281
|
-
const icon = v.severity === "error" ?
|
|
1282
|
-
console.log(`${icon} ${
|
|
1319
|
+
const icon = v.severity === "error" ? import_chalk4.default.red("\u2717") : import_chalk4.default.yellow("!");
|
|
1320
|
+
console.log(`${icon} ${import_chalk4.default.dim(v.rule)} ${v.file}: ${v.message}`);
|
|
1283
1321
|
}
|
|
1284
1322
|
totalShown += toShow.length;
|
|
1285
1323
|
if (hidden > 0) {
|
|
1286
|
-
console.log(
|
|
1324
|
+
console.log(import_chalk4.default.dim(` ... and ${hidden} more ${rule} violations`));
|
|
1287
1325
|
}
|
|
1288
1326
|
}
|
|
1289
1327
|
}
|
|
@@ -1373,13 +1411,13 @@ async function checkCommand(options, cwd) {
|
|
|
1373
1411
|
const startDir = cwd ?? process.cwd();
|
|
1374
1412
|
const projectRoot = findProjectRoot(startDir);
|
|
1375
1413
|
if (!projectRoot) {
|
|
1376
|
-
console.error(`${
|
|
1414
|
+
console.error(`${import_chalk5.default.red("Error:")} No package.json found. Are you in a JS/TS project?`);
|
|
1377
1415
|
return 1;
|
|
1378
1416
|
}
|
|
1379
1417
|
const configPath = path7.join(projectRoot, CONFIG_FILE2);
|
|
1380
1418
|
if (!fs7.existsSync(configPath)) {
|
|
1381
1419
|
console.error(
|
|
1382
|
-
`${
|
|
1420
|
+
`${import_chalk5.default.red("Error:")} No viberails.config.json found. Run \`viberails init\` first.`
|
|
1383
1421
|
);
|
|
1384
1422
|
return 1;
|
|
1385
1423
|
}
|
|
@@ -1393,7 +1431,7 @@ async function checkCommand(options, cwd) {
|
|
|
1393
1431
|
} else if (options.diffBase) {
|
|
1394
1432
|
const diff = getDiffFiles(projectRoot, options.diffBase);
|
|
1395
1433
|
if (diff.error && options.enforce) {
|
|
1396
|
-
console.error(`${
|
|
1434
|
+
console.error(`${import_chalk5.default.red("Error:")} ${diff.error}`);
|
|
1397
1435
|
return 1;
|
|
1398
1436
|
}
|
|
1399
1437
|
filesToCheck = diff.all.filter((f) => SOURCE_EXTS.has(path7.extname(f)));
|
|
@@ -1408,13 +1446,13 @@ async function checkCommand(options, cwd) {
|
|
|
1408
1446
|
if (options.format === "json") {
|
|
1409
1447
|
console.log(JSON.stringify({ violations: [], checkedFiles: 0 }));
|
|
1410
1448
|
} else {
|
|
1411
|
-
console.log(`${
|
|
1449
|
+
console.log(`${import_chalk5.default.green("\u2713")} No files to check.`);
|
|
1412
1450
|
}
|
|
1413
1451
|
return 0;
|
|
1414
1452
|
}
|
|
1415
1453
|
const violations = [];
|
|
1416
1454
|
const severity = options.enforce ? "error" : "warn";
|
|
1417
|
-
const log9 = options.format !== "json" && !options.hook && !options.quiet ? (msg) => process.stderr.write(
|
|
1455
|
+
const log9 = options.format !== "json" && !options.hook && !options.quiet ? (msg) => process.stderr.write(import_chalk5.default.dim(msg)) : () => {
|
|
1418
1456
|
};
|
|
1419
1457
|
log9(" Checking files...");
|
|
1420
1458
|
for (const file of filesToCheck) {
|
|
@@ -1509,7 +1547,7 @@ async function checkCommand(options, cwd) {
|
|
|
1509
1547
|
return options.enforce && violations.length > 0 ? 1 : 0;
|
|
1510
1548
|
}
|
|
1511
1549
|
if (violations.length === 0) {
|
|
1512
|
-
console.log(`${
|
|
1550
|
+
console.log(`${import_chalk5.default.green("\u2713")} ${filesToCheck.length} files checked \u2014 no violations`);
|
|
1513
1551
|
return 0;
|
|
1514
1552
|
}
|
|
1515
1553
|
if (!options.quiet) {
|
|
@@ -1517,7 +1555,7 @@ async function checkCommand(options, cwd) {
|
|
|
1517
1555
|
}
|
|
1518
1556
|
printSummary(violations);
|
|
1519
1557
|
if (options.enforce) {
|
|
1520
|
-
console.log(
|
|
1558
|
+
console.log(import_chalk5.default.red("Fix violations before committing."));
|
|
1521
1559
|
return 1;
|
|
1522
1560
|
}
|
|
1523
1561
|
return 0;
|
|
@@ -1575,14 +1613,14 @@ var path9 = __toESM(require("path"), 1);
|
|
|
1575
1613
|
var clack6 = __toESM(require("@clack/prompts"), 1);
|
|
1576
1614
|
var import_config6 = require("@viberails/config");
|
|
1577
1615
|
var import_scanner = require("@viberails/scanner");
|
|
1578
|
-
var
|
|
1616
|
+
var import_chalk8 = __toESM(require("chalk"), 1);
|
|
1579
1617
|
|
|
1580
1618
|
// src/display-text.ts
|
|
1581
1619
|
var import_types4 = require("@viberails/types");
|
|
1582
1620
|
|
|
1583
1621
|
// src/display.ts
|
|
1584
1622
|
var import_types3 = require("@viberails/types");
|
|
1585
|
-
var
|
|
1623
|
+
var import_chalk7 = __toESM(require("chalk"), 1);
|
|
1586
1624
|
|
|
1587
1625
|
// src/display-helpers.ts
|
|
1588
1626
|
var import_types = require("@viberails/types");
|
|
@@ -1635,7 +1673,7 @@ function formatRoleGroup(group) {
|
|
|
1635
1673
|
|
|
1636
1674
|
// src/display-monorepo.ts
|
|
1637
1675
|
var import_types2 = require("@viberails/types");
|
|
1638
|
-
var
|
|
1676
|
+
var import_chalk6 = __toESM(require("chalk"), 1);
|
|
1639
1677
|
function formatPackageSummary(pkg) {
|
|
1640
1678
|
const parts = [];
|
|
1641
1679
|
if (pkg.stack.framework) {
|
|
@@ -1652,23 +1690,23 @@ function formatPackageSummary(pkg) {
|
|
|
1652
1690
|
function displayMonorepoResults(scanResult) {
|
|
1653
1691
|
const { stack, packages } = scanResult;
|
|
1654
1692
|
console.log(`
|
|
1655
|
-
${
|
|
1656
|
-
console.log(` ${
|
|
1693
|
+
${import_chalk6.default.bold(`Detected: (monorepo, ${packages.length} packages)`)}`);
|
|
1694
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.language)}`);
|
|
1657
1695
|
if (stack.packageManager) {
|
|
1658
|
-
console.log(` ${
|
|
1696
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.packageManager)}`);
|
|
1659
1697
|
}
|
|
1660
1698
|
if (stack.linter && stack.formatter && stack.linter.name === stack.formatter.name) {
|
|
1661
|
-
console.log(` ${
|
|
1699
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.linter)} (lint + format)`);
|
|
1662
1700
|
} else {
|
|
1663
1701
|
if (stack.linter) {
|
|
1664
|
-
console.log(` ${
|
|
1702
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.linter)}`);
|
|
1665
1703
|
}
|
|
1666
1704
|
if (stack.formatter) {
|
|
1667
|
-
console.log(` ${
|
|
1705
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.formatter)}`);
|
|
1668
1706
|
}
|
|
1669
1707
|
}
|
|
1670
1708
|
if (stack.testRunner) {
|
|
1671
|
-
console.log(` ${
|
|
1709
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.testRunner)}`);
|
|
1672
1710
|
}
|
|
1673
1711
|
console.log("");
|
|
1674
1712
|
for (const pkg of packages) {
|
|
@@ -1679,13 +1717,13 @@ ${import_chalk5.default.bold(`Detected: (monorepo, ${packages.length} packages)`
|
|
|
1679
1717
|
);
|
|
1680
1718
|
if (packagesWithDirs.length > 0) {
|
|
1681
1719
|
console.log(`
|
|
1682
|
-
${
|
|
1720
|
+
${import_chalk6.default.bold("Structure:")}`);
|
|
1683
1721
|
for (const pkg of packagesWithDirs) {
|
|
1684
1722
|
const groups = groupByRole(pkg.structure.directories);
|
|
1685
1723
|
if (groups.length === 0) continue;
|
|
1686
1724
|
console.log(` ${pkg.relativePath}:`);
|
|
1687
1725
|
for (const group of groups) {
|
|
1688
|
-
console.log(` ${
|
|
1726
|
+
console.log(` ${import_chalk6.default.green("\u2713")} ${formatRoleGroup(group)}`);
|
|
1689
1727
|
}
|
|
1690
1728
|
}
|
|
1691
1729
|
}
|
|
@@ -1766,7 +1804,7 @@ function displayConventions(scanResult) {
|
|
|
1766
1804
|
const conventionEntries = Object.entries(scanResult.conventions);
|
|
1767
1805
|
if (conventionEntries.length === 0) return;
|
|
1768
1806
|
console.log(`
|
|
1769
|
-
${
|
|
1807
|
+
${import_chalk7.default.bold("Conventions:")}`);
|
|
1770
1808
|
for (const [key, convention] of conventionEntries) {
|
|
1771
1809
|
if (convention.confidence === "low") continue;
|
|
1772
1810
|
const label = import_types3.CONVENTION_LABELS[key] ?? key;
|
|
@@ -1774,19 +1812,19 @@ ${import_chalk6.default.bold("Conventions:")}`);
|
|
|
1774
1812
|
const pkgValues = scanResult.packages.filter((pkg) => pkg.conventions[key] && pkg.conventions[key].confidence !== "low").map((pkg) => ({ relativePath: pkg.relativePath, convention: pkg.conventions[key] }));
|
|
1775
1813
|
const allSame = pkgValues.every((pv) => pv.convention.value === convention.value);
|
|
1776
1814
|
if (allSame || pkgValues.length <= 1) {
|
|
1777
|
-
const ind = convention.confidence === "high" ?
|
|
1778
|
-
const detail =
|
|
1815
|
+
const ind = convention.confidence === "high" ? import_chalk7.default.green("\u2713") : import_chalk7.default.yellow("~");
|
|
1816
|
+
const detail = import_chalk7.default.dim(`(${confidenceLabel(convention)})`);
|
|
1779
1817
|
console.log(` ${ind} ${label}: ${convention.value} ${detail}`);
|
|
1780
1818
|
} else {
|
|
1781
|
-
console.log(` ${
|
|
1819
|
+
console.log(` ${import_chalk7.default.yellow("~")} ${label}: varies by package`);
|
|
1782
1820
|
for (const pv of pkgValues) {
|
|
1783
1821
|
const pct = Math.round(pv.convention.consistency);
|
|
1784
1822
|
console.log(` ${pv.relativePath}: ${pv.convention.value} (${pct}%)`);
|
|
1785
1823
|
}
|
|
1786
1824
|
}
|
|
1787
1825
|
} else {
|
|
1788
|
-
const ind = convention.confidence === "high" ?
|
|
1789
|
-
const detail =
|
|
1826
|
+
const ind = convention.confidence === "high" ? import_chalk7.default.green("\u2713") : import_chalk7.default.yellow("~");
|
|
1827
|
+
const detail = import_chalk7.default.dim(`(${confidenceLabel(convention)})`);
|
|
1790
1828
|
console.log(` ${ind} ${label}: ${convention.value} ${detail}`);
|
|
1791
1829
|
}
|
|
1792
1830
|
}
|
|
@@ -1794,7 +1832,7 @@ ${import_chalk6.default.bold("Conventions:")}`);
|
|
|
1794
1832
|
function displaySummarySection(scanResult) {
|
|
1795
1833
|
const pkgCount = scanResult.packages.length > 1 ? scanResult.packages.length : void 0;
|
|
1796
1834
|
console.log(`
|
|
1797
|
-
${
|
|
1835
|
+
${import_chalk7.default.bold("Summary:")}`);
|
|
1798
1836
|
console.log(` ${formatSummary(scanResult.statistics, pkgCount)}`);
|
|
1799
1837
|
const ext = formatExtensions(scanResult.statistics.filesByExtension);
|
|
1800
1838
|
if (ext) {
|
|
@@ -1808,47 +1846,47 @@ function displayScanResults(scanResult) {
|
|
|
1808
1846
|
}
|
|
1809
1847
|
const { stack } = scanResult;
|
|
1810
1848
|
console.log(`
|
|
1811
|
-
${
|
|
1849
|
+
${import_chalk7.default.bold("Detected:")}`);
|
|
1812
1850
|
if (stack.framework) {
|
|
1813
|
-
console.log(` ${
|
|
1851
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.framework, import_types3.FRAMEWORK_NAMES)}`);
|
|
1814
1852
|
}
|
|
1815
|
-
console.log(` ${
|
|
1853
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.language)}`);
|
|
1816
1854
|
if (stack.styling) {
|
|
1817
|
-
console.log(` ${
|
|
1855
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.styling, import_types3.STYLING_NAMES)}`);
|
|
1818
1856
|
}
|
|
1819
1857
|
if (stack.backend) {
|
|
1820
|
-
console.log(` ${
|
|
1858
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.backend, import_types3.FRAMEWORK_NAMES)}`);
|
|
1821
1859
|
}
|
|
1822
1860
|
if (stack.orm) {
|
|
1823
|
-
console.log(` ${
|
|
1861
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.orm, import_types3.ORM_NAMES)}`);
|
|
1824
1862
|
}
|
|
1825
1863
|
if (stack.linter && stack.formatter && stack.linter.name === stack.formatter.name) {
|
|
1826
|
-
console.log(` ${
|
|
1864
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.linter)} (lint + format)`);
|
|
1827
1865
|
} else {
|
|
1828
1866
|
if (stack.linter) {
|
|
1829
|
-
console.log(` ${
|
|
1867
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.linter)}`);
|
|
1830
1868
|
}
|
|
1831
1869
|
if (stack.formatter) {
|
|
1832
|
-
console.log(` ${
|
|
1870
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.formatter)}`);
|
|
1833
1871
|
}
|
|
1834
1872
|
}
|
|
1835
1873
|
if (stack.testRunner) {
|
|
1836
|
-
console.log(` ${
|
|
1874
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.testRunner)}`);
|
|
1837
1875
|
}
|
|
1838
1876
|
if (stack.packageManager) {
|
|
1839
|
-
console.log(` ${
|
|
1877
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(stack.packageManager)}`);
|
|
1840
1878
|
}
|
|
1841
1879
|
if (stack.libraries.length > 0) {
|
|
1842
1880
|
for (const lib of stack.libraries) {
|
|
1843
|
-
console.log(` ${
|
|
1881
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatItem(lib, import_types3.LIBRARY_NAMES)}`);
|
|
1844
1882
|
}
|
|
1845
1883
|
}
|
|
1846
1884
|
const groups = groupByRole(scanResult.structure.directories);
|
|
1847
1885
|
if (groups.length > 0) {
|
|
1848
1886
|
console.log(`
|
|
1849
|
-
${
|
|
1887
|
+
${import_chalk7.default.bold("Structure:")}`);
|
|
1850
1888
|
for (const group of groups) {
|
|
1851
|
-
console.log(` ${
|
|
1889
|
+
console.log(` ${import_chalk7.default.green("\u2713")} ${formatRoleGroup(group)}`);
|
|
1852
1890
|
}
|
|
1853
1891
|
}
|
|
1854
1892
|
displayConventions(scanResult);
|
|
@@ -1858,25 +1896,25 @@ ${import_chalk6.default.bold("Structure:")}`);
|
|
|
1858
1896
|
function displayRulesPreview(config) {
|
|
1859
1897
|
const root = config.packages.find((p) => p.path === ".") ?? config.packages[0];
|
|
1860
1898
|
console.log(
|
|
1861
|
-
`${
|
|
1899
|
+
`${import_chalk7.default.bold("Rules:")} ${import_chalk7.default.dim("(warns on violation; use --enforce in CI to block)")}`
|
|
1862
1900
|
);
|
|
1863
|
-
console.log(` ${
|
|
1901
|
+
console.log(` ${import_chalk7.default.dim("\u2022")} Max file size: ${config.rules.maxFileLines} lines`);
|
|
1864
1902
|
if (config.rules.testCoverage > 0 && root?.structure?.testPattern) {
|
|
1865
1903
|
console.log(
|
|
1866
|
-
` ${
|
|
1904
|
+
` ${import_chalk7.default.dim("\u2022")} Test coverage target: ${config.rules.testCoverage}% (${root.structure.testPattern})`
|
|
1867
1905
|
);
|
|
1868
1906
|
} else if (config.rules.testCoverage > 0) {
|
|
1869
|
-
console.log(` ${
|
|
1907
|
+
console.log(` ${import_chalk7.default.dim("\u2022")} Test coverage target: ${config.rules.testCoverage}%`);
|
|
1870
1908
|
} else {
|
|
1871
|
-
console.log(` ${
|
|
1909
|
+
console.log(` ${import_chalk7.default.dim("\u2022")} Test coverage target: disabled`);
|
|
1872
1910
|
}
|
|
1873
1911
|
if (config.rules.enforceNaming && root?.conventions?.fileNaming) {
|
|
1874
|
-
console.log(` ${
|
|
1912
|
+
console.log(` ${import_chalk7.default.dim("\u2022")} Enforce file naming: ${root.conventions.fileNaming}`);
|
|
1875
1913
|
} else {
|
|
1876
|
-
console.log(` ${
|
|
1914
|
+
console.log(` ${import_chalk7.default.dim("\u2022")} Enforce file naming: no`);
|
|
1877
1915
|
}
|
|
1878
1916
|
console.log(
|
|
1879
|
-
` ${
|
|
1917
|
+
` ${import_chalk7.default.dim("\u2022")} Enforce boundaries: ${config.rules.enforceBoundaries ? "yes" : "no"}`
|
|
1880
1918
|
);
|
|
1881
1919
|
console.log("");
|
|
1882
1920
|
}
|
|
@@ -2201,7 +2239,7 @@ async function configCommand(options, cwd) {
|
|
|
2201
2239
|
}
|
|
2202
2240
|
const configPath = path9.join(projectRoot, CONFIG_FILE3);
|
|
2203
2241
|
if (!fs10.existsSync(configPath)) {
|
|
2204
|
-
console.log(`${
|
|
2242
|
+
console.log(`${import_chalk8.default.yellow("!")} No config found. Run ${import_chalk8.default.cyan("viberails")} first.`);
|
|
2205
2243
|
return;
|
|
2206
2244
|
}
|
|
2207
2245
|
if (!options.suppressIntro) {
|
|
@@ -2292,22 +2330,22 @@ async function rescanAndMerge(projectRoot, config) {
|
|
|
2292
2330
|
var fs13 = __toESM(require("fs"), 1);
|
|
2293
2331
|
var path13 = __toESM(require("path"), 1);
|
|
2294
2332
|
var import_config7 = require("@viberails/config");
|
|
2295
|
-
var
|
|
2333
|
+
var import_chalk10 = __toESM(require("chalk"), 1);
|
|
2296
2334
|
|
|
2297
2335
|
// src/commands/fix-helpers.ts
|
|
2298
2336
|
var import_node_child_process3 = require("child_process");
|
|
2299
|
-
var
|
|
2337
|
+
var import_chalk9 = __toESM(require("chalk"), 1);
|
|
2300
2338
|
function printPlan(renames, stubs) {
|
|
2301
2339
|
if (renames.length > 0) {
|
|
2302
|
-
console.log(
|
|
2340
|
+
console.log(import_chalk9.default.bold("\nFile renames:"));
|
|
2303
2341
|
for (const r of renames) {
|
|
2304
|
-
console.log(` ${
|
|
2342
|
+
console.log(` ${import_chalk9.default.red(r.oldPath)} \u2192 ${import_chalk9.default.green(r.newPath)}`);
|
|
2305
2343
|
}
|
|
2306
2344
|
}
|
|
2307
2345
|
if (stubs.length > 0) {
|
|
2308
|
-
console.log(
|
|
2346
|
+
console.log(import_chalk9.default.bold("\nTest stubs to create:"));
|
|
2309
2347
|
for (const s of stubs) {
|
|
2310
|
-
console.log(` ${
|
|
2348
|
+
console.log(` ${import_chalk9.default.green("+")} ${s.path}`);
|
|
2311
2349
|
}
|
|
2312
2350
|
}
|
|
2313
2351
|
}
|
|
@@ -2635,13 +2673,13 @@ async function fixCommand(options, cwd) {
|
|
|
2635
2673
|
const startDir = cwd ?? process.cwd();
|
|
2636
2674
|
const projectRoot = findProjectRoot(startDir);
|
|
2637
2675
|
if (!projectRoot) {
|
|
2638
|
-
console.error(`${
|
|
2676
|
+
console.error(`${import_chalk10.default.red("Error:")} No package.json found. Are you in a JS/TS project?`);
|
|
2639
2677
|
return 1;
|
|
2640
2678
|
}
|
|
2641
2679
|
const configPath = path13.join(projectRoot, CONFIG_FILE4);
|
|
2642
2680
|
if (!fs13.existsSync(configPath)) {
|
|
2643
2681
|
console.error(
|
|
2644
|
-
`${
|
|
2682
|
+
`${import_chalk10.default.red("Error:")} No viberails.config.json found. Run \`viberails init\` first.`
|
|
2645
2683
|
);
|
|
2646
2684
|
return 1;
|
|
2647
2685
|
}
|
|
@@ -2650,7 +2688,7 @@ async function fixCommand(options, cwd) {
|
|
|
2650
2688
|
const isDirty = checkGitDirty(projectRoot);
|
|
2651
2689
|
if (isDirty) {
|
|
2652
2690
|
console.log(
|
|
2653
|
-
|
|
2691
|
+
import_chalk10.default.yellow("Warning: You have uncommitted changes. Consider committing first.")
|
|
2654
2692
|
);
|
|
2655
2693
|
}
|
|
2656
2694
|
}
|
|
@@ -2697,41 +2735,41 @@ async function fixCommand(options, cwd) {
|
|
|
2697
2735
|
return blockedOldBareNames.has(bare);
|
|
2698
2736
|
});
|
|
2699
2737
|
if (safeRenames.length === 0 && testStubs.length === 0 && skippedRenames.length === 0) {
|
|
2700
|
-
console.log(`${
|
|
2738
|
+
console.log(`${import_chalk10.default.green("\u2713")} No fixable violations found.`);
|
|
2701
2739
|
return 0;
|
|
2702
2740
|
}
|
|
2703
2741
|
printPlan(safeRenames, testStubs);
|
|
2704
2742
|
if (skippedRenames.length > 0) {
|
|
2705
2743
|
console.log("");
|
|
2706
2744
|
console.log(
|
|
2707
|
-
|
|
2745
|
+
import_chalk10.default.yellow(
|
|
2708
2746
|
`Skipping ${skippedRenames.length} rename${skippedRenames.length > 1 ? "s" : ""} \u2014 aliased imports would break:`
|
|
2709
2747
|
)
|
|
2710
2748
|
);
|
|
2711
2749
|
for (const r of skippedRenames.slice(0, 5)) {
|
|
2712
|
-
console.log(
|
|
2750
|
+
console.log(import_chalk10.default.dim(` ${r.oldPath} \u2192 ${r.newPath}`));
|
|
2713
2751
|
}
|
|
2714
2752
|
if (skippedRenames.length > 5) {
|
|
2715
|
-
console.log(
|
|
2753
|
+
console.log(import_chalk10.default.dim(` ... and ${skippedRenames.length - 5} more`));
|
|
2716
2754
|
}
|
|
2717
2755
|
console.log("");
|
|
2718
|
-
console.log(
|
|
2756
|
+
console.log(import_chalk10.default.yellow("Affected aliased imports:"));
|
|
2719
2757
|
for (const alias of aliasImports.slice(0, 5)) {
|
|
2720
2758
|
const relFile = path13.relative(projectRoot, alias.file);
|
|
2721
|
-
console.log(
|
|
2759
|
+
console.log(import_chalk10.default.dim(` ${relFile}:${alias.line} \u2014 ${alias.specifier}`));
|
|
2722
2760
|
}
|
|
2723
2761
|
if (aliasImports.length > 5) {
|
|
2724
|
-
console.log(
|
|
2762
|
+
console.log(import_chalk10.default.dim(` ... and ${aliasImports.length - 5} more`));
|
|
2725
2763
|
}
|
|
2726
|
-
console.log(
|
|
2764
|
+
console.log(import_chalk10.default.dim(" Update these imports to relative paths first, then re-run fix."));
|
|
2727
2765
|
}
|
|
2728
2766
|
if (safeRenames.length === 0 && testStubs.length === 0) {
|
|
2729
2767
|
console.log(`
|
|
2730
|
-
${
|
|
2768
|
+
${import_chalk10.default.yellow("!")} No safe fixes to apply. Resolve aliased imports first.`);
|
|
2731
2769
|
return 0;
|
|
2732
2770
|
}
|
|
2733
2771
|
if (options.dryRun) {
|
|
2734
|
-
console.log(
|
|
2772
|
+
console.log(import_chalk10.default.dim("\nDry run \u2014 no changes applied."));
|
|
2735
2773
|
return 0;
|
|
2736
2774
|
}
|
|
2737
2775
|
if (!options.yes) {
|
|
@@ -2762,15 +2800,15 @@ ${import_chalk9.default.yellow("!")} No safe fixes to apply. Resolve aliased imp
|
|
|
2762
2800
|
}
|
|
2763
2801
|
console.log("");
|
|
2764
2802
|
if (renameCount > 0) {
|
|
2765
|
-
console.log(`${
|
|
2803
|
+
console.log(`${import_chalk10.default.green("\u2713")} Renamed ${renameCount} file${renameCount > 1 ? "s" : ""}`);
|
|
2766
2804
|
}
|
|
2767
2805
|
if (importUpdateCount > 0) {
|
|
2768
2806
|
console.log(
|
|
2769
|
-
`${
|
|
2807
|
+
`${import_chalk10.default.green("\u2713")} Updated ${importUpdateCount} import${importUpdateCount > 1 ? "s" : ""}`
|
|
2770
2808
|
);
|
|
2771
2809
|
}
|
|
2772
2810
|
if (stubCount > 0) {
|
|
2773
|
-
console.log(`${
|
|
2811
|
+
console.log(`${import_chalk10.default.green("\u2713")} Generated ${stubCount} test stub${stubCount > 1 ? "s" : ""}`);
|
|
2774
2812
|
}
|
|
2775
2813
|
return 0;
|
|
2776
2814
|
}
|
|
@@ -2781,13 +2819,13 @@ var path21 = __toESM(require("path"), 1);
|
|
|
2781
2819
|
var clack13 = __toESM(require("@clack/prompts"), 1);
|
|
2782
2820
|
var import_config9 = require("@viberails/config");
|
|
2783
2821
|
var import_scanner3 = require("@viberails/scanner");
|
|
2784
|
-
var
|
|
2822
|
+
var import_chalk16 = __toESM(require("chalk"), 1);
|
|
2785
2823
|
|
|
2786
2824
|
// src/utils/check-prerequisites.ts
|
|
2787
2825
|
var fs14 = __toESM(require("fs"), 1);
|
|
2788
2826
|
var path14 = __toESM(require("path"), 1);
|
|
2789
2827
|
var clack7 = __toESM(require("@clack/prompts"), 1);
|
|
2790
|
-
var
|
|
2828
|
+
var import_chalk11 = __toESM(require("chalk"), 1);
|
|
2791
2829
|
|
|
2792
2830
|
// src/utils/spawn-async.ts
|
|
2793
2831
|
var import_node_child_process4 = require("child_process");
|
|
@@ -2842,9 +2880,9 @@ function displayMissingPrereqs(prereqs) {
|
|
|
2842
2880
|
const missing = prereqs.filter((p) => !p.installed);
|
|
2843
2881
|
for (const m of missing) {
|
|
2844
2882
|
const suffix = m.affectedPackages ? ` \u2014 needed for coverage in: ${m.affectedPackages.join(", ")}` : ` \u2014 ${m.reason}`;
|
|
2845
|
-
console.log(` ${
|
|
2883
|
+
console.log(` ${import_chalk11.default.yellow("!")} ${m.label} not installed${suffix}`);
|
|
2846
2884
|
if (m.installCommand) {
|
|
2847
|
-
console.log(` Install: ${
|
|
2885
|
+
console.log(` Install: ${import_chalk11.default.cyan(m.installCommand)}`);
|
|
2848
2886
|
}
|
|
2849
2887
|
}
|
|
2850
2888
|
}
|
|
@@ -3169,7 +3207,7 @@ async function handleIntegrations(state, opts) {
|
|
|
3169
3207
|
}
|
|
3170
3208
|
|
|
3171
3209
|
// src/utils/prompt-main-menu-hints.ts
|
|
3172
|
-
var
|
|
3210
|
+
var import_chalk12 = __toESM(require("chalk"), 1);
|
|
3173
3211
|
function fileLimitsHint(config) {
|
|
3174
3212
|
const max = config.rules.maxFileLines;
|
|
3175
3213
|
const test = config.rules.maxTestFileLines;
|
|
@@ -3188,7 +3226,7 @@ function fileNamingHint(config, scanResult) {
|
|
|
3188
3226
|
return "mixed \u2014 will not enforce if skipped";
|
|
3189
3227
|
}
|
|
3190
3228
|
function fileNamingStatus(config) {
|
|
3191
|
-
if (!config.rules.enforceNaming) return "
|
|
3229
|
+
if (!config.rules.enforceNaming) return "unconfigured";
|
|
3192
3230
|
const rootPkg = getRootPackage(config.packages);
|
|
3193
3231
|
return rootPkg.conventions?.fileNaming ? "ok" : "needs-input";
|
|
3194
3232
|
}
|
|
@@ -3215,28 +3253,27 @@ function coverageHint(config, hasTestRunner) {
|
|
|
3215
3253
|
function advancedNamingHint(config) {
|
|
3216
3254
|
const rootPkg = getRootPackage(config.packages);
|
|
3217
3255
|
if (!config.rules.enforceNaming) return "not enforced";
|
|
3218
|
-
const
|
|
3219
|
-
const
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
parts.
|
|
3227
|
-
return parts.join(import_chalk11.default.dim(", "));
|
|
3256
|
+
const ok = import_chalk12.default.green("\u2713");
|
|
3257
|
+
const no = import_chalk12.default.dim("\u2717");
|
|
3258
|
+
const parts = [
|
|
3259
|
+
`${rootPkg.conventions?.fileNaming ? ok : no} file naming`,
|
|
3260
|
+
`${rootPkg.conventions?.componentNaming ? ok : no} components`,
|
|
3261
|
+
`${rootPkg.conventions?.hookNaming ? ok : no} hooks`,
|
|
3262
|
+
`${rootPkg.conventions?.importAlias ? ok : no} alias`
|
|
3263
|
+
];
|
|
3264
|
+
return parts.join(import_chalk12.default.dim(", "));
|
|
3228
3265
|
}
|
|
3229
3266
|
function integrationsHint(state) {
|
|
3230
3267
|
if (!state.visited.integrations || !state.integrations)
|
|
3231
3268
|
return "not configured \u2014 select to set up";
|
|
3232
3269
|
const items = [];
|
|
3233
|
-
if (state.integrations.preCommitHook) items.push(
|
|
3234
|
-
if (state.integrations.typecheckHook) items.push(
|
|
3235
|
-
if (state.integrations.lintHook) items.push(
|
|
3236
|
-
if (state.integrations.claudeCodeHook) items.push(
|
|
3237
|
-
if (state.integrations.claudeMdRef) items.push(
|
|
3238
|
-
if (state.integrations.githubAction) items.push(
|
|
3239
|
-
return items.length > 0 ? items.join(
|
|
3270
|
+
if (state.integrations.preCommitHook) items.push(import_chalk12.default.green("pre-commit"));
|
|
3271
|
+
if (state.integrations.typecheckHook) items.push(import_chalk12.default.green("typecheck"));
|
|
3272
|
+
if (state.integrations.lintHook) items.push(import_chalk12.default.green("lint"));
|
|
3273
|
+
if (state.integrations.claudeCodeHook) items.push(import_chalk12.default.green("Claude"));
|
|
3274
|
+
if (state.integrations.claudeMdRef) items.push(import_chalk12.default.green("CLAUDE.md"));
|
|
3275
|
+
if (state.integrations.githubAction) items.push(import_chalk12.default.green("CI"));
|
|
3276
|
+
return items.length > 0 ? items.join(import_chalk12.default.dim(" \xB7 ")) : "none selected";
|
|
3240
3277
|
}
|
|
3241
3278
|
function packageOverridesHint(config) {
|
|
3242
3279
|
const rootNaming = getRootPackage(config.packages).conventions?.fileNaming;
|
|
@@ -3255,10 +3292,15 @@ function boundariesHint(config, state) {
|
|
|
3255
3292
|
return `${ruleCount} rules across ${pkgCount} packages`;
|
|
3256
3293
|
}
|
|
3257
3294
|
function advancedNamingStatus(config) {
|
|
3258
|
-
if (!config.rules.enforceNaming) return "
|
|
3295
|
+
if (!config.rules.enforceNaming) return "unconfigured";
|
|
3259
3296
|
const rootPkg = getRootPackage(config.packages);
|
|
3260
|
-
const
|
|
3261
|
-
|
|
3297
|
+
const hasFile = !!rootPkg.conventions?.fileNaming;
|
|
3298
|
+
const hasComp = !!rootPkg.conventions?.componentNaming;
|
|
3299
|
+
const hasHook = !!rootPkg.conventions?.hookNaming;
|
|
3300
|
+
const hasAlias = !!rootPkg.conventions?.importAlias;
|
|
3301
|
+
if (hasFile && hasComp && hasHook && hasAlias) return "ok";
|
|
3302
|
+
if (hasFile || hasComp || hasHook || hasAlias) return "partial";
|
|
3303
|
+
return "unconfigured";
|
|
3262
3304
|
}
|
|
3263
3305
|
function packageOverridesStatus(config) {
|
|
3264
3306
|
const rootNaming = getRootPackage(config.packages).conventions?.fileNaming;
|
|
@@ -3269,15 +3311,15 @@ function packageOverridesStatus(config) {
|
|
|
3269
3311
|
return customized ? "ok" : "unconfigured";
|
|
3270
3312
|
}
|
|
3271
3313
|
function statusIcon(status) {
|
|
3272
|
-
if (status === "ok") return
|
|
3273
|
-
if (status === "needs-input") return
|
|
3274
|
-
if (status === "unconfigured") return
|
|
3275
|
-
return
|
|
3314
|
+
if (status === "ok") return import_chalk12.default.green("\u2713");
|
|
3315
|
+
if (status === "needs-input") return import_chalk12.default.yellow("?");
|
|
3316
|
+
if (status === "unconfigured") return import_chalk12.default.dim("-");
|
|
3317
|
+
return import_chalk12.default.yellow("~");
|
|
3276
3318
|
}
|
|
3277
3319
|
function buildMainMenuOptions(config, scanResult, state) {
|
|
3278
3320
|
const namingStatus = fileNamingStatus(config);
|
|
3279
|
-
const coverageStatus = config.rules.testCoverage === 0 ? "
|
|
3280
|
-
const missingTestsStatus = config.rules.enforceMissingTests ? "ok" : "
|
|
3321
|
+
const coverageStatus = config.rules.testCoverage === 0 ? "unconfigured" : !state.hasTestRunner ? "partial" : "ok";
|
|
3322
|
+
const missingTestsStatus = config.rules.enforceMissingTests ? "ok" : "unconfigured";
|
|
3281
3323
|
const options = [
|
|
3282
3324
|
{
|
|
3283
3325
|
value: "fileLimits",
|
|
@@ -3403,7 +3445,7 @@ function updateGitignore(projectRoot) {
|
|
|
3403
3445
|
// src/commands/init-hooks.ts
|
|
3404
3446
|
var fs18 = __toESM(require("fs"), 1);
|
|
3405
3447
|
var path18 = __toESM(require("path"), 1);
|
|
3406
|
-
var
|
|
3448
|
+
var import_chalk13 = __toESM(require("chalk"), 1);
|
|
3407
3449
|
var import_yaml = require("yaml");
|
|
3408
3450
|
|
|
3409
3451
|
// src/commands/resolve-typecheck.ts
|
|
@@ -3448,13 +3490,13 @@ function setupPreCommitHook(projectRoot) {
|
|
|
3448
3490
|
const lefthookPath = path18.join(projectRoot, "lefthook.yml");
|
|
3449
3491
|
if (fs18.existsSync(lefthookPath)) {
|
|
3450
3492
|
addLefthookPreCommit(lefthookPath);
|
|
3451
|
-
console.log(` ${
|
|
3493
|
+
console.log(` ${import_chalk13.default.green("\u2713")} lefthook.yml \u2014 added viberails pre-commit`);
|
|
3452
3494
|
return "lefthook.yml";
|
|
3453
3495
|
}
|
|
3454
3496
|
const huskyDir = path18.join(projectRoot, ".husky");
|
|
3455
3497
|
if (fs18.existsSync(huskyDir)) {
|
|
3456
3498
|
writeHuskyPreCommit(huskyDir);
|
|
3457
|
-
console.log(` ${
|
|
3499
|
+
console.log(` ${import_chalk13.default.green("\u2713")} .husky/pre-commit \u2014 added viberails check`);
|
|
3458
3500
|
return ".husky/pre-commit";
|
|
3459
3501
|
}
|
|
3460
3502
|
const gitDir = path18.join(projectRoot, ".git");
|
|
@@ -3464,7 +3506,7 @@ function setupPreCommitHook(projectRoot) {
|
|
|
3464
3506
|
fs18.mkdirSync(hooksDir, { recursive: true });
|
|
3465
3507
|
}
|
|
3466
3508
|
writeGitHookPreCommit(hooksDir);
|
|
3467
|
-
console.log(` ${
|
|
3509
|
+
console.log(` ${import_chalk13.default.green("\u2713")} .git/hooks/pre-commit`);
|
|
3468
3510
|
return ".git/hooks/pre-commit";
|
|
3469
3511
|
}
|
|
3470
3512
|
return void 0;
|
|
@@ -3525,9 +3567,9 @@ function setupClaudeCodeHook(projectRoot) {
|
|
|
3525
3567
|
settings = JSON.parse(fs18.readFileSync(settingsPath, "utf-8"));
|
|
3526
3568
|
} catch {
|
|
3527
3569
|
console.warn(
|
|
3528
|
-
` ${
|
|
3570
|
+
` ${import_chalk13.default.yellow("!")} .claude/settings.json contains invalid JSON \u2014 skipping hook setup`
|
|
3529
3571
|
);
|
|
3530
|
-
console.warn(` Fix the JSON manually, then re-run ${
|
|
3572
|
+
console.warn(` Fix the JSON manually, then re-run ${import_chalk13.default.cyan("viberails init --force")}`);
|
|
3531
3573
|
return;
|
|
3532
3574
|
}
|
|
3533
3575
|
}
|
|
@@ -3550,7 +3592,7 @@ function setupClaudeCodeHook(projectRoot) {
|
|
|
3550
3592
|
settings.hooks = hooks;
|
|
3551
3593
|
fs18.writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
|
|
3552
3594
|
`);
|
|
3553
|
-
console.log(` ${
|
|
3595
|
+
console.log(` ${import_chalk13.default.green("\u2713")} .claude/settings.json \u2014 added viberails PostToolUse hook`);
|
|
3554
3596
|
}
|
|
3555
3597
|
function setupClaudeMdReference(projectRoot) {
|
|
3556
3598
|
const claudeMdPath = path18.join(projectRoot, "CLAUDE.md");
|
|
@@ -3562,7 +3604,7 @@ function setupClaudeMdReference(projectRoot) {
|
|
|
3562
3604
|
const ref = "\n@.viberails/context.md\n";
|
|
3563
3605
|
const prefix = content.length === 0 ? "" : content.trimEnd();
|
|
3564
3606
|
fs18.writeFileSync(claudeMdPath, prefix + ref);
|
|
3565
|
-
console.log(` ${
|
|
3607
|
+
console.log(` ${import_chalk13.default.green("\u2713")} CLAUDE.md \u2014 added @.viberails/context.md reference`);
|
|
3566
3608
|
}
|
|
3567
3609
|
function setupGithubAction(projectRoot, packageManager, options) {
|
|
3568
3610
|
const workflowDir = path18.join(projectRoot, ".github", "workflows");
|
|
@@ -3648,7 +3690,7 @@ ${cmd}
|
|
|
3648
3690
|
// src/commands/init-hooks-extra.ts
|
|
3649
3691
|
var fs19 = __toESM(require("fs"), 1);
|
|
3650
3692
|
var path19 = __toESM(require("path"), 1);
|
|
3651
|
-
var
|
|
3693
|
+
var import_chalk14 = __toESM(require("chalk"), 1);
|
|
3652
3694
|
var import_yaml2 = require("yaml");
|
|
3653
3695
|
function addPreCommitStep(projectRoot, name, command, marker, lefthookExtra) {
|
|
3654
3696
|
const lefthookPath = path19.join(projectRoot, "lefthook.yml");
|
|
@@ -3708,12 +3750,12 @@ ${command}
|
|
|
3708
3750
|
function setupTypecheckHook(projectRoot, packageManager) {
|
|
3709
3751
|
const resolved = resolveTypecheckCommand(projectRoot, packageManager);
|
|
3710
3752
|
if (!resolved.command) {
|
|
3711
|
-
console.log(` ${
|
|
3753
|
+
console.log(` ${import_chalk14.default.yellow("!")} Skipped typecheck hook: ${resolved.reason}`);
|
|
3712
3754
|
return void 0;
|
|
3713
3755
|
}
|
|
3714
3756
|
const target = addPreCommitStep(projectRoot, "typecheck", resolved.command, "typecheck");
|
|
3715
3757
|
if (target) {
|
|
3716
|
-
console.log(` ${
|
|
3758
|
+
console.log(` ${import_chalk14.default.green("\u2713")} ${target} \u2014 added typecheck (${resolved.label})`);
|
|
3717
3759
|
}
|
|
3718
3760
|
return target;
|
|
3719
3761
|
}
|
|
@@ -3734,7 +3776,7 @@ function setupLintHook(projectRoot, linter) {
|
|
|
3734
3776
|
}
|
|
3735
3777
|
const target = addPreCommitStep(projectRoot, "lint", command, linter, lefthookExtra);
|
|
3736
3778
|
if (target) {
|
|
3737
|
-
console.log(` ${
|
|
3779
|
+
console.log(` ${import_chalk14.default.green("\u2713")} ${target} \u2014 added ${linterName} lint check`);
|
|
3738
3780
|
}
|
|
3739
3781
|
return target;
|
|
3740
3782
|
}
|
|
@@ -3743,7 +3785,7 @@ function setupSelectedIntegrations(projectRoot, integrations, opts) {
|
|
|
3743
3785
|
if (integrations.preCommitHook) {
|
|
3744
3786
|
const t = setupPreCommitHook(projectRoot);
|
|
3745
3787
|
if (t && opts.lefthookExpected && !t.includes("lefthook")) {
|
|
3746
|
-
console.log(` ${
|
|
3788
|
+
console.log(` ${import_chalk14.default.yellow("!")} Lefthook install failed \u2014 fell back to ${t}`);
|
|
3747
3789
|
}
|
|
3748
3790
|
created.push(t ? `${t} \u2014 added viberails pre-commit` : "pre-commit hook skipped");
|
|
3749
3791
|
}
|
|
@@ -3779,7 +3821,7 @@ var path20 = __toESM(require("path"), 1);
|
|
|
3779
3821
|
var clack12 = __toESM(require("@clack/prompts"), 1);
|
|
3780
3822
|
var import_config8 = require("@viberails/config");
|
|
3781
3823
|
var import_scanner2 = require("@viberails/scanner");
|
|
3782
|
-
var
|
|
3824
|
+
var import_chalk15 = __toESM(require("chalk"), 1);
|
|
3783
3825
|
|
|
3784
3826
|
// src/utils/filter-confidence.ts
|
|
3785
3827
|
function filterHighConfidence(conventions, meta) {
|
|
@@ -3815,7 +3857,7 @@ async function initNonInteractive(projectRoot, configPath) {
|
|
|
3815
3857
|
const exempted = getExemptedPackages(config);
|
|
3816
3858
|
if (exempted.length > 0) {
|
|
3817
3859
|
console.log(
|
|
3818
|
-
` ${
|
|
3860
|
+
` ${import_chalk15.default.dim("Auto-exempted from coverage:")} ${exempted.join(", ")} ${import_chalk15.default.dim("(types-only)")}`
|
|
3819
3861
|
);
|
|
3820
3862
|
}
|
|
3821
3863
|
if (config.packages.length > 1) {
|
|
@@ -3852,14 +3894,14 @@ async function initNonInteractive(projectRoot, configPath) {
|
|
|
3852
3894
|
const hookManager = detectHookManager(projectRoot);
|
|
3853
3895
|
const hasHookManager = hookManager === "Lefthook" || hookManager === "Husky";
|
|
3854
3896
|
const preCommitTarget = hasHookManager ? setupPreCommitHook(projectRoot) : void 0;
|
|
3855
|
-
const ok =
|
|
3897
|
+
const ok = import_chalk15.default.green("\u2713");
|
|
3856
3898
|
const created = [
|
|
3857
3899
|
`${ok} ${path20.basename(configPath)}`,
|
|
3858
3900
|
`${ok} .viberails/context.md`,
|
|
3859
3901
|
`${ok} .viberails/scan-result.json`,
|
|
3860
3902
|
`${ok} .claude/settings.json \u2014 added viberails hook`,
|
|
3861
3903
|
`${ok} CLAUDE.md \u2014 added @.viberails/context.md reference`,
|
|
3862
|
-
preCommitTarget ? `${ok} ${preCommitTarget}` : `${
|
|
3904
|
+
preCommitTarget ? `${ok} ${preCommitTarget}` : `${import_chalk15.default.yellow("!")} pre-commit hook skipped (install lefthook or husky)`,
|
|
3863
3905
|
actionTarget ? `${ok} ${actionTarget} \u2014 blocks PRs on violations` : ""
|
|
3864
3906
|
].filter(Boolean);
|
|
3865
3907
|
if (hasHookManager && isTypeScript) setupTypecheckHook(projectRoot, rootPkgPm);
|
|
@@ -3884,8 +3926,8 @@ async function initCommand(options, cwd) {
|
|
|
3884
3926
|
return initInteractive(projectRoot, configPath, options);
|
|
3885
3927
|
}
|
|
3886
3928
|
console.log(
|
|
3887
|
-
`${
|
|
3888
|
-
Run ${
|
|
3929
|
+
`${import_chalk16.default.yellow("!")} viberails is already initialized.
|
|
3930
|
+
Run ${import_chalk16.default.cyan("viberails")} to review or edit the existing setup, ${import_chalk16.default.cyan("viberails sync")} to update generated files, or ${import_chalk16.default.cyan("viberails init --force")} to replace it.`
|
|
3889
3931
|
);
|
|
3890
3932
|
return;
|
|
3891
3933
|
}
|
|
@@ -3926,11 +3968,6 @@ async function initInteractive(projectRoot, configPath, options) {
|
|
|
3926
3968
|
);
|
|
3927
3969
|
}
|
|
3928
3970
|
const hasTestRunner = !!scanResult.stack.testRunner;
|
|
3929
|
-
if (!hasTestRunner) {
|
|
3930
|
-
clack13.log.info(
|
|
3931
|
-
"No test runner detected. Coverage checks are inactive until a test runner is installed.\nInstall a test runner (e.g. vitest) and re-run viberails init."
|
|
3932
|
-
);
|
|
3933
|
-
}
|
|
3934
3971
|
const hookManager = detectHookManager(projectRoot);
|
|
3935
3972
|
const coveragePrereqs = checkCoveragePrereqs(projectRoot, scanResult);
|
|
3936
3973
|
const rootPkgStack = (config.packages.find((p) => p.path === ".") ?? config.packages[0])?.stack;
|
|
@@ -3962,7 +3999,7 @@ async function initInteractive(projectRoot, configPath, options) {
|
|
|
3962
3999
|
writeGeneratedFiles(projectRoot, config, scanResult);
|
|
3963
4000
|
updateGitignore(projectRoot);
|
|
3964
4001
|
ws.stop("Configuration written");
|
|
3965
|
-
const ok =
|
|
4002
|
+
const ok = import_chalk16.default.green("\u2713");
|
|
3966
4003
|
clack13.log.step(`${ok} ${path21.basename(configPath)}`);
|
|
3967
4004
|
clack13.log.step(`${ok} .viberails/context.md`);
|
|
3968
4005
|
clack13.log.step(`${ok} .viberails/scan-result.json`);
|
|
@@ -3976,7 +4013,7 @@ async function initInteractive(projectRoot, configPath, options) {
|
|
|
3976
4013
|
}
|
|
3977
4014
|
clack13.outro(
|
|
3978
4015
|
`Done! Next: review viberails.config.json, then run viberails check
|
|
3979
|
-
${
|
|
4016
|
+
${import_chalk16.default.dim("Tip: use")} ${import_chalk16.default.cyan("viberails check --enforce")} ${import_chalk16.default.dim("in CI to block PRs on violations.")}`
|
|
3980
4017
|
);
|
|
3981
4018
|
}
|
|
3982
4019
|
|
|
@@ -3986,7 +4023,7 @@ var path22 = __toESM(require("path"), 1);
|
|
|
3986
4023
|
var clack14 = __toESM(require("@clack/prompts"), 1);
|
|
3987
4024
|
var import_config11 = require("@viberails/config");
|
|
3988
4025
|
var import_scanner4 = require("@viberails/scanner");
|
|
3989
|
-
var
|
|
4026
|
+
var import_chalk17 = __toESM(require("chalk"), 1);
|
|
3990
4027
|
var CONFIG_FILE6 = "viberails.config.json";
|
|
3991
4028
|
var SCAN_RESULT_FILE2 = ".viberails/scan-result.json";
|
|
3992
4029
|
function loadPreviousStats(projectRoot) {
|
|
@@ -4027,13 +4064,13 @@ async function syncCommand(options, cwd) {
|
|
|
4027
4064
|
const statsDelta = previousStats ? formatStatsDelta(previousStats, scanResult.statistics) : void 0;
|
|
4028
4065
|
if (changes.length > 0 || statsDelta) {
|
|
4029
4066
|
console.log(`
|
|
4030
|
-
${
|
|
4067
|
+
${import_chalk17.default.bold("Changes:")}`);
|
|
4031
4068
|
for (const change of changes) {
|
|
4032
|
-
const icon = change.type === "removed" ?
|
|
4069
|
+
const icon = change.type === "removed" ? import_chalk17.default.red("-") : import_chalk17.default.green("+");
|
|
4033
4070
|
console.log(` ${icon} ${change.description}`);
|
|
4034
4071
|
}
|
|
4035
4072
|
if (statsDelta) {
|
|
4036
|
-
console.log(` ${
|
|
4073
|
+
console.log(` ${import_chalk17.default.dim(statsDelta)}`);
|
|
4037
4074
|
}
|
|
4038
4075
|
}
|
|
4039
4076
|
if (options?.interactive) {
|
|
@@ -4082,18 +4119,18 @@ ${import_chalk16.default.bold("Changes:")}`);
|
|
|
4082
4119
|
`);
|
|
4083
4120
|
writeGeneratedFiles(projectRoot, merged, scanResult);
|
|
4084
4121
|
console.log(`
|
|
4085
|
-
${
|
|
4122
|
+
${import_chalk17.default.bold("Synced:")}`);
|
|
4086
4123
|
if (configChanged) {
|
|
4087
|
-
console.log(` ${
|
|
4124
|
+
console.log(` ${import_chalk17.default.yellow("!")} ${CONFIG_FILE6} \u2014 updated (review changes)`);
|
|
4088
4125
|
} else {
|
|
4089
|
-
console.log(` ${
|
|
4126
|
+
console.log(` ${import_chalk17.default.green("\u2713")} ${CONFIG_FILE6} \u2014 unchanged`);
|
|
4090
4127
|
}
|
|
4091
|
-
console.log(` ${
|
|
4092
|
-
console.log(` ${
|
|
4128
|
+
console.log(` ${import_chalk17.default.green("\u2713")} .viberails/context.md \u2014 regenerated`);
|
|
4129
|
+
console.log(` ${import_chalk17.default.green("\u2713")} .viberails/scan-result.json \u2014 updated`);
|
|
4093
4130
|
}
|
|
4094
4131
|
|
|
4095
4132
|
// src/index.ts
|
|
4096
|
-
var VERSION = "0.6.
|
|
4133
|
+
var VERSION = "0.6.9";
|
|
4097
4134
|
var program = new import_commander.Command();
|
|
4098
4135
|
program.name("viberails").description("Guardrails for vibe coding").version(VERSION);
|
|
4099
4136
|
program.command("init", { isDefault: true }).description("Scan your project and set up enforcement guardrails").option("-y, --yes", "Non-interactive mode (use defaults, high-confidence only)").option("-f, --force", "Re-initialize, replacing existing config").action(async (options) => {
|
|
@@ -4101,7 +4138,7 @@ program.command("init", { isDefault: true }).description("Scan your project and
|
|
|
4101
4138
|
await initCommand(options);
|
|
4102
4139
|
} catch (err) {
|
|
4103
4140
|
const message = err instanceof Error ? err.message : String(err);
|
|
4104
|
-
console.error(`${
|
|
4141
|
+
console.error(`${import_chalk18.default.red("Error:")} ${message}`);
|
|
4105
4142
|
process.exit(1);
|
|
4106
4143
|
}
|
|
4107
4144
|
});
|
|
@@ -4110,7 +4147,7 @@ program.command("sync").description("Re-scan and update generated files").option
|
|
|
4110
4147
|
await syncCommand(options);
|
|
4111
4148
|
} catch (err) {
|
|
4112
4149
|
const message = err instanceof Error ? err.message : String(err);
|
|
4113
|
-
console.error(`${
|
|
4150
|
+
console.error(`${import_chalk18.default.red("Error:")} ${message}`);
|
|
4114
4151
|
process.exit(1);
|
|
4115
4152
|
}
|
|
4116
4153
|
});
|
|
@@ -4119,7 +4156,7 @@ program.command("config").description("Interactively edit existing config rules"
|
|
|
4119
4156
|
await configCommand(options);
|
|
4120
4157
|
} catch (err) {
|
|
4121
4158
|
const message = err instanceof Error ? err.message : String(err);
|
|
4122
|
-
console.error(`${
|
|
4159
|
+
console.error(`${import_chalk18.default.red("Error:")} ${message}`);
|
|
4123
4160
|
process.exit(1);
|
|
4124
4161
|
}
|
|
4125
4162
|
});
|
|
@@ -4140,7 +4177,7 @@ program.command("check").description("Check files against enforced rules").optio
|
|
|
4140
4177
|
process.exit(exitCode);
|
|
4141
4178
|
} catch (err) {
|
|
4142
4179
|
const message = err instanceof Error ? err.message : String(err);
|
|
4143
|
-
console.error(`${
|
|
4180
|
+
console.error(`${import_chalk18.default.red("Error:")} ${message}`);
|
|
4144
4181
|
process.exit(1);
|
|
4145
4182
|
}
|
|
4146
4183
|
}
|
|
@@ -4151,7 +4188,7 @@ program.command("fix").description("Auto-fix file naming violations and generate
|
|
|
4151
4188
|
process.exit(exitCode);
|
|
4152
4189
|
} catch (err) {
|
|
4153
4190
|
const message = err instanceof Error ? err.message : String(err);
|
|
4154
|
-
console.error(`${
|
|
4191
|
+
console.error(`${import_chalk18.default.red("Error:")} ${message}`);
|
|
4155
4192
|
process.exit(1);
|
|
4156
4193
|
}
|
|
4157
4194
|
});
|
|
@@ -4160,7 +4197,7 @@ program.command("boundaries").description("Display, infer, or inspect import bou
|
|
|
4160
4197
|
await boundariesCommand(options);
|
|
4161
4198
|
} catch (err) {
|
|
4162
4199
|
const message = err instanceof Error ? err.message : String(err);
|
|
4163
|
-
console.error(`${
|
|
4200
|
+
console.error(`${import_chalk18.default.red("Error:")} ${message}`);
|
|
4164
4201
|
process.exit(1);
|
|
4165
4202
|
}
|
|
4166
4203
|
});
|