viberails 0.5.4 → 0.5.5

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
@@ -98,7 +98,7 @@ async function promptIntegrations(projectRoot, hookManager, tools) {
98
98
  options.push({
99
99
  value: "typecheck",
100
100
  label: "Typecheck (tsc --noEmit)",
101
- hint: "catches type errors before commit"
101
+ hint: "pre-commit hook + CI check"
102
102
  });
103
103
  }
104
104
  if (tools?.linter) {
@@ -106,7 +106,7 @@ async function promptIntegrations(projectRoot, hookManager, tools) {
106
106
  options.push({
107
107
  value: "lint",
108
108
  label: `Lint check (${linterName})`,
109
- hint: "runs linter on staged files before commit"
109
+ hint: "pre-commit hook + CI check"
110
110
  });
111
111
  }
112
112
  options.push(
@@ -1421,7 +1421,8 @@ function formatPackageSummary(pkg) {
1421
1421
  if (pkg.stack.styling) {
1422
1422
  parts.push(formatItem(pkg.stack.styling, STYLING_NAMES));
1423
1423
  }
1424
- const files = `${pkg.statistics.totalFiles} files`;
1424
+ const n = pkg.statistics.totalFiles;
1425
+ const files = `${n} ${n === 1 ? "file" : "files"}`;
1425
1426
  const detail = parts.length > 0 ? `${parts.join(", ")} (${files})` : `(${files})`;
1426
1427
  return ` ${pkg.relativePath} \u2014 ${detail}`;
1427
1428
  }
@@ -1477,7 +1478,8 @@ function formatPackageSummaryPlain(pkg) {
1477
1478
  if (pkg.stack.styling) {
1478
1479
  parts.push(formatItem(pkg.stack.styling, STYLING_NAMES));
1479
1480
  }
1480
- const files = `${pkg.statistics.totalFiles} files`;
1481
+ const n = pkg.statistics.totalFiles;
1482
+ const files = `${n} ${n === 1 ? "file" : "files"}`;
1481
1483
  const detail = parts.length > 0 ? `${parts.join(", ")} (${files})` : `(${files})`;
1482
1484
  return ` ${pkg.relativePath} \u2014 ${detail}`;
1483
1485
  }
@@ -3013,13 +3015,6 @@ async function initInteractive(projectRoot, configPath, options) {
3013
3015
  const scanResult = await scan2(projectRoot);
3014
3016
  const config = generateConfig(scanResult);
3015
3017
  s.stop("Scan complete");
3016
- const prereqResult = await promptMissingPrereqs(
3017
- projectRoot,
3018
- checkCoveragePrereqs(projectRoot, scanResult)
3019
- );
3020
- if (prereqResult.disableCoverage) {
3021
- config.rules.testCoverage = 0;
3022
- }
3023
3018
  if (scanResult.statistics.totalFiles === 0) {
3024
3019
  clack8.log.warn(
3025
3020
  "No source files detected. Try running from the project root,\nor check that source files exist. Run viberails sync after adding files."
@@ -3060,15 +3055,23 @@ async function initInteractive(projectRoot, configPath, options) {
3060
3055
  if (denyCount > 0) {
3061
3056
  config.boundaries = inferred;
3062
3057
  config.rules.enforceBoundaries = true;
3063
- bs.stop(`Inferred ${denyCount} boundary rules`);
3064
- const boundaryLines = Object.entries(inferred.deny).map(([pkg, denied]) => `${pkg} must NOT import from: ${denied.join(", ")}`).join("\n");
3065
- clack8.note(boundaryLines, "Boundary rules");
3058
+ const pkgCount = Object.keys(inferred.deny).length;
3059
+ bs.stop(`Inferred ${denyCount} boundary rules across ${pkgCount} packages`);
3066
3060
  } else {
3067
3061
  bs.stop("No boundary rules inferred");
3068
3062
  }
3069
3063
  }
3070
3064
  }
3071
3065
  const hookManager = detectHookManager(projectRoot);
3066
+ const coveragePrereqs = checkCoveragePrereqs(projectRoot, scanResult);
3067
+ const hasMissingPrereqs = coveragePrereqs.some((p) => !p.installed) || !hookManager;
3068
+ if (hasMissingPrereqs) {
3069
+ clack8.log.info("Some dependencies are needed for full functionality.");
3070
+ }
3071
+ const prereqResult = await promptMissingPrereqs(projectRoot, coveragePrereqs);
3072
+ if (prereqResult.disableCoverage) {
3073
+ config.rules.testCoverage = 0;
3074
+ }
3072
3075
  const rootPkgStack = (config.packages.find((p) => p.path === ".") ?? config.packages[0])?.stack;
3073
3076
  const integrations = await promptIntegrations(projectRoot, hookManager, {
3074
3077
  isTypeScript: rootPkgStack?.language === "typescript",
@@ -3086,17 +3089,14 @@ async function initInteractive(projectRoot, configPath, options) {
3086
3089
  `);
3087
3090
  writeGeneratedFiles(projectRoot, config, scanResult);
3088
3091
  updateGitignore(projectRoot);
3089
- const createdFiles = [
3090
- path18.basename(configPath),
3091
- ".viberails/context.md",
3092
- ".viberails/scan-result.json",
3093
- ...setupSelectedIntegrations(projectRoot, integrations, {
3094
- linter: rootPkgStack?.linter?.split("@")[0],
3095
- packageManager: rootPkgStack?.packageManager
3096
- })
3097
- ];
3098
- clack8.log.success(`Created:
3099
- ${createdFiles.map((f) => ` ${f}`).join("\n")}`);
3092
+ const ok = chalk11.green("\u2713");
3093
+ clack8.log.step(`${ok} ${path18.basename(configPath)}`);
3094
+ clack8.log.step(`${ok} .viberails/context.md`);
3095
+ clack8.log.step(`${ok} .viberails/scan-result.json`);
3096
+ setupSelectedIntegrations(projectRoot, integrations, {
3097
+ linter: rootPkgStack?.linter?.split("@")[0],
3098
+ packageManager: rootPkgStack?.packageManager
3099
+ });
3100
3100
  clack8.outro(
3101
3101
  `Done! Next: review viberails.config.json, then run viberails check
3102
3102
  ${chalk11.dim("Tip: use")} ${chalk11.cyan("viberails check --enforce")} ${chalk11.dim("in CI to block PRs on violations.")}`
@@ -3210,7 +3210,7 @@ ${chalk12.bold("Synced:")}`);
3210
3210
  }
3211
3211
 
3212
3212
  // src/index.ts
3213
- var VERSION = "0.5.4";
3213
+ var VERSION = "0.5.5";
3214
3214
  var program = new Command();
3215
3215
  program.name("viberails").description("Guardrails for vibe coding").version(VERSION);
3216
3216
  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) => {