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