viberails 0.6.7 → 0.6.8

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_chalk17 = __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_chalk2 = __toESM(require("chalk"), 1);
45
45
 
46
46
  // src/utils/find-project-root.ts
47
47
  var fs = __toESM(require("fs"), 1);
@@ -90,6 +90,7 @@ var HINT_AUTO_DETECT = "auto-detect";
90
90
 
91
91
  // src/utils/prompt-submenus.ts
92
92
  var clack = __toESM(require("@clack/prompts"), 1);
93
+ var import_chalk = __toESM(require("chalk"), 1);
93
94
  var FILE_NAMING_OPTIONS = [
94
95
  { value: "kebab-case", label: "kebab-case" },
95
96
  { value: "camelCase", label: "camelCase" },
@@ -153,7 +154,7 @@ async function promptNamingMenu(state) {
153
154
  {
154
155
  value: "enforceNaming",
155
156
  label: "Enforce file naming",
156
- hint: state.enforceNaming ? "yes" : "no"
157
+ hint: state.enforceNaming ? import_chalk.default.green("yes") : import_chalk.default.dim("no")
157
158
  }
158
159
  ];
159
160
  if (state.enforceNaming) {
@@ -271,7 +272,7 @@ async function promptTestingMenu(state) {
271
272
  {
272
273
  value: "enforceMissingTests",
273
274
  label: "Enforce missing tests",
274
- hint: state.enforceMissingTests ? "yes" : "no"
275
+ hint: state.enforceMissingTests ? import_chalk.default.green("yes") : import_chalk.default.dim("no")
275
276
  },
276
277
  {
277
278
  value: "testCoverage",
@@ -767,48 +768,48 @@ async function boundariesCommand(options, cwd) {
767
768
  }
768
769
  function displayRules(config) {
769
770
  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.`);
771
+ console.log(import_chalk2.default.yellow("No boundary rules configured."));
772
+ console.log(`Run ${import_chalk2.default.cyan("viberails boundaries --infer")} to generate rules.`);
772
773
  return;
773
774
  }
774
775
  const { deny } = config.boundaries;
775
776
  const sources = Object.keys(deny).filter((k) => deny[k].length > 0);
776
777
  const totalRules = sources.reduce((sum, k) => sum + deny[k].length, 0);
777
778
  console.log(`
778
- ${import_chalk.default.bold(`Boundary rules (${totalRules} deny rules):`)}
779
+ ${import_chalk2.default.bold(`Boundary rules (${totalRules} deny rules):`)}
779
780
  `);
780
781
  for (const source of sources) {
781
782
  for (const target of deny[source]) {
782
- console.log(` ${import_chalk.default.red("\u2717")} ${source} \u2192 ${target}`);
783
+ console.log(` ${import_chalk2.default.red("\u2717")} ${source} \u2192 ${target}`);
783
784
  }
784
785
  }
785
786
  console.log(
786
787
  `
787
- Enforcement: ${config.rules.enforceBoundaries ? import_chalk.default.green("on") : import_chalk.default.yellow("off")}`
788
+ Enforcement: ${config.rules.enforceBoundaries ? import_chalk2.default.green("on") : import_chalk2.default.yellow("off")}`
788
789
  );
789
790
  }
790
791
  async function inferAndDisplay(projectRoot, config, configPath) {
791
- console.log(import_chalk.default.dim("Analyzing imports..."));
792
+ console.log(import_chalk2.default.dim("Analyzing imports..."));
792
793
  const { buildImportGraph, inferBoundaries } = await import("@viberails/graph");
793
794
  const packages = config.packages.length > 1 ? resolveWorkspacePackages(projectRoot, config.packages) : void 0;
794
795
  const graph = await buildImportGraph(projectRoot, {
795
796
  packages,
796
797
  ignore: config.ignore
797
798
  });
798
- console.log(import_chalk.default.dim(`${graph.nodes.length} files, ${graph.edges.length} edges`));
799
+ console.log(import_chalk2.default.dim(`${graph.nodes.length} files, ${graph.edges.length} edges`));
799
800
  const inferred = inferBoundaries(graph);
800
801
  const sources = Object.keys(inferred.deny).filter((k) => inferred.deny[k].length > 0);
801
802
  const totalRules = sources.reduce((sum, k) => sum + inferred.deny[k].length, 0);
802
803
  if (totalRules === 0) {
803
- console.log(import_chalk.default.yellow("No boundary rules could be inferred."));
804
+ console.log(import_chalk2.default.yellow("No boundary rules could be inferred."));
804
805
  return;
805
806
  }
806
807
  console.log(`
807
- ${import_chalk.default.bold("Inferred boundary rules:")}
808
+ ${import_chalk2.default.bold("Inferred boundary rules:")}
808
809
  `);
809
810
  for (const source of sources) {
810
811
  for (const target of inferred.deny[source]) {
811
- console.log(` ${import_chalk.default.red("\u2717")} ${source} \u2192 ${target}`);
812
+ console.log(` ${import_chalk2.default.red("\u2717")} ${source} \u2192 ${target}`);
812
813
  }
813
814
  }
814
815
  console.log(`
@@ -820,11 +821,11 @@ ${import_chalk.default.bold("Inferred boundary rules:")}
820
821
  config.rules.enforceBoundaries = true;
821
822
  fs3.writeFileSync(configPath, `${JSON.stringify((0, import_config.compactConfig)(config), null, 2)}
822
823
  `);
823
- console.log(`${import_chalk.default.green("\u2713")} Saved ${totalRules} rules`);
824
+ console.log(`${import_chalk2.default.green("\u2713")} Saved ${totalRules} rules`);
824
825
  }
825
826
  }
826
827
  async function showGraph(projectRoot, config) {
827
- console.log(import_chalk.default.dim("Building import graph..."));
828
+ console.log(import_chalk2.default.dim("Building import graph..."));
828
829
  const { buildImportGraph } = await import("@viberails/graph");
829
830
  const packages = config.packages.length > 1 ? resolveWorkspacePackages(projectRoot, config.packages) : void 0;
830
831
  const graph = await buildImportGraph(projectRoot, {
@@ -832,20 +833,20 @@ async function showGraph(projectRoot, config) {
832
833
  ignore: config.ignore
833
834
  });
834
835
  console.log(`
835
- ${import_chalk.default.bold("Import dependency graph:")}
836
+ ${import_chalk2.default.bold("Import dependency graph:")}
836
837
  `);
837
838
  console.log(` ${graph.nodes.length} files, ${graph.edges.length} imports
838
839
  `);
839
840
  if (graph.packages.length > 0) {
840
841
  for (const pkg of graph.packages) {
841
842
  const deps = pkg.internalDeps.length > 0 ? `
842
- ${pkg.internalDeps.map((d) => ` \u2192 ${d}`).join("\n")}` : import_chalk.default.dim(" (no internal deps)");
843
+ ${pkg.internalDeps.map((d) => ` \u2192 ${d}`).join("\n")}` : import_chalk2.default.dim(" (no internal deps)");
843
844
  console.log(` ${pkg.name}${deps}`);
844
845
  }
845
846
  }
846
847
  if (graph.cycles.length > 0) {
847
848
  console.log(`
848
- ${import_chalk.default.yellow("Cycles detected:")}`);
849
+ ${import_chalk2.default.yellow("Cycles detected:")}`);
849
850
  for (const cycle of graph.cycles) {
850
851
  const paths = cycle.map((f) => path3.relative(projectRoot, f));
851
852
  console.log(` ${paths.join(" \u2192 ")}`);
@@ -857,7 +858,7 @@ ${import_chalk.default.yellow("Cycles detected:")}`);
857
858
  var fs7 = __toESM(require("fs"), 1);
858
859
  var path7 = __toESM(require("path"), 1);
859
860
  var import_config5 = require("@viberails/config");
860
- var import_chalk3 = __toESM(require("chalk"), 1);
861
+ var import_chalk4 = __toESM(require("chalk"), 1);
861
862
 
862
863
  // src/commands/check-config.ts
863
864
  var import_config2 = require("@viberails/config");
@@ -1249,7 +1250,7 @@ function collectSourceFiles(dir, projectRoot) {
1249
1250
  }
1250
1251
 
1251
1252
  // src/commands/check-print.ts
1252
- var import_chalk2 = __toESM(require("chalk"), 1);
1253
+ var import_chalk3 = __toESM(require("chalk"), 1);
1253
1254
  function printGroupedViolations(violations, limit) {
1254
1255
  const groups = /* @__PURE__ */ new Map();
1255
1256
  for (const v of violations) {
@@ -1277,12 +1278,12 @@ function printGroupedViolations(violations, limit) {
1277
1278
  const toShow = group.slice(0, remaining);
1278
1279
  const hidden = group.length - toShow.length;
1279
1280
  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}`);
1281
+ const icon = v.severity === "error" ? import_chalk3.default.red("\u2717") : import_chalk3.default.yellow("!");
1282
+ console.log(`${icon} ${import_chalk3.default.dim(v.rule)} ${v.file}: ${v.message}`);
1282
1283
  }
1283
1284
  totalShown += toShow.length;
1284
1285
  if (hidden > 0) {
1285
- console.log(import_chalk2.default.dim(` ... and ${hidden} more ${rule} violations`));
1286
+ console.log(import_chalk3.default.dim(` ... and ${hidden} more ${rule} violations`));
1286
1287
  }
1287
1288
  }
1288
1289
  }
@@ -1372,13 +1373,13 @@ async function checkCommand(options, cwd) {
1372
1373
  const startDir = cwd ?? process.cwd();
1373
1374
  const projectRoot = findProjectRoot(startDir);
1374
1375
  if (!projectRoot) {
1375
- console.error(`${import_chalk3.default.red("Error:")} No package.json found. Are you in a JS/TS project?`);
1376
+ console.error(`${import_chalk4.default.red("Error:")} No package.json found. Are you in a JS/TS project?`);
1376
1377
  return 1;
1377
1378
  }
1378
1379
  const configPath = path7.join(projectRoot, CONFIG_FILE2);
1379
1380
  if (!fs7.existsSync(configPath)) {
1380
1381
  console.error(
1381
- `${import_chalk3.default.red("Error:")} No viberails.config.json found. Run \`viberails init\` first.`
1382
+ `${import_chalk4.default.red("Error:")} No viberails.config.json found. Run \`viberails init\` first.`
1382
1383
  );
1383
1384
  return 1;
1384
1385
  }
@@ -1392,7 +1393,7 @@ async function checkCommand(options, cwd) {
1392
1393
  } else if (options.diffBase) {
1393
1394
  const diff = getDiffFiles(projectRoot, options.diffBase);
1394
1395
  if (diff.error && options.enforce) {
1395
- console.error(`${import_chalk3.default.red("Error:")} ${diff.error}`);
1396
+ console.error(`${import_chalk4.default.red("Error:")} ${diff.error}`);
1396
1397
  return 1;
1397
1398
  }
1398
1399
  filesToCheck = diff.all.filter((f) => SOURCE_EXTS.has(path7.extname(f)));
@@ -1407,13 +1408,13 @@ async function checkCommand(options, cwd) {
1407
1408
  if (options.format === "json") {
1408
1409
  console.log(JSON.stringify({ violations: [], checkedFiles: 0 }));
1409
1410
  } else {
1410
- console.log(`${import_chalk3.default.green("\u2713")} No files to check.`);
1411
+ console.log(`${import_chalk4.default.green("\u2713")} No files to check.`);
1411
1412
  }
1412
1413
  return 0;
1413
1414
  }
1414
1415
  const violations = [];
1415
1416
  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)) : () => {
1417
+ const log9 = options.format !== "json" && !options.hook && !options.quiet ? (msg) => process.stderr.write(import_chalk4.default.dim(msg)) : () => {
1417
1418
  };
1418
1419
  log9(" Checking files...");
1419
1420
  for (const file of filesToCheck) {
@@ -1508,7 +1509,7 @@ async function checkCommand(options, cwd) {
1508
1509
  return options.enforce && violations.length > 0 ? 1 : 0;
1509
1510
  }
1510
1511
  if (violations.length === 0) {
1511
- console.log(`${import_chalk3.default.green("\u2713")} ${filesToCheck.length} files checked \u2014 no violations`);
1512
+ console.log(`${import_chalk4.default.green("\u2713")} ${filesToCheck.length} files checked \u2014 no violations`);
1512
1513
  return 0;
1513
1514
  }
1514
1515
  if (!options.quiet) {
@@ -1516,7 +1517,7 @@ async function checkCommand(options, cwd) {
1516
1517
  }
1517
1518
  printSummary(violations);
1518
1519
  if (options.enforce) {
1519
- console.log(import_chalk3.default.red("Fix violations before committing."));
1520
+ console.log(import_chalk4.default.red("Fix violations before committing."));
1520
1521
  return 1;
1521
1522
  }
1522
1523
  return 0;
@@ -1574,14 +1575,14 @@ var path9 = __toESM(require("path"), 1);
1574
1575
  var clack6 = __toESM(require("@clack/prompts"), 1);
1575
1576
  var import_config6 = require("@viberails/config");
1576
1577
  var import_scanner = require("@viberails/scanner");
1577
- var import_chalk6 = __toESM(require("chalk"), 1);
1578
+ var import_chalk7 = __toESM(require("chalk"), 1);
1578
1579
 
1579
1580
  // src/display-text.ts
1580
1581
  var import_types4 = require("@viberails/types");
1581
1582
 
1582
1583
  // src/display.ts
1583
1584
  var import_types3 = require("@viberails/types");
1584
- var import_chalk5 = __toESM(require("chalk"), 1);
1585
+ var import_chalk6 = __toESM(require("chalk"), 1);
1585
1586
 
1586
1587
  // src/display-helpers.ts
1587
1588
  var import_types = require("@viberails/types");
@@ -1634,7 +1635,7 @@ function formatRoleGroup(group) {
1634
1635
 
1635
1636
  // src/display-monorepo.ts
1636
1637
  var import_types2 = require("@viberails/types");
1637
- var import_chalk4 = __toESM(require("chalk"), 1);
1638
+ var import_chalk5 = __toESM(require("chalk"), 1);
1638
1639
  function formatPackageSummary(pkg) {
1639
1640
  const parts = [];
1640
1641
  if (pkg.stack.framework) {
@@ -1651,23 +1652,23 @@ function formatPackageSummary(pkg) {
1651
1652
  function displayMonorepoResults(scanResult) {
1652
1653
  const { stack, packages } = scanResult;
1653
1654
  console.log(`
1654
- ${import_chalk4.default.bold(`Detected: (monorepo, ${packages.length} packages)`)}`);
1655
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatItem(stack.language)}`);
1655
+ ${import_chalk5.default.bold(`Detected: (monorepo, ${packages.length} packages)`)}`);
1656
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.language)}`);
1656
1657
  if (stack.packageManager) {
1657
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatItem(stack.packageManager)}`);
1658
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.packageManager)}`);
1658
1659
  }
1659
1660
  if (stack.linter && stack.formatter && stack.linter.name === stack.formatter.name) {
1660
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatItem(stack.linter)} (lint + format)`);
1661
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.linter)} (lint + format)`);
1661
1662
  } else {
1662
1663
  if (stack.linter) {
1663
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatItem(stack.linter)}`);
1664
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.linter)}`);
1664
1665
  }
1665
1666
  if (stack.formatter) {
1666
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatItem(stack.formatter)}`);
1667
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.formatter)}`);
1667
1668
  }
1668
1669
  }
1669
1670
  if (stack.testRunner) {
1670
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatItem(stack.testRunner)}`);
1671
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.testRunner)}`);
1671
1672
  }
1672
1673
  console.log("");
1673
1674
  for (const pkg of packages) {
@@ -1678,13 +1679,13 @@ ${import_chalk4.default.bold(`Detected: (monorepo, ${packages.length} packages)`
1678
1679
  );
1679
1680
  if (packagesWithDirs.length > 0) {
1680
1681
  console.log(`
1681
- ${import_chalk4.default.bold("Structure:")}`);
1682
+ ${import_chalk5.default.bold("Structure:")}`);
1682
1683
  for (const pkg of packagesWithDirs) {
1683
1684
  const groups = groupByRole(pkg.structure.directories);
1684
1685
  if (groups.length === 0) continue;
1685
1686
  console.log(` ${pkg.relativePath}:`);
1686
1687
  for (const group of groups) {
1687
- console.log(` ${import_chalk4.default.green("\u2713")} ${formatRoleGroup(group)}`);
1688
+ console.log(` ${import_chalk5.default.green("\u2713")} ${formatRoleGroup(group)}`);
1688
1689
  }
1689
1690
  }
1690
1691
  }
@@ -1765,7 +1766,7 @@ function displayConventions(scanResult) {
1765
1766
  const conventionEntries = Object.entries(scanResult.conventions);
1766
1767
  if (conventionEntries.length === 0) return;
1767
1768
  console.log(`
1768
- ${import_chalk5.default.bold("Conventions:")}`);
1769
+ ${import_chalk6.default.bold("Conventions:")}`);
1769
1770
  for (const [key, convention] of conventionEntries) {
1770
1771
  if (convention.confidence === "low") continue;
1771
1772
  const label = import_types3.CONVENTION_LABELS[key] ?? key;
@@ -1773,19 +1774,19 @@ ${import_chalk5.default.bold("Conventions:")}`);
1773
1774
  const pkgValues = scanResult.packages.filter((pkg) => pkg.conventions[key] && pkg.conventions[key].confidence !== "low").map((pkg) => ({ relativePath: pkg.relativePath, convention: pkg.conventions[key] }));
1774
1775
  const allSame = pkgValues.every((pv) => pv.convention.value === convention.value);
1775
1776
  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)})`);
1777
+ const ind = convention.confidence === "high" ? import_chalk6.default.green("\u2713") : import_chalk6.default.yellow("~");
1778
+ const detail = import_chalk6.default.dim(`(${confidenceLabel(convention)})`);
1778
1779
  console.log(` ${ind} ${label}: ${convention.value} ${detail}`);
1779
1780
  } else {
1780
- console.log(` ${import_chalk5.default.yellow("~")} ${label}: varies by package`);
1781
+ console.log(` ${import_chalk6.default.yellow("~")} ${label}: varies by package`);
1781
1782
  for (const pv of pkgValues) {
1782
1783
  const pct = Math.round(pv.convention.consistency);
1783
1784
  console.log(` ${pv.relativePath}: ${pv.convention.value} (${pct}%)`);
1784
1785
  }
1785
1786
  }
1786
1787
  } 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)})`);
1788
+ const ind = convention.confidence === "high" ? import_chalk6.default.green("\u2713") : import_chalk6.default.yellow("~");
1789
+ const detail = import_chalk6.default.dim(`(${confidenceLabel(convention)})`);
1789
1790
  console.log(` ${ind} ${label}: ${convention.value} ${detail}`);
1790
1791
  }
1791
1792
  }
@@ -1793,7 +1794,7 @@ ${import_chalk5.default.bold("Conventions:")}`);
1793
1794
  function displaySummarySection(scanResult) {
1794
1795
  const pkgCount = scanResult.packages.length > 1 ? scanResult.packages.length : void 0;
1795
1796
  console.log(`
1796
- ${import_chalk5.default.bold("Summary:")}`);
1797
+ ${import_chalk6.default.bold("Summary:")}`);
1797
1798
  console.log(` ${formatSummary(scanResult.statistics, pkgCount)}`);
1798
1799
  const ext = formatExtensions(scanResult.statistics.filesByExtension);
1799
1800
  if (ext) {
@@ -1807,47 +1808,47 @@ function displayScanResults(scanResult) {
1807
1808
  }
1808
1809
  const { stack } = scanResult;
1809
1810
  console.log(`
1810
- ${import_chalk5.default.bold("Detected:")}`);
1811
+ ${import_chalk6.default.bold("Detected:")}`);
1811
1812
  if (stack.framework) {
1812
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.framework, import_types3.FRAMEWORK_NAMES)}`);
1813
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.framework, import_types3.FRAMEWORK_NAMES)}`);
1813
1814
  }
1814
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.language)}`);
1815
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.language)}`);
1815
1816
  if (stack.styling) {
1816
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.styling, import_types3.STYLING_NAMES)}`);
1817
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.styling, import_types3.STYLING_NAMES)}`);
1817
1818
  }
1818
1819
  if (stack.backend) {
1819
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.backend, import_types3.FRAMEWORK_NAMES)}`);
1820
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.backend, import_types3.FRAMEWORK_NAMES)}`);
1820
1821
  }
1821
1822
  if (stack.orm) {
1822
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.orm, import_types3.ORM_NAMES)}`);
1823
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.orm, import_types3.ORM_NAMES)}`);
1823
1824
  }
1824
1825
  if (stack.linter && stack.formatter && stack.linter.name === stack.formatter.name) {
1825
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.linter)} (lint + format)`);
1826
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.linter)} (lint + format)`);
1826
1827
  } else {
1827
1828
  if (stack.linter) {
1828
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.linter)}`);
1829
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.linter)}`);
1829
1830
  }
1830
1831
  if (stack.formatter) {
1831
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.formatter)}`);
1832
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.formatter)}`);
1832
1833
  }
1833
1834
  }
1834
1835
  if (stack.testRunner) {
1835
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.testRunner)}`);
1836
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.testRunner)}`);
1836
1837
  }
1837
1838
  if (stack.packageManager) {
1838
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(stack.packageManager)}`);
1839
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(stack.packageManager)}`);
1839
1840
  }
1840
1841
  if (stack.libraries.length > 0) {
1841
1842
  for (const lib of stack.libraries) {
1842
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatItem(lib, import_types3.LIBRARY_NAMES)}`);
1843
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatItem(lib, import_types3.LIBRARY_NAMES)}`);
1843
1844
  }
1844
1845
  }
1845
1846
  const groups = groupByRole(scanResult.structure.directories);
1846
1847
  if (groups.length > 0) {
1847
1848
  console.log(`
1848
- ${import_chalk5.default.bold("Structure:")}`);
1849
+ ${import_chalk6.default.bold("Structure:")}`);
1849
1850
  for (const group of groups) {
1850
- console.log(` ${import_chalk5.default.green("\u2713")} ${formatRoleGroup(group)}`);
1851
+ console.log(` ${import_chalk6.default.green("\u2713")} ${formatRoleGroup(group)}`);
1851
1852
  }
1852
1853
  }
1853
1854
  displayConventions(scanResult);
@@ -1857,25 +1858,25 @@ ${import_chalk5.default.bold("Structure:")}`);
1857
1858
  function displayRulesPreview(config) {
1858
1859
  const root = config.packages.find((p) => p.path === ".") ?? config.packages[0];
1859
1860
  console.log(
1860
- `${import_chalk5.default.bold("Rules:")} ${import_chalk5.default.dim("(warns on violation; use --enforce in CI to block)")}`
1861
+ `${import_chalk6.default.bold("Rules:")} ${import_chalk6.default.dim("(warns on violation; use --enforce in CI to block)")}`
1861
1862
  );
1862
- console.log(` ${import_chalk5.default.dim("\u2022")} Max file size: ${config.rules.maxFileLines} lines`);
1863
+ console.log(` ${import_chalk6.default.dim("\u2022")} Max file size: ${config.rules.maxFileLines} lines`);
1863
1864
  if (config.rules.testCoverage > 0 && root?.structure?.testPattern) {
1864
1865
  console.log(
1865
- ` ${import_chalk5.default.dim("\u2022")} Test coverage target: ${config.rules.testCoverage}% (${root.structure.testPattern})`
1866
+ ` ${import_chalk6.default.dim("\u2022")} Test coverage target: ${config.rules.testCoverage}% (${root.structure.testPattern})`
1866
1867
  );
1867
1868
  } else if (config.rules.testCoverage > 0) {
1868
- console.log(` ${import_chalk5.default.dim("\u2022")} Test coverage target: ${config.rules.testCoverage}%`);
1869
+ console.log(` ${import_chalk6.default.dim("\u2022")} Test coverage target: ${config.rules.testCoverage}%`);
1869
1870
  } else {
1870
- console.log(` ${import_chalk5.default.dim("\u2022")} Test coverage target: disabled`);
1871
+ console.log(` ${import_chalk6.default.dim("\u2022")} Test coverage target: disabled`);
1871
1872
  }
1872
1873
  if (config.rules.enforceNaming && root?.conventions?.fileNaming) {
1873
- console.log(` ${import_chalk5.default.dim("\u2022")} Enforce file naming: ${root.conventions.fileNaming}`);
1874
+ console.log(` ${import_chalk6.default.dim("\u2022")} Enforce file naming: ${root.conventions.fileNaming}`);
1874
1875
  } else {
1875
- console.log(` ${import_chalk5.default.dim("\u2022")} Enforce file naming: no`);
1876
+ console.log(` ${import_chalk6.default.dim("\u2022")} Enforce file naming: no`);
1876
1877
  }
1877
1878
  console.log(
1878
- ` ${import_chalk5.default.dim("\u2022")} Enforce boundaries: ${config.rules.enforceBoundaries ? "yes" : "no"}`
1879
+ ` ${import_chalk6.default.dim("\u2022")} Enforce boundaries: ${config.rules.enforceBoundaries ? "yes" : "no"}`
1879
1880
  );
1880
1881
  console.log("");
1881
1882
  }
@@ -2200,7 +2201,7 @@ async function configCommand(options, cwd) {
2200
2201
  }
2201
2202
  const configPath = path9.join(projectRoot, CONFIG_FILE3);
2202
2203
  if (!fs10.existsSync(configPath)) {
2203
- console.log(`${import_chalk6.default.yellow("!")} No config found. Run ${import_chalk6.default.cyan("viberails")} first.`);
2204
+ console.log(`${import_chalk7.default.yellow("!")} No config found. Run ${import_chalk7.default.cyan("viberails")} first.`);
2204
2205
  return;
2205
2206
  }
2206
2207
  if (!options.suppressIntro) {
@@ -2291,22 +2292,22 @@ async function rescanAndMerge(projectRoot, config) {
2291
2292
  var fs13 = __toESM(require("fs"), 1);
2292
2293
  var path13 = __toESM(require("path"), 1);
2293
2294
  var import_config7 = require("@viberails/config");
2294
- var import_chalk8 = __toESM(require("chalk"), 1);
2295
+ var import_chalk9 = __toESM(require("chalk"), 1);
2295
2296
 
2296
2297
  // src/commands/fix-helpers.ts
2297
2298
  var import_node_child_process3 = require("child_process");
2298
- var import_chalk7 = __toESM(require("chalk"), 1);
2299
+ var import_chalk8 = __toESM(require("chalk"), 1);
2299
2300
  function printPlan(renames, stubs) {
2300
2301
  if (renames.length > 0) {
2301
- console.log(import_chalk7.default.bold("\nFile renames:"));
2302
+ console.log(import_chalk8.default.bold("\nFile renames:"));
2302
2303
  for (const r of renames) {
2303
- console.log(` ${import_chalk7.default.red(r.oldPath)} \u2192 ${import_chalk7.default.green(r.newPath)}`);
2304
+ console.log(` ${import_chalk8.default.red(r.oldPath)} \u2192 ${import_chalk8.default.green(r.newPath)}`);
2304
2305
  }
2305
2306
  }
2306
2307
  if (stubs.length > 0) {
2307
- console.log(import_chalk7.default.bold("\nTest stubs to create:"));
2308
+ console.log(import_chalk8.default.bold("\nTest stubs to create:"));
2308
2309
  for (const s of stubs) {
2309
- console.log(` ${import_chalk7.default.green("+")} ${s.path}`);
2310
+ console.log(` ${import_chalk8.default.green("+")} ${s.path}`);
2310
2311
  }
2311
2312
  }
2312
2313
  }
@@ -2634,13 +2635,13 @@ async function fixCommand(options, cwd) {
2634
2635
  const startDir = cwd ?? process.cwd();
2635
2636
  const projectRoot = findProjectRoot(startDir);
2636
2637
  if (!projectRoot) {
2637
- console.error(`${import_chalk8.default.red("Error:")} No package.json found. Are you in a JS/TS project?`);
2638
+ console.error(`${import_chalk9.default.red("Error:")} No package.json found. Are you in a JS/TS project?`);
2638
2639
  return 1;
2639
2640
  }
2640
2641
  const configPath = path13.join(projectRoot, CONFIG_FILE4);
2641
2642
  if (!fs13.existsSync(configPath)) {
2642
2643
  console.error(
2643
- `${import_chalk8.default.red("Error:")} No viberails.config.json found. Run \`viberails init\` first.`
2644
+ `${import_chalk9.default.red("Error:")} No viberails.config.json found. Run \`viberails init\` first.`
2644
2645
  );
2645
2646
  return 1;
2646
2647
  }
@@ -2649,7 +2650,7 @@ async function fixCommand(options, cwd) {
2649
2650
  const isDirty = checkGitDirty(projectRoot);
2650
2651
  if (isDirty) {
2651
2652
  console.log(
2652
- import_chalk8.default.yellow("Warning: You have uncommitted changes. Consider committing first.")
2653
+ import_chalk9.default.yellow("Warning: You have uncommitted changes. Consider committing first.")
2653
2654
  );
2654
2655
  }
2655
2656
  }
@@ -2696,41 +2697,41 @@ async function fixCommand(options, cwd) {
2696
2697
  return blockedOldBareNames.has(bare);
2697
2698
  });
2698
2699
  if (safeRenames.length === 0 && testStubs.length === 0 && skippedRenames.length === 0) {
2699
- console.log(`${import_chalk8.default.green("\u2713")} No fixable violations found.`);
2700
+ console.log(`${import_chalk9.default.green("\u2713")} No fixable violations found.`);
2700
2701
  return 0;
2701
2702
  }
2702
2703
  printPlan(safeRenames, testStubs);
2703
2704
  if (skippedRenames.length > 0) {
2704
2705
  console.log("");
2705
2706
  console.log(
2706
- import_chalk8.default.yellow(
2707
+ import_chalk9.default.yellow(
2707
2708
  `Skipping ${skippedRenames.length} rename${skippedRenames.length > 1 ? "s" : ""} \u2014 aliased imports would break:`
2708
2709
  )
2709
2710
  );
2710
2711
  for (const r of skippedRenames.slice(0, 5)) {
2711
- console.log(import_chalk8.default.dim(` ${r.oldPath} \u2192 ${r.newPath}`));
2712
+ console.log(import_chalk9.default.dim(` ${r.oldPath} \u2192 ${r.newPath}`));
2712
2713
  }
2713
2714
  if (skippedRenames.length > 5) {
2714
- console.log(import_chalk8.default.dim(` ... and ${skippedRenames.length - 5} more`));
2715
+ console.log(import_chalk9.default.dim(` ... and ${skippedRenames.length - 5} more`));
2715
2716
  }
2716
2717
  console.log("");
2717
- console.log(import_chalk8.default.yellow("Affected aliased imports:"));
2718
+ console.log(import_chalk9.default.yellow("Affected aliased imports:"));
2718
2719
  for (const alias of aliasImports.slice(0, 5)) {
2719
2720
  const relFile = path13.relative(projectRoot, alias.file);
2720
- console.log(import_chalk8.default.dim(` ${relFile}:${alias.line} \u2014 ${alias.specifier}`));
2721
+ console.log(import_chalk9.default.dim(` ${relFile}:${alias.line} \u2014 ${alias.specifier}`));
2721
2722
  }
2722
2723
  if (aliasImports.length > 5) {
2723
- console.log(import_chalk8.default.dim(` ... and ${aliasImports.length - 5} more`));
2724
+ console.log(import_chalk9.default.dim(` ... and ${aliasImports.length - 5} more`));
2724
2725
  }
2725
- console.log(import_chalk8.default.dim(" Update these imports to relative paths first, then re-run fix."));
2726
+ console.log(import_chalk9.default.dim(" Update these imports to relative paths first, then re-run fix."));
2726
2727
  }
2727
2728
  if (safeRenames.length === 0 && testStubs.length === 0) {
2728
2729
  console.log(`
2729
- ${import_chalk8.default.yellow("!")} No safe fixes to apply. Resolve aliased imports first.`);
2730
+ ${import_chalk9.default.yellow("!")} No safe fixes to apply. Resolve aliased imports first.`);
2730
2731
  return 0;
2731
2732
  }
2732
2733
  if (options.dryRun) {
2733
- console.log(import_chalk8.default.dim("\nDry run \u2014 no changes applied."));
2734
+ console.log(import_chalk9.default.dim("\nDry run \u2014 no changes applied."));
2734
2735
  return 0;
2735
2736
  }
2736
2737
  if (!options.yes) {
@@ -2761,15 +2762,15 @@ ${import_chalk8.default.yellow("!")} No safe fixes to apply. Resolve aliased imp
2761
2762
  }
2762
2763
  console.log("");
2763
2764
  if (renameCount > 0) {
2764
- console.log(`${import_chalk8.default.green("\u2713")} Renamed ${renameCount} file${renameCount > 1 ? "s" : ""}`);
2765
+ console.log(`${import_chalk9.default.green("\u2713")} Renamed ${renameCount} file${renameCount > 1 ? "s" : ""}`);
2765
2766
  }
2766
2767
  if (importUpdateCount > 0) {
2767
2768
  console.log(
2768
- `${import_chalk8.default.green("\u2713")} Updated ${importUpdateCount} import${importUpdateCount > 1 ? "s" : ""}`
2769
+ `${import_chalk9.default.green("\u2713")} Updated ${importUpdateCount} import${importUpdateCount > 1 ? "s" : ""}`
2769
2770
  );
2770
2771
  }
2771
2772
  if (stubCount > 0) {
2772
- console.log(`${import_chalk8.default.green("\u2713")} Generated ${stubCount} test stub${stubCount > 1 ? "s" : ""}`);
2773
+ console.log(`${import_chalk9.default.green("\u2713")} Generated ${stubCount} test stub${stubCount > 1 ? "s" : ""}`);
2773
2774
  }
2774
2775
  return 0;
2775
2776
  }
@@ -2780,13 +2781,13 @@ var path21 = __toESM(require("path"), 1);
2780
2781
  var clack13 = __toESM(require("@clack/prompts"), 1);
2781
2782
  var import_config9 = require("@viberails/config");
2782
2783
  var import_scanner3 = require("@viberails/scanner");
2783
- var import_chalk14 = __toESM(require("chalk"), 1);
2784
+ var import_chalk15 = __toESM(require("chalk"), 1);
2784
2785
 
2785
2786
  // src/utils/check-prerequisites.ts
2786
2787
  var fs14 = __toESM(require("fs"), 1);
2787
2788
  var path14 = __toESM(require("path"), 1);
2788
2789
  var clack7 = __toESM(require("@clack/prompts"), 1);
2789
- var import_chalk9 = __toESM(require("chalk"), 1);
2790
+ var import_chalk10 = __toESM(require("chalk"), 1);
2790
2791
 
2791
2792
  // src/utils/spawn-async.ts
2792
2793
  var import_node_child_process4 = require("child_process");
@@ -2841,9 +2842,9 @@ function displayMissingPrereqs(prereqs) {
2841
2842
  const missing = prereqs.filter((p) => !p.installed);
2842
2843
  for (const m of missing) {
2843
2844
  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}`);
2845
+ console.log(` ${import_chalk10.default.yellow("!")} ${m.label} not installed${suffix}`);
2845
2846
  if (m.installCommand) {
2846
- console.log(` Install: ${import_chalk9.default.cyan(m.installCommand)}`);
2847
+ console.log(` Install: ${import_chalk10.default.cyan(m.installCommand)}`);
2847
2848
  }
2848
2849
  }
2849
2850
  }
@@ -3168,7 +3169,7 @@ async function handleIntegrations(state, opts) {
3168
3169
  }
3169
3170
 
3170
3171
  // src/utils/prompt-main-menu-hints.ts
3171
- var import_chalk10 = __toESM(require("chalk"), 1);
3172
+ var import_chalk11 = __toESM(require("chalk"), 1);
3172
3173
  function fileLimitsHint(config) {
3173
3174
  const max = config.rules.maxFileLines;
3174
3175
  const test = config.rules.maxTestFileLines;
@@ -3213,24 +3214,29 @@ function coverageHint(config, hasTestRunner) {
3213
3214
  }
3214
3215
  function advancedNamingHint(config) {
3215
3216
  const rootPkg = getRootPackage(config.packages);
3217
+ if (!config.rules.enforceNaming) return "not enforced";
3216
3218
  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";
3219
+ const naming = rootPkg.conventions?.fileNaming;
3220
+ if (naming) parts.push(import_chalk11.default.green(naming));
3221
+ const comp = rootPkg.conventions?.componentNaming;
3222
+ parts.push(comp ? import_chalk11.default.green(`${comp} components`) : import_chalk11.default.dim("components"));
3223
+ const hook = rootPkg.conventions?.hookNaming;
3224
+ parts.push(hook ? import_chalk11.default.green(`${hook} hooks`) : import_chalk11.default.dim("hooks"));
3225
+ const alias = rootPkg.conventions?.importAlias;
3226
+ parts.push(alias ? import_chalk11.default.green(alias) : import_chalk11.default.dim("alias"));
3227
+ return parts.join(import_chalk11.default.dim(", "));
3222
3228
  }
3223
3229
  function integrationsHint(state) {
3224
3230
  if (!state.visited.integrations || !state.integrations)
3225
3231
  return "not configured \u2014 select to set up";
3226
3232
  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";
3233
+ if (state.integrations.preCommitHook) items.push(import_chalk11.default.green("pre-commit"));
3234
+ if (state.integrations.typecheckHook) items.push(import_chalk11.default.green("typecheck"));
3235
+ if (state.integrations.lintHook) items.push(import_chalk11.default.green("lint"));
3236
+ if (state.integrations.claudeCodeHook) items.push(import_chalk11.default.green("Claude"));
3237
+ if (state.integrations.claudeMdRef) items.push(import_chalk11.default.green("CLAUDE.md"));
3238
+ if (state.integrations.githubAction) items.push(import_chalk11.default.green("CI"));
3239
+ return items.length > 0 ? items.join(import_chalk11.default.dim(" \xB7 ")) : "none selected";
3234
3240
  }
3235
3241
  function packageOverridesHint(config) {
3236
3242
  const rootNaming = getRootPackage(config.packages).conventions?.fileNaming;
@@ -3249,8 +3255,9 @@ function boundariesHint(config, state) {
3249
3255
  return `${ruleCount} rules across ${pkgCount} packages`;
3250
3256
  }
3251
3257
  function advancedNamingStatus(config) {
3258
+ if (!config.rules.enforceNaming) return "disabled";
3252
3259
  const rootPkg = getRootPackage(config.packages);
3253
- const hasAny = !!rootPkg.conventions?.componentNaming || !!rootPkg.conventions?.hookNaming || !!rootPkg.conventions?.importAlias;
3260
+ const hasAny = !!rootPkg.conventions?.fileNaming || !!rootPkg.conventions?.componentNaming || !!rootPkg.conventions?.hookNaming || !!rootPkg.conventions?.importAlias;
3254
3261
  return hasAny ? "ok" : "unconfigured";
3255
3262
  }
3256
3263
  function packageOverridesStatus(config) {
@@ -3262,10 +3269,10 @@ function packageOverridesStatus(config) {
3262
3269
  return customized ? "ok" : "unconfigured";
3263
3270
  }
3264
3271
  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("~");
3272
+ if (status === "ok") return import_chalk11.default.green("\u2713");
3273
+ if (status === "needs-input") return import_chalk11.default.yellow("?");
3274
+ if (status === "unconfigured") return import_chalk11.default.dim("-");
3275
+ return import_chalk11.default.yellow("~");
3269
3276
  }
3270
3277
  function buildMainMenuOptions(config, scanResult, state) {
3271
3278
  const namingStatus = fileNamingStatus(config);
@@ -3316,7 +3323,7 @@ function buildMainMenuOptions(config, scanResult, state) {
3316
3323
  options.push(
3317
3324
  { value: "integrations", label: `${iIcon} Integrations`, hint: integrationsHint(state) },
3318
3325
  { value: "reset", label: " Reset all to defaults" },
3319
- { value: "review", label: " Review scan details" },
3326
+ { value: "review", label: " Review scan details", hint: "detected stack & conventions" },
3320
3327
  { value: "done", label: " Done \u2014 write config" }
3321
3328
  );
3322
3329
  return options;
@@ -3396,7 +3403,7 @@ function updateGitignore(projectRoot) {
3396
3403
  // src/commands/init-hooks.ts
3397
3404
  var fs18 = __toESM(require("fs"), 1);
3398
3405
  var path18 = __toESM(require("path"), 1);
3399
- var import_chalk11 = __toESM(require("chalk"), 1);
3406
+ var import_chalk12 = __toESM(require("chalk"), 1);
3400
3407
  var import_yaml = require("yaml");
3401
3408
 
3402
3409
  // src/commands/resolve-typecheck.ts
@@ -3441,13 +3448,13 @@ function setupPreCommitHook(projectRoot) {
3441
3448
  const lefthookPath = path18.join(projectRoot, "lefthook.yml");
3442
3449
  if (fs18.existsSync(lefthookPath)) {
3443
3450
  addLefthookPreCommit(lefthookPath);
3444
- console.log(` ${import_chalk11.default.green("\u2713")} lefthook.yml \u2014 added viberails pre-commit`);
3451
+ console.log(` ${import_chalk12.default.green("\u2713")} lefthook.yml \u2014 added viberails pre-commit`);
3445
3452
  return "lefthook.yml";
3446
3453
  }
3447
3454
  const huskyDir = path18.join(projectRoot, ".husky");
3448
3455
  if (fs18.existsSync(huskyDir)) {
3449
3456
  writeHuskyPreCommit(huskyDir);
3450
- console.log(` ${import_chalk11.default.green("\u2713")} .husky/pre-commit \u2014 added viberails check`);
3457
+ console.log(` ${import_chalk12.default.green("\u2713")} .husky/pre-commit \u2014 added viberails check`);
3451
3458
  return ".husky/pre-commit";
3452
3459
  }
3453
3460
  const gitDir = path18.join(projectRoot, ".git");
@@ -3457,7 +3464,7 @@ function setupPreCommitHook(projectRoot) {
3457
3464
  fs18.mkdirSync(hooksDir, { recursive: true });
3458
3465
  }
3459
3466
  writeGitHookPreCommit(hooksDir);
3460
- console.log(` ${import_chalk11.default.green("\u2713")} .git/hooks/pre-commit`);
3467
+ console.log(` ${import_chalk12.default.green("\u2713")} .git/hooks/pre-commit`);
3461
3468
  return ".git/hooks/pre-commit";
3462
3469
  }
3463
3470
  return void 0;
@@ -3518,9 +3525,9 @@ function setupClaudeCodeHook(projectRoot) {
3518
3525
  settings = JSON.parse(fs18.readFileSync(settingsPath, "utf-8"));
3519
3526
  } catch {
3520
3527
  console.warn(
3521
- ` ${import_chalk11.default.yellow("!")} .claude/settings.json contains invalid JSON \u2014 skipping hook setup`
3528
+ ` ${import_chalk12.default.yellow("!")} .claude/settings.json contains invalid JSON \u2014 skipping hook setup`
3522
3529
  );
3523
- console.warn(` Fix the JSON manually, then re-run ${import_chalk11.default.cyan("viberails init --force")}`);
3530
+ console.warn(` Fix the JSON manually, then re-run ${import_chalk12.default.cyan("viberails init --force")}`);
3524
3531
  return;
3525
3532
  }
3526
3533
  }
@@ -3543,7 +3550,7 @@ function setupClaudeCodeHook(projectRoot) {
3543
3550
  settings.hooks = hooks;
3544
3551
  fs18.writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
3545
3552
  `);
3546
- console.log(` ${import_chalk11.default.green("\u2713")} .claude/settings.json \u2014 added viberails PostToolUse hook`);
3553
+ console.log(` ${import_chalk12.default.green("\u2713")} .claude/settings.json \u2014 added viberails PostToolUse hook`);
3547
3554
  }
3548
3555
  function setupClaudeMdReference(projectRoot) {
3549
3556
  const claudeMdPath = path18.join(projectRoot, "CLAUDE.md");
@@ -3555,7 +3562,7 @@ function setupClaudeMdReference(projectRoot) {
3555
3562
  const ref = "\n@.viberails/context.md\n";
3556
3563
  const prefix = content.length === 0 ? "" : content.trimEnd();
3557
3564
  fs18.writeFileSync(claudeMdPath, prefix + ref);
3558
- console.log(` ${import_chalk11.default.green("\u2713")} CLAUDE.md \u2014 added @.viberails/context.md reference`);
3565
+ console.log(` ${import_chalk12.default.green("\u2713")} CLAUDE.md \u2014 added @.viberails/context.md reference`);
3559
3566
  }
3560
3567
  function setupGithubAction(projectRoot, packageManager, options) {
3561
3568
  const workflowDir = path18.join(projectRoot, ".github", "workflows");
@@ -3641,7 +3648,7 @@ ${cmd}
3641
3648
  // src/commands/init-hooks-extra.ts
3642
3649
  var fs19 = __toESM(require("fs"), 1);
3643
3650
  var path19 = __toESM(require("path"), 1);
3644
- var import_chalk12 = __toESM(require("chalk"), 1);
3651
+ var import_chalk13 = __toESM(require("chalk"), 1);
3645
3652
  var import_yaml2 = require("yaml");
3646
3653
  function addPreCommitStep(projectRoot, name, command, marker, lefthookExtra) {
3647
3654
  const lefthookPath = path19.join(projectRoot, "lefthook.yml");
@@ -3701,12 +3708,12 @@ ${command}
3701
3708
  function setupTypecheckHook(projectRoot, packageManager) {
3702
3709
  const resolved = resolveTypecheckCommand(projectRoot, packageManager);
3703
3710
  if (!resolved.command) {
3704
- console.log(` ${import_chalk12.default.yellow("!")} Skipped typecheck hook: ${resolved.reason}`);
3711
+ console.log(` ${import_chalk13.default.yellow("!")} Skipped typecheck hook: ${resolved.reason}`);
3705
3712
  return void 0;
3706
3713
  }
3707
3714
  const target = addPreCommitStep(projectRoot, "typecheck", resolved.command, "typecheck");
3708
3715
  if (target) {
3709
- console.log(` ${import_chalk12.default.green("\u2713")} ${target} \u2014 added typecheck (${resolved.label})`);
3716
+ console.log(` ${import_chalk13.default.green("\u2713")} ${target} \u2014 added typecheck (${resolved.label})`);
3710
3717
  }
3711
3718
  return target;
3712
3719
  }
@@ -3727,7 +3734,7 @@ function setupLintHook(projectRoot, linter) {
3727
3734
  }
3728
3735
  const target = addPreCommitStep(projectRoot, "lint", command, linter, lefthookExtra);
3729
3736
  if (target) {
3730
- console.log(` ${import_chalk12.default.green("\u2713")} ${target} \u2014 added ${linterName} lint check`);
3737
+ console.log(` ${import_chalk13.default.green("\u2713")} ${target} \u2014 added ${linterName} lint check`);
3731
3738
  }
3732
3739
  return target;
3733
3740
  }
@@ -3736,7 +3743,7 @@ function setupSelectedIntegrations(projectRoot, integrations, opts) {
3736
3743
  if (integrations.preCommitHook) {
3737
3744
  const t = setupPreCommitHook(projectRoot);
3738
3745
  if (t && opts.lefthookExpected && !t.includes("lefthook")) {
3739
- console.log(` ${import_chalk12.default.yellow("!")} Lefthook install failed \u2014 fell back to ${t}`);
3746
+ console.log(` ${import_chalk13.default.yellow("!")} Lefthook install failed \u2014 fell back to ${t}`);
3740
3747
  }
3741
3748
  created.push(t ? `${t} \u2014 added viberails pre-commit` : "pre-commit hook skipped");
3742
3749
  }
@@ -3772,7 +3779,7 @@ var path20 = __toESM(require("path"), 1);
3772
3779
  var clack12 = __toESM(require("@clack/prompts"), 1);
3773
3780
  var import_config8 = require("@viberails/config");
3774
3781
  var import_scanner2 = require("@viberails/scanner");
3775
- var import_chalk13 = __toESM(require("chalk"), 1);
3782
+ var import_chalk14 = __toESM(require("chalk"), 1);
3776
3783
 
3777
3784
  // src/utils/filter-confidence.ts
3778
3785
  function filterHighConfidence(conventions, meta) {
@@ -3808,7 +3815,7 @@ async function initNonInteractive(projectRoot, configPath) {
3808
3815
  const exempted = getExemptedPackages(config);
3809
3816
  if (exempted.length > 0) {
3810
3817
  console.log(
3811
- ` ${import_chalk13.default.dim("Auto-exempted from coverage:")} ${exempted.join(", ")} ${import_chalk13.default.dim("(types-only)")}`
3818
+ ` ${import_chalk14.default.dim("Auto-exempted from coverage:")} ${exempted.join(", ")} ${import_chalk14.default.dim("(types-only)")}`
3812
3819
  );
3813
3820
  }
3814
3821
  if (config.packages.length > 1) {
@@ -3845,14 +3852,14 @@ async function initNonInteractive(projectRoot, configPath) {
3845
3852
  const hookManager = detectHookManager(projectRoot);
3846
3853
  const hasHookManager = hookManager === "Lefthook" || hookManager === "Husky";
3847
3854
  const preCommitTarget = hasHookManager ? setupPreCommitHook(projectRoot) : void 0;
3848
- const ok = import_chalk13.default.green("\u2713");
3855
+ const ok = import_chalk14.default.green("\u2713");
3849
3856
  const created = [
3850
3857
  `${ok} ${path20.basename(configPath)}`,
3851
3858
  `${ok} .viberails/context.md`,
3852
3859
  `${ok} .viberails/scan-result.json`,
3853
3860
  `${ok} .claude/settings.json \u2014 added viberails hook`,
3854
3861
  `${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)`,
3862
+ preCommitTarget ? `${ok} ${preCommitTarget}` : `${import_chalk14.default.yellow("!")} pre-commit hook skipped (install lefthook or husky)`,
3856
3863
  actionTarget ? `${ok} ${actionTarget} \u2014 blocks PRs on violations` : ""
3857
3864
  ].filter(Boolean);
3858
3865
  if (hasHookManager && isTypeScript) setupTypecheckHook(projectRoot, rootPkgPm);
@@ -3877,8 +3884,8 @@ async function initCommand(options, cwd) {
3877
3884
  return initInteractive(projectRoot, configPath, options);
3878
3885
  }
3879
3886
  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.`
3887
+ `${import_chalk15.default.yellow("!")} viberails is already initialized.
3888
+ Run ${import_chalk15.default.cyan("viberails")} to review or edit the existing setup, ${import_chalk15.default.cyan("viberails sync")} to update generated files, or ${import_chalk15.default.cyan("viberails init --force")} to replace it.`
3882
3889
  );
3883
3890
  return;
3884
3891
  }
@@ -3955,7 +3962,7 @@ async function initInteractive(projectRoot, configPath, options) {
3955
3962
  writeGeneratedFiles(projectRoot, config, scanResult);
3956
3963
  updateGitignore(projectRoot);
3957
3964
  ws.stop("Configuration written");
3958
- const ok = import_chalk14.default.green("\u2713");
3965
+ const ok = import_chalk15.default.green("\u2713");
3959
3966
  clack13.log.step(`${ok} ${path21.basename(configPath)}`);
3960
3967
  clack13.log.step(`${ok} .viberails/context.md`);
3961
3968
  clack13.log.step(`${ok} .viberails/scan-result.json`);
@@ -3969,7 +3976,7 @@ async function initInteractive(projectRoot, configPath, options) {
3969
3976
  }
3970
3977
  clack13.outro(
3971
3978
  `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.")}`
3979
+ ${import_chalk15.default.dim("Tip: use")} ${import_chalk15.default.cyan("viberails check --enforce")} ${import_chalk15.default.dim("in CI to block PRs on violations.")}`
3973
3980
  );
3974
3981
  }
3975
3982
 
@@ -3979,7 +3986,7 @@ var path22 = __toESM(require("path"), 1);
3979
3986
  var clack14 = __toESM(require("@clack/prompts"), 1);
3980
3987
  var import_config11 = require("@viberails/config");
3981
3988
  var import_scanner4 = require("@viberails/scanner");
3982
- var import_chalk15 = __toESM(require("chalk"), 1);
3989
+ var import_chalk16 = __toESM(require("chalk"), 1);
3983
3990
  var CONFIG_FILE6 = "viberails.config.json";
3984
3991
  var SCAN_RESULT_FILE2 = ".viberails/scan-result.json";
3985
3992
  function loadPreviousStats(projectRoot) {
@@ -4020,13 +4027,13 @@ async function syncCommand(options, cwd) {
4020
4027
  const statsDelta = previousStats ? formatStatsDelta(previousStats, scanResult.statistics) : void 0;
4021
4028
  if (changes.length > 0 || statsDelta) {
4022
4029
  console.log(`
4023
- ${import_chalk15.default.bold("Changes:")}`);
4030
+ ${import_chalk16.default.bold("Changes:")}`);
4024
4031
  for (const change of changes) {
4025
- const icon = change.type === "removed" ? import_chalk15.default.red("-") : import_chalk15.default.green("+");
4032
+ const icon = change.type === "removed" ? import_chalk16.default.red("-") : import_chalk16.default.green("+");
4026
4033
  console.log(` ${icon} ${change.description}`);
4027
4034
  }
4028
4035
  if (statsDelta) {
4029
- console.log(` ${import_chalk15.default.dim(statsDelta)}`);
4036
+ console.log(` ${import_chalk16.default.dim(statsDelta)}`);
4030
4037
  }
4031
4038
  }
4032
4039
  if (options?.interactive) {
@@ -4075,18 +4082,18 @@ ${import_chalk15.default.bold("Changes:")}`);
4075
4082
  `);
4076
4083
  writeGeneratedFiles(projectRoot, merged, scanResult);
4077
4084
  console.log(`
4078
- ${import_chalk15.default.bold("Synced:")}`);
4085
+ ${import_chalk16.default.bold("Synced:")}`);
4079
4086
  if (configChanged) {
4080
- console.log(` ${import_chalk15.default.yellow("!")} ${CONFIG_FILE6} \u2014 updated (review changes)`);
4087
+ console.log(` ${import_chalk16.default.yellow("!")} ${CONFIG_FILE6} \u2014 updated (review changes)`);
4081
4088
  } else {
4082
- console.log(` ${import_chalk15.default.green("\u2713")} ${CONFIG_FILE6} \u2014 unchanged`);
4089
+ console.log(` ${import_chalk16.default.green("\u2713")} ${CONFIG_FILE6} \u2014 unchanged`);
4083
4090
  }
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`);
4091
+ console.log(` ${import_chalk16.default.green("\u2713")} .viberails/context.md \u2014 regenerated`);
4092
+ console.log(` ${import_chalk16.default.green("\u2713")} .viberails/scan-result.json \u2014 updated`);
4086
4093
  }
4087
4094
 
4088
4095
  // src/index.ts
4089
- var VERSION = "0.6.7";
4096
+ var VERSION = "0.6.8";
4090
4097
  var program = new import_commander.Command();
4091
4098
  program.name("viberails").description("Guardrails for vibe coding").version(VERSION);
4092
4099
  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 +4101,7 @@ program.command("init", { isDefault: true }).description("Scan your project and
4094
4101
  await initCommand(options);
4095
4102
  } catch (err) {
4096
4103
  const message = err instanceof Error ? err.message : String(err);
4097
- console.error(`${import_chalk16.default.red("Error:")} ${message}`);
4104
+ console.error(`${import_chalk17.default.red("Error:")} ${message}`);
4098
4105
  process.exit(1);
4099
4106
  }
4100
4107
  });
@@ -4103,7 +4110,7 @@ program.command("sync").description("Re-scan and update generated files").option
4103
4110
  await syncCommand(options);
4104
4111
  } catch (err) {
4105
4112
  const message = err instanceof Error ? err.message : String(err);
4106
- console.error(`${import_chalk16.default.red("Error:")} ${message}`);
4113
+ console.error(`${import_chalk17.default.red("Error:")} ${message}`);
4107
4114
  process.exit(1);
4108
4115
  }
4109
4116
  });
@@ -4112,7 +4119,7 @@ program.command("config").description("Interactively edit existing config rules"
4112
4119
  await configCommand(options);
4113
4120
  } catch (err) {
4114
4121
  const message = err instanceof Error ? err.message : String(err);
4115
- console.error(`${import_chalk16.default.red("Error:")} ${message}`);
4122
+ console.error(`${import_chalk17.default.red("Error:")} ${message}`);
4116
4123
  process.exit(1);
4117
4124
  }
4118
4125
  });
@@ -4133,7 +4140,7 @@ program.command("check").description("Check files against enforced rules").optio
4133
4140
  process.exit(exitCode);
4134
4141
  } catch (err) {
4135
4142
  const message = err instanceof Error ? err.message : String(err);
4136
- console.error(`${import_chalk16.default.red("Error:")} ${message}`);
4143
+ console.error(`${import_chalk17.default.red("Error:")} ${message}`);
4137
4144
  process.exit(1);
4138
4145
  }
4139
4146
  }
@@ -4144,7 +4151,7 @@ program.command("fix").description("Auto-fix file naming violations and generate
4144
4151
  process.exit(exitCode);
4145
4152
  } catch (err) {
4146
4153
  const message = err instanceof Error ? err.message : String(err);
4147
- console.error(`${import_chalk16.default.red("Error:")} ${message}`);
4154
+ console.error(`${import_chalk17.default.red("Error:")} ${message}`);
4148
4155
  process.exit(1);
4149
4156
  }
4150
4157
  });
@@ -4153,7 +4160,7 @@ program.command("boundaries").description("Display, infer, or inspect import bou
4153
4160
  await boundariesCommand(options);
4154
4161
  } catch (err) {
4155
4162
  const message = err instanceof Error ? err.message : String(err);
4156
- console.error(`${import_chalk16.default.red("Error:")} ${message}`);
4163
+ console.error(`${import_chalk17.default.red("Error:")} ${message}`);
4157
4164
  process.exit(1);
4158
4165
  }
4159
4166
  });