relionhq 2.1.0 → 2.1.1

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.
Files changed (2) hide show
  1. package/dist/index.js +33 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -237,28 +237,31 @@ function wordWrap(text, maxWidth) {
237
237
  if (current) lines.push(current);
238
238
  return lines.length ? lines : [""];
239
239
  }
240
- function boxLine(content, width) {
240
+ var INNER = 64;
241
+ var TEXT = INNER - 4;
242
+ function boxLine(content) {
241
243
  const stripped = stripAnsi(content);
242
- const gap = Math.max(0, width - stripped.length);
244
+ const gap = Math.max(0, TEXT - stripped.length);
243
245
  return `\u2502 ${content}${" ".repeat(gap)} \u2502`;
244
246
  }
245
- function blankLine(width) {
246
- return `\u2502${" ".repeat(width + 2)}\u2502`;
247
+ function blankLine() {
248
+ return `\u2502${" ".repeat(INNER)}\u2502`;
249
+ }
250
+ function divider() {
251
+ return `\u251C${"\u2500".repeat(INNER)}\u2524`;
247
252
  }
248
253
  function printPredeployReceipt(opts) {
249
254
  if (QUIET) return;
250
- const width = 62;
251
- const line = "\u2500".repeat(width);
252
255
  const pad = (label, value) => {
253
256
  const stripped = stripAnsi(value);
254
- const gap = Math.max(1, width - label.length - stripped.length - 2);
257
+ const gap = Math.max(1, TEXT - label.length - stripped.length);
255
258
  return `\u2502 ${label}${" ".repeat(gap)}${value} \u2502`;
256
259
  };
257
260
  const verdictLabel = opts.verdict === "safe" ? color.green("\u2713 SAFE") : opts.verdict === "caution" ? color.yellow("\u26A0 CAUTION") : opts.verdict === "high_risk" ? color.red("\u2717 HIGH RISK") : opts.verdict === "blocked" ? color.red("\u2717 BLOCKED") : color.dim("\u2014 OFFLINE");
258
261
  console.log("");
259
- console.log(`\u250C${"\u2500".repeat(width + 2)}\u2510`);
260
- console.log(`\u2502 ${color.bold("Relion Pre-Deploy Check")}${" ".repeat(width - 22)} \u2502`);
261
- console.log(`\u251C${line}\u2524`);
262
+ console.log(`\u250C${"\u2500".repeat(INNER)}\u2510`);
263
+ console.log(`\u2502 ${color.bold("Relion Pre-Deploy Check")}${" ".repeat(TEXT - 22)} \u2502`);
264
+ console.log(divider());
262
265
  if (opts.branch || opts.commit) {
263
266
  const meta = [opts.branch, opts.commit ? opts.commit.slice(0, 7) : ""].filter(Boolean).join(" \xB7 ");
264
267
  console.log(pad("Branch:", color.dim(meta)));
@@ -266,59 +269,56 @@ function printPredeployReceipt(opts) {
266
269
  if (opts.baseBranch) console.log(pad("Comparing against:", color.dim(opts.baseBranch)));
267
270
  console.log(pad("Duration:", color.dim(`${(opts.durationMs / 1e3).toFixed(1)}s`)));
268
271
  if (opts.offline) console.log(pad("Mode:", color.yellow("offline")));
269
- console.log(`\u251C${line}\u2524`);
272
+ console.log(divider());
270
273
  console.log(pad("Files in diff:", String(opts.filesChangedCount)));
271
274
  console.log(pad("APIs involved:", String(opts.apisInvolvedCount)));
272
- console.log(`\u251C${line}\u2524`);
275
+ console.log(divider());
273
276
  console.log(pad("Verdict:", verdictLabel));
274
277
  const nonSafe = opts.findings.filter((f) => f.riskLevel !== "safe" && f.riskLevel !== "info");
275
278
  if (nonSafe.length > 0) {
276
- console.log(`\u251C${line}\u2524`);
279
+ console.log(divider());
277
280
  for (const finding of nonSafe) {
278
- console.log(blankLine(width));
281
+ console.log(blankLine());
279
282
  const icon = finding.riskLevel === "blocked" ? color.red("\u2717") : finding.riskLevel === "high_risk" ? color.red("!") : color.yellow("\u26A0");
280
283
  const badge = finding.riskLevel === "blocked" ? color.red("[BLOCKED]") : finding.riskLevel === "high_risk" ? color.red("[HIGH RISK]") : color.yellow("[CAUTION]");
281
284
  const sourceTag = finding.source === "probe_failure" ? color.dim(" \xB7 live probe") : finding.source === "vendor_change" ? color.dim(" \xB7 spec change") : finding.source === "alert" ? color.dim(" \xB7 alert") : "";
282
- const headerText = `${icon} ${badge} ${color.bold(finding.vendorName)}${sourceTag}`;
283
- console.log(boxLine(headerText, width));
285
+ console.log(boxLine(`${icon} ${badge} ${color.bold(finding.vendorName)}${sourceTag}`));
284
286
  const title = finding.title ?? finding.description;
285
287
  if (title) {
286
- const titleLines = wordWrap(title, width - 4);
287
- for (const tl of titleLines) {
288
- console.log(boxLine(` ${color.dim(tl)}`, width));
288
+ for (const tl of wordWrap(title, TEXT - 4)) {
289
+ console.log(boxLine(` ${color.dim(tl)}`));
289
290
  }
290
291
  }
291
292
  if (finding.versionFrom || finding.versionTo) {
292
- const vRange = [finding.versionFrom, finding.versionTo].filter(Boolean).join(color.dim(" \u2192 "));
293
- console.log(boxLine(` ${color.dim("v")}${vRange}`, width));
293
+ const vRange = [finding.versionFrom, finding.versionTo].filter(Boolean).join(" \u2192 ");
294
+ console.log(boxLine(` v${vRange}`));
294
295
  }
295
296
  const body = finding.summary ?? finding.description;
296
297
  if (body) {
297
- const bodyLines = wordWrap(body, width - 4);
298
- console.log(blankLine(width));
299
- for (const bl of bodyLines) {
300
- console.log(boxLine(` ${bl}`, width));
298
+ console.log(blankLine());
299
+ for (const bl of wordWrap(body, TEXT - 4)) {
300
+ console.log(boxLine(` ${bl}`));
301
301
  }
302
302
  }
303
303
  if (finding.recommendation) {
304
- const recLines = wordWrap(finding.recommendation, width - 7);
305
- console.log(blankLine(width));
304
+ console.log(blankLine());
305
+ const recLines = wordWrap(finding.recommendation, TEXT - 7);
306
306
  for (let i = 0; i < recLines.length; i++) {
307
307
  const prefix = i === 0 ? ` ${color.cyan("\u2192")} ` : " ";
308
- console.log(boxLine(`${prefix}${recLines[i]}`, width));
308
+ console.log(boxLine(`${prefix}${recLines[i]}`));
309
309
  }
310
310
  }
311
311
  }
312
- console.log(blankLine(width));
312
+ console.log(blankLine());
313
313
  if (nonSafe.length > 1) {
314
- console.log(boxLine(color.dim(` ${nonSafe.length} finding${nonSafe.length === 1 ? "" : "s"} total`), width));
314
+ console.log(boxLine(color.dim(` ${nonSafe.length} findings total`)));
315
315
  }
316
316
  }
317
317
  if (opts.dashboardUrl) {
318
- console.log(`\u251C${line}\u2524`);
319
- console.log(boxLine(`${color.cyan("View:")} ${color.dim(opts.dashboardUrl)}`, width));
318
+ console.log(divider());
319
+ console.log(boxLine(`${color.cyan("View:")} ${color.dim(opts.dashboardUrl)}`));
320
320
  }
321
- console.log(`\u2514${"\u2500".repeat(width + 2)}\u2518`);
321
+ console.log(`\u2514${"\u2500".repeat(INNER)}\u2518`);
322
322
  console.log("");
323
323
  if (opts.verdict === "safe" && !QUIET) {
324
324
  console.log(`${color.green("\u2713")} No API risk detected. Safe to deploy.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relionhq",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Relion CLI — pre-deploy API risk detection and monitoring client.",
5
5
  "license": "MIT",
6
6
  "bin": {