viberails 0.5.1 → 0.5.2

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.js CHANGED
@@ -328,11 +328,10 @@ function buildMenuOptions(state, packageCount) {
328
328
  hint: state.fileNamingValue
329
329
  });
330
330
  }
331
- options.push({
332
- value: "testCoverage",
333
- label: "Test coverage target",
334
- hint: state.testCoverage === 0 ? "0 (disabled)" : `${state.testCoverage}%`
335
- });
331
+ const isMonorepo = packageCount > 0;
332
+ const coverageLabel = isMonorepo ? "Default coverage target" : "Test coverage target";
333
+ const coverageHint = state.testCoverage === 0 ? "0 (disabled)" : isMonorepo ? `${state.testCoverage}% (per-package default)` : `${state.testCoverage}%`;
334
+ options.push({ value: "testCoverage", label: coverageLabel, hint: coverageHint });
336
335
  options.push({
337
336
  value: "enforceMissingTests",
338
337
  label: "Enforce missing tests",
@@ -342,16 +341,16 @@ function buildMenuOptions(state, packageCount) {
342
341
  options.push(
343
342
  {
344
343
  value: "coverageSummaryPath",
345
- label: "Coverage summary path",
344
+ label: isMonorepo ? "Default coverage summary path" : "Coverage summary path",
346
345
  hint: state.coverageSummaryPath
347
346
  },
348
347
  {
349
348
  value: "coverageCommand",
350
- label: "Coverage command",
349
+ label: isMonorepo ? "Default coverage command" : "Coverage command",
351
350
  hint: state.coverageCommand ?? "auto-detect from package.json test runner"
352
351
  }
353
352
  );
354
- if (packageCount > 0) {
353
+ if (isMonorepo) {
355
354
  options.push({
356
355
  value: "packageOverrides",
357
356
  label: "Per-package coverage overrides",
@@ -1655,6 +1654,56 @@ function displayRulesPreview(config) {
1655
1654
  );
1656
1655
  console.log("");
1657
1656
  }
1657
+ function displayInitSummary(config, exemptedPackages) {
1658
+ const root = config.packages.find((p) => p.path === ".") ?? config.packages[0];
1659
+ const isMonorepo = config.packages.length > 1;
1660
+ const ok = chalk4.green("\u2713");
1661
+ const off = chalk4.dim("\u25CB");
1662
+ console.log("");
1663
+ console.log(` ${chalk4.bold("Rules to apply:")}`);
1664
+ console.log(` ${ok} Max file size: ${chalk4.cyan(`${config.rules.maxFileLines} lines`)}`);
1665
+ if (config.rules.enforceNaming && root?.conventions?.fileNaming) {
1666
+ console.log(` ${ok} File naming: ${chalk4.cyan(root.conventions.fileNaming)}`);
1667
+ } else {
1668
+ console.log(` ${off} File naming: ${chalk4.dim("not enforced")}`);
1669
+ }
1670
+ if (config.rules.enforceMissingTests && root?.structure?.testPattern) {
1671
+ console.log(` ${ok} Missing tests: ${chalk4.cyan(`enforced (${root.structure.testPattern})`)}`);
1672
+ } else if (config.rules.enforceMissingTests) {
1673
+ console.log(` ${ok} Missing tests: ${chalk4.cyan("enforced")}`);
1674
+ } else {
1675
+ console.log(` ${off} Missing tests: ${chalk4.dim("not enforced")}`);
1676
+ }
1677
+ if (config.rules.testCoverage > 0) {
1678
+ if (isMonorepo) {
1679
+ const withCoverage = config.packages.filter(
1680
+ (p) => (p.rules?.testCoverage ?? config.rules.testCoverage) > 0
1681
+ );
1682
+ console.log(
1683
+ ` ${ok} Coverage: ${chalk4.cyan(`${config.rules.testCoverage}%`)} default ${chalk4.dim(`(${withCoverage.length}/${config.packages.length} packages)`)}`
1684
+ );
1685
+ } else {
1686
+ console.log(` ${ok} Coverage: ${chalk4.cyan(`${config.rules.testCoverage}%`)}`);
1687
+ }
1688
+ } else {
1689
+ console.log(` ${off} Coverage: ${chalk4.dim("disabled")}`);
1690
+ }
1691
+ if (exemptedPackages.length > 0) {
1692
+ console.log(
1693
+ ` ${chalk4.dim(" exempted:")} ${chalk4.dim(exemptedPackages.join(", "))} ${chalk4.dim("(types-only)")}`
1694
+ );
1695
+ }
1696
+ if (isMonorepo) {
1697
+ console.log(
1698
+ `
1699
+ ${chalk4.dim(`${config.packages.length} packages scanned \xB7 warns on violation \xB7 use --enforce in CI`)}`
1700
+ );
1701
+ } else {
1702
+ console.log(`
1703
+ ${chalk4.dim("warns on violation \xB7 use --enforce in CI to block")}`);
1704
+ }
1705
+ console.log("");
1706
+ }
1658
1707
 
1659
1708
  // src/display-text.ts
1660
1709
  function plainConfidenceLabel(convention) {
@@ -1695,10 +1744,13 @@ function formatConventionsText(scanResult) {
1695
1744
  }
1696
1745
  function formatRulesText(config) {
1697
1746
  const root = config.packages.find((p) => p.path === ".") ?? config.packages[0];
1747
+ const isMonorepo = config.packages.length > 1;
1698
1748
  const lines = [];
1699
1749
  lines.push(`Max file size: ${config.rules.maxFileLines} lines`);
1700
1750
  if (config.rules.testCoverage > 0) {
1701
- lines.push(`Test coverage target: ${config.rules.testCoverage}%`);
1751
+ const label = isMonorepo ? "Default coverage target" : "Test coverage target";
1752
+ const suffix = isMonorepo ? " (per-package)" : "";
1753
+ lines.push(`${label}: ${config.rules.testCoverage}%${suffix}`);
1702
1754
  } else {
1703
1755
  lines.push("Test coverage target: disabled");
1704
1756
  }
@@ -2946,11 +2998,8 @@ async function initInteractive(projectRoot, configPath, options) {
2946
2998
  );
2947
2999
  }
2948
3000
  clack8.note(formatScanResultsText(scanResult), "Scan results");
2949
- const rulesLines = formatRulesText(config);
2950
3001
  const exemptedPkgs = getExemptedPackages(config);
2951
- if (exemptedPkgs.length > 0)
2952
- rulesLines.push(`Auto-exempted from coverage: ${exemptedPkgs.join(", ")} (types-only)`);
2953
- clack8.note(rulesLines.join("\n"), "Rules");
3002
+ displayInitSummary(config, exemptedPkgs);
2954
3003
  const decision = await promptInitDecision();
2955
3004
  if (decision === "customize") {
2956
3005
  const rootPkg = config.packages.find((p) => p.path === ".") ?? config.packages[0];
@@ -3132,7 +3181,7 @@ ${chalk12.bold("Synced:")}`);
3132
3181
  }
3133
3182
 
3134
3183
  // src/index.ts
3135
- var VERSION = "0.5.1";
3184
+ var VERSION = "0.5.2";
3136
3185
  var program = new Command();
3137
3186
  program.name("viberails").description("Guardrails for vibe coding").version(VERSION);
3138
3187
  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) => {