@krawlup/cli 1.2.0 → 1.2.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/entry.js +242 -48
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,32 @@ All notable changes to `@krawlup/cli` are documented here. The format
4
4
  follows [Keep a Changelog](https://keepachangelog.com/) and the package
5
5
  uses [semantic versioning](https://semver.org/).
6
6
 
7
+ ## 1.2.2 - 2026-11-03
8
+
9
+ ### Added
10
+
11
+ - **Colored output across the CLI.** Battery marks read at a glance —
12
+ ✓ green, ! yellow, ✗ red, – gray — with section titles bold cyan,
13
+ `fix:` values cyan, and summary counts in their own colors. Success
14
+ messages print green, errors red, and the login URL cyan.
15
+ - **Pace-colored loading screens** ("lower is better"): the free-report
16
+ progress bar and elapsed clock run green while a stage is within its
17
+ expected time, yellow up to twice over, red beyond — completed, green.
18
+ - `NO_COLOR` is honored everywhere; `FORCE_COLOR=1`/`FORCE_COLOR=0`
19
+ forces color on or off past the TTY auto-detection. `--json` and
20
+ `--md` output never carry escape codes, and pipes stay byte-clean.
21
+ - The interactive TUI renders battery results as a structured colored
22
+ view (same palette) instead of pasting the plain text render.
23
+
24
+ ## 1.2.1 - 2026-11-03
25
+
26
+ ### Added
27
+
28
+ - **`--version` / `-v`** prints the CLI version and exits — read from
29
+ `package.json` at runtime, and the battery's User-Agent string
30
+ (`krawlup-cli/x.y.z`) now derives from the same source so the two can
31
+ never drift.
32
+
7
33
  ## 1.2.0 - 2026-11-03
8
34
 
9
35
  ### Added
package/dist/entry.js CHANGED
@@ -41209,7 +41209,7 @@ import { join as join2 } from "node:path";
41209
41209
  // package.json
41210
41210
  var package_default = {
41211
41211
  name: "@krawlup/cli",
41212
- version: "1.2.0",
41212
+ version: "1.2.2",
41213
41213
  description: "Official CLI for krawlup — manage products, insights and analytics from the terminal, with a free no-account site battery.",
41214
41214
  license: "MIT",
41215
41215
  author: "Nowshad Hossain Rahat",
@@ -42631,6 +42631,31 @@ function severityTone(severity) {
42631
42631
  }
42632
42632
  }
42633
42633
 
42634
+ // src/checks/verdict.ts
42635
+ var MARKS = {
42636
+ pass: "✓",
42637
+ warn: "!",
42638
+ fail: "✗",
42639
+ unknown: "–"
42640
+ };
42641
+ var STATUS_COLOR = {
42642
+ pass: "green",
42643
+ warn: "yellow",
42644
+ fail: "red",
42645
+ unknown: "gray"
42646
+ };
42647
+ function summarize(sections) {
42648
+ const s = { pass: 0, warn: 0, fail: 0, unknown: 0 };
42649
+ for (const sec of sections) {
42650
+ for (const c of sec.checks)
42651
+ s[c.status]++;
42652
+ }
42653
+ return s;
42654
+ }
42655
+ function exitFor(summary) {
42656
+ return summary.fail > 0 ? 1 : 0;
42657
+ }
42658
+
42634
42659
  // src/ui/components.tsx
42635
42660
  var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
42636
42661
  var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
@@ -42864,6 +42889,110 @@ function IssueLine({ issue: issue2 }) {
42864
42889
  ]
42865
42890
  }, undefined, true, undefined, this);
42866
42891
  }
42892
+ var LOCAL_DETAIL_CAP = 240;
42893
+ function LocalResultView({ result: result2 }) {
42894
+ const s = result2.summary;
42895
+ return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
42896
+ flexDirection: "column",
42897
+ children: [
42898
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42899
+ bold: true,
42900
+ children: result2.title
42901
+ }, undefined, false, undefined, this),
42902
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42903
+ children: [
42904
+ s.fail ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42905
+ color: "red",
42906
+ children: [
42907
+ s.fail,
42908
+ " fail"
42909
+ ]
42910
+ }, "f", true, undefined, this) : null,
42911
+ s.warn ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42912
+ color: "yellow",
42913
+ children: [
42914
+ s.warn,
42915
+ " warn"
42916
+ ]
42917
+ }, "w", true, undefined, this) : null,
42918
+ s.unknown ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42919
+ color: "gray",
42920
+ children: [
42921
+ s.unknown,
42922
+ " unknown"
42923
+ ]
42924
+ }, "u", true, undefined, this) : null,
42925
+ s.pass ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42926
+ color: "green",
42927
+ children: [
42928
+ s.pass,
42929
+ " pass"
42930
+ ]
42931
+ }, "p", true, undefined, this) : null
42932
+ ].filter(Boolean).map((node2, i) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42933
+ children: [
42934
+ i > 0 ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42935
+ dimColor: true,
42936
+ children: " · "
42937
+ }, undefined, false, undefined, this) : null,
42938
+ node2
42939
+ ]
42940
+ }, i, true, undefined, this))
42941
+ }, undefined, false, undefined, this),
42942
+ result2.sections.map((sec) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
42943
+ flexDirection: "column",
42944
+ marginTop: 1,
42945
+ children: [
42946
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42947
+ bold: true,
42948
+ color: "cyan",
42949
+ children: sec.title
42950
+ }, undefined, false, undefined, this),
42951
+ sec.checks.map((ch) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
42952
+ flexDirection: "column",
42953
+ children: [
42954
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42955
+ children: [
42956
+ " ",
42957
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42958
+ color: STATUS_COLOR[ch.status],
42959
+ bold: ch.status !== "unknown",
42960
+ children: MARKS[ch.status]
42961
+ }, undefined, false, undefined, this),
42962
+ " ",
42963
+ ch.label.padEnd(18),
42964
+ ch.detail.slice(0, LOCAL_DETAIL_CAP)
42965
+ ]
42966
+ }, undefined, true, undefined, this),
42967
+ ch.fix ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42968
+ children: [
42969
+ " ",
42970
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42971
+ dimColor: true,
42972
+ children: "fix: "
42973
+ }, undefined, false, undefined, this),
42974
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42975
+ color: "cyan",
42976
+ children: ch.fix
42977
+ }, undefined, false, undefined, this)
42978
+ ]
42979
+ }, undefined, true, undefined, this) : null
42980
+ ]
42981
+ }, ch.id, true, undefined, this)),
42982
+ sec.note ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
42983
+ dimColor: true,
42984
+ children: [
42985
+ " ",
42986
+ sec.note.split(`
42987
+ `).map((l) => l.slice(0, LOCAL_DETAIL_CAP)).join(`
42988
+ `)
42989
+ ]
42990
+ }, undefined, true, undefined, this) : null
42991
+ ]
42992
+ }, sec.id, true, undefined, this))
42993
+ ]
42994
+ }, undefined, true, undefined, this);
42995
+ }
42867
42996
 
42868
42997
  // src/ui/live-pane.tsx
42869
42998
  var import_react32 = __toESM(require_react(), 1);
@@ -42963,6 +43092,48 @@ function pickFirstEditAuditId(issues) {
42963
43092
  // src/ui/public-report.tsx
42964
43093
  var import_react31 = __toESM(require_react(), 1);
42965
43094
 
43095
+ // src/lib/ansi.ts
43096
+ var CODES = {
43097
+ green: "\x1B[32m",
43098
+ yellow: "\x1B[33m",
43099
+ red: "\x1B[31m",
43100
+ cyan: "\x1B[36m",
43101
+ gray: "\x1B[90m",
43102
+ dim: "\x1B[2m",
43103
+ bold: "\x1B[1m"
43104
+ };
43105
+ var RESET = "\x1B[0m";
43106
+ function colorEnabled(stream = process.stdout) {
43107
+ if (process.env.FORCE_COLOR === "1" || process.env.FORCE_COLOR === "true")
43108
+ return true;
43109
+ if (process.env.FORCE_COLOR === "0" || process.env.FORCE_COLOR === "false")
43110
+ return false;
43111
+ if (process.env.NO_COLOR)
43112
+ return false;
43113
+ return !!stream?.isTTY;
43114
+ }
43115
+ function paint(preset, s, enabled) {
43116
+ if (!enabled || s.length === 0)
43117
+ return s;
43118
+ return `${CODES[preset]}${s}${RESET}`;
43119
+ }
43120
+ var green = (s, enabled) => paint("green", s, enabled);
43121
+ var yellow = (s, enabled) => paint("yellow", s, enabled);
43122
+ var red = (s, enabled) => paint("red", s, enabled);
43123
+ var cyan = (s, enabled) => paint("cyan", s, enabled);
43124
+ var gray = (s, enabled) => paint("gray", s, enabled);
43125
+ var dim = (s, enabled) => paint("dim", s, enabled);
43126
+ var bold = (s, enabled) => paint("bold", s, enabled);
43127
+ function paceColor(elapsedSec, expectedSec) {
43128
+ if (expectedSec <= 0)
43129
+ return "green";
43130
+ if (elapsedSec <= expectedSec)
43131
+ return "green";
43132
+ if (elapsedSec <= expectedSec * 2)
43133
+ return "yellow";
43134
+ return "red";
43135
+ }
43136
+
42966
43137
  // src/ui/report-sections.tsx
42967
43138
  var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
42968
43139
  function safeText(v) {
@@ -43654,15 +43825,16 @@ function fmtClock(sec) {
43654
43825
  const s = Math.max(0, Math.floor(sec));
43655
43826
  return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`;
43656
43827
  }
43657
- function Bar({ pct, right, width }) {
43828
+ function Bar({ pct, right, rightTone, tone, width }) {
43658
43829
  const w = Math.max(6, width);
43659
43830
  const filled = Math.round(Math.min(100, Math.max(0, pct)) / 100 * w);
43660
43831
  const bar = "█".repeat(Math.min(filled, w)) + "░".repeat(Math.max(0, w - Math.min(filled, w)));
43832
+ const color = pct >= 100 ? "green" : tone === "yellow" || tone === "red" ? tone : "cyan";
43661
43833
  return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
43662
43834
  children: [
43663
43835
  " ",
43664
43836
  /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
43665
- color: pct >= 100 ? "green" : "cyan",
43837
+ color,
43666
43838
  children: bar
43667
43839
  }, undefined, false, undefined, this),
43668
43840
  " ",
@@ -43673,7 +43845,13 @@ function Bar({ pct, right, width }) {
43673
43845
  "%"
43674
43846
  ]
43675
43847
  }, undefined, true, undefined, this),
43676
- right ? /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
43848
+ right ? rightTone && rightTone !== "green" ? /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
43849
+ color: rightTone,
43850
+ children: [
43851
+ " ",
43852
+ right
43853
+ ]
43854
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
43677
43855
  dimColor: true,
43678
43856
  children: [
43679
43857
  " ",
@@ -43701,6 +43879,10 @@ function PublicScanProgress({
43701
43879
  const elapsedInStage = (Date.now() - state.stageStartMs) / 1000;
43702
43880
  const barPct = Math.max(state.barPct, stageBarPct(state.stageIdx, elapsedInStage, pacing));
43703
43881
  const cols = useTerminalColumns();
43882
+ const stageExpected = PUBLIC_SCAN_STAGES[state.stageIdx]?.seconds ?? 0;
43883
+ const barTone = state.phase === "done" ? "green" : paceColor(elapsedInStage, stageExpected);
43884
+ const plannedSec = PUBLIC_SCAN_STAGES.slice(0, state.stageIdx + 1).reduce((a, s) => a + s.seconds, 0);
43885
+ const clockTone = state.phase === "done" ? "green" : paceColor(state.elapsedSec, plannedSec);
43704
43886
  const labelW = Math.max(20, Math.min(42, cols - 40));
43705
43887
  return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
43706
43888
  flexDirection: "column",
@@ -43774,6 +43956,8 @@ function PublicScanProgress({
43774
43956
  children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Bar, {
43775
43957
  pct: barPct,
43776
43958
  right: fmtClock(state.elapsedSec),
43959
+ rightTone: clockTone,
43960
+ tone: barTone,
43777
43961
  width: Math.max(12, Math.min(32, cols - 44))
43778
43962
  }, undefined, false, undefined, this)
43779
43963
  }, undefined, false, undefined, this),
@@ -45162,8 +45346,23 @@ function normalizeDomainArg(raw) {
45162
45346
  // src/commands/local.ts
45163
45347
  import { Resolver } from "node:dns/promises";
45164
45348
 
45349
+ // src/lib/version.ts
45350
+ import { createRequire as createRequire2 } from "node:module";
45351
+ var require2 = createRequire2(import.meta.url);
45352
+ function readVersion() {
45353
+ for (const rel of ["../package.json", "../../package.json"]) {
45354
+ try {
45355
+ const pkg = require2(rel);
45356
+ if (typeof pkg?.version === "string" && pkg.version)
45357
+ return pkg.version;
45358
+ } catch {}
45359
+ }
45360
+ return "0.0.0";
45361
+ }
45362
+ var CLI_VERSION2 = readVersion();
45363
+
45165
45364
  // src/checks/net.ts
45166
- var KRAWLUP_CLI_UA = "Mozilla/5.0 (compatible; krawlup-cli/1.2; +https://krawlup.com/cli)";
45365
+ var KRAWLUP_CLI_UA = `Mozilla/5.0 (compatible; krawlup-cli/${CLI_VERSION2}; +https://krawlup.com/cli)`;
45167
45366
  var GPTBOT_UA = "GPTBot/1.0 (+https://openai.com/gptbot)";
45168
45367
  var DEFAULT_TIMEOUT_MS = 12000;
45169
45368
  var DEFAULT_CAP_BYTES = 2000000;
@@ -46288,25 +46487,6 @@ function defaultSnapshotDir() {
46288
46487
  return path.join(homedir3(), ".krawlup", "snapshots");
46289
46488
  }
46290
46489
 
46291
- // src/checks/verdict.ts
46292
- var MARKS = {
46293
- pass: "✓",
46294
- warn: "!",
46295
- fail: "✗",
46296
- unknown: "–"
46297
- };
46298
- function summarize(sections) {
46299
- const s = { pass: 0, warn: 0, fail: 0, unknown: 0 };
46300
- for (const sec of sections) {
46301
- for (const c of sec.checks)
46302
- s[c.status]++;
46303
- }
46304
- return s;
46305
- }
46306
- function exitFor(summary) {
46307
- return summary.fail > 0 ? 1 : 0;
46308
- }
46309
-
46310
46490
  // src/commands/local.ts
46311
46491
  class UsageError extends Error {
46312
46492
  }
@@ -46613,31 +46793,37 @@ async function runLocalCommand(cmd, args, io = {}) {
46613
46793
  }
46614
46794
  }
46615
46795
  var DETAIL_CAP = 240;
46616
- function renderLocalText(r) {
46796
+ function renderLocalText(r, opts) {
46797
+ const on = opts?.color ?? colorEnabled();
46617
46798
  const out = [];
46618
- out.push(r.title);
46799
+ out.push(bold(r.title, on));
46619
46800
  out.push([
46620
- r.summary.fail ? `${r.summary.fail} fail` : null,
46621
- r.summary.warn ? `${r.summary.warn} warn` : null,
46622
- r.summary.unknown ? `${r.summary.unknown} unknown` : null,
46623
- r.summary.pass ? `${r.summary.pass} pass` : null
46624
- ].filter(Boolean).join(" · "));
46801
+ r.summary.fail ? red(`${r.summary.fail} fail`, on) : null,
46802
+ r.summary.warn ? yellow(`${r.summary.warn} warn`, on) : null,
46803
+ r.summary.unknown ? gray(`${r.summary.unknown} unknown`, on) : null,
46804
+ r.summary.pass ? green(`${r.summary.pass} pass`, on) : null
46805
+ ].filter(Boolean).join(dim(" · ", on)));
46625
46806
  for (const sec of r.sections) {
46626
46807
  out.push("");
46627
- out.push(sec.title);
46628
- for (const c of sec.checks) {
46629
- out.push(` ${MARKS[c.status]} ${c.label.padEnd(18)}${c.detail.slice(0, DETAIL_CAP)}`);
46630
- if (c.fix)
46631
- out.push(` fix: ${c.fix}`);
46808
+ out.push(bold(cyan(sec.title, on), on));
46809
+ for (const ch of sec.checks) {
46810
+ out.push(` ${mark(ch.status, on)} ${ch.label.padEnd(18)}${ch.detail.slice(0, DETAIL_CAP)}`);
46811
+ if (ch.fix)
46812
+ out.push(` ${dim("fix:", on)} ${cyan(ch.fix, on)}`);
46632
46813
  }
46633
46814
  if (sec.note)
46634
46815
  for (const line of sec.note.split(`
46635
46816
  `))
46636
- out.push(` ${line.slice(0, DETAIL_CAP)}`);
46817
+ out.push(` ${dim(line.slice(0, DETAIL_CAP), on)}`);
46637
46818
  }
46638
46819
  return out.join(`
46639
46820
  `);
46640
46821
  }
46822
+ function mark(status, on) {
46823
+ const preset = STATUS_COLOR[status];
46824
+ const painter = preset === "green" ? green : preset === "yellow" ? yellow : preset === "red" ? red : gray;
46825
+ return painter(MARKS[status], on);
46826
+ }
46641
46827
  function renderLocalJson(r) {
46642
46828
  return JSON.stringify(r, null, 2);
46643
46829
  }
@@ -46655,10 +46841,10 @@ function renderLocalMarkdown(r) {
46655
46841
  for (const sec of r.sections) {
46656
46842
  out.push("", `## ${sec.title}`, "");
46657
46843
  for (const c of sec.checks) {
46658
- const mark = MARKS[c.status];
46844
+ const mark2 = MARKS[c.status];
46659
46845
  const fix = c.fix ? ` Fix: \`${c.fix}\`.` : "";
46660
46846
  const detail = c.detail.replace(/\n/g, " ").slice(0, DETAIL_CAP);
46661
- out.push(`- ${mark} **${c.label}** — ${detail}${/[.!?…]$/.test(detail) ? "" : "."}${fix}`);
46847
+ out.push(`- ${mark2} **${c.label}** — ${detail}${/[.!?…]$/.test(detail) ? "" : "."}${fix}`);
46662
46848
  }
46663
46849
  if (sec.note)
46664
46850
  out.push("", ...sec.note.split(`
@@ -47212,8 +47398,8 @@ function App2() {
47212
47398
  }
47213
47399
  try {
47214
47400
  const result2 = await runLocalCommand(cmd, localArgs);
47215
- push(/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
47216
- children: renderLocalText(result2)
47401
+ push(/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(LocalResultView, {
47402
+ result: result2
47217
47403
  }, undefined, false, undefined, this));
47218
47404
  } catch (e) {
47219
47405
  if (e instanceof UsageError) {
@@ -48054,6 +48240,10 @@ var LOCAL_HELP_BLOCK = `
48054
48240
  krawlup diff <url> snapshot a page; next run reports the drift
48055
48241
  `;
48056
48242
  var argv = process.argv.slice(2);
48243
+ if (argv.includes("--version") || argv.includes("-v")) {
48244
+ console.log(CLI_VERSION2);
48245
+ process.exit(0);
48246
+ }
48057
48247
  var interactive = !!process.stdout.isTTY && !!process.stdin.isTTY && argv.length === 0;
48058
48248
  function helpText(cfg) {
48059
48249
  const allowance = scanAllowance(cfg);
@@ -48086,6 +48276,7 @@ function helpText(cfg) {
48086
48276
  ${LOCAL_HELP_BLOCK}
48087
48277
  --json machine-readable output on data commands
48088
48278
  --help, -h this page
48279
+ --version, -v print the version and exit
48089
48280
 
48090
48281
  'krawlup report' needs no account: your device id (~/.krawlup/device-id)
48091
48282
  carries the free quota — ${allowanceText(cfg)} — and every report read
@@ -48131,19 +48322,20 @@ async function argvMode() {
48131
48322
  console.log(helpText(scanConfig.get()));
48132
48323
  return;
48133
48324
  case "login": {
48325
+ const outOn = colorEnabled();
48134
48326
  const out = await runLogin({
48135
48327
  apiBase: args[0],
48136
- onUrl: (url2, opened) => console.log(opened ? `opening your browser — if it did not, sign in at: ${url2}` : `sign in: ${url2}`)
48328
+ onUrl: (url2, opened) => console.log(opened ? `opening your browser — if it did not, sign in at: ${cyan(url2, outOn)}` : `sign in: ${cyan(url2, outOn)}`)
48137
48329
  });
48138
- console.log(`✓ signed in → ${out.api} (session stored at ~/.krawlup/session.json)`);
48330
+ console.log(green("✓", outOn) + ` signed in → ${out.api} (session stored at ~/.krawlup/session.json)`);
48139
48331
  await refreshScanConfig(out.api);
48140
48332
  if (scanConfig.get().betaUnlimited)
48141
- console.log("✓ beta tester — free scans are unlimited on this account");
48333
+ console.log(green("✓", outOn) + " beta tester — free scans are unlimited on this account");
48142
48334
  return;
48143
48335
  }
48144
48336
  case "logout":
48145
48337
  await runLogout();
48146
- console.log("✓ signed out");
48338
+ console.log(green("✓", colorEnabled()) + " signed out");
48147
48339
  return;
48148
48340
  case "report": {
48149
48341
  let initialScanState = function() {
@@ -48326,8 +48518,10 @@ async function argvMode() {
48326
48518
  break;
48327
48519
  case "scan":
48328
48520
  result2 = await scanAction(product, (update2) => {
48329
- if (process.stderr.isTTY)
48330
- console.error(update2.pending ? "⏳ scan running…" : "⏳ scan finished");
48521
+ if (process.stderr.isTTY) {
48522
+ const errOn = colorEnabled(process.stderr);
48523
+ console.error(update2.pending ? "⏳ scan running…" : green("⏳ scan finished", errOn));
48524
+ }
48331
48525
  });
48332
48526
  break;
48333
48527
  case "publish":
@@ -48405,7 +48599,7 @@ ${helpText(scanConfig.get())}`);
48405
48599
  if (argv.includes("--json")) {
48406
48600
  console.log(JSON.stringify({ error: true, message: msg }, null, 2));
48407
48601
  } else {
48408
- console.error(`✗ ${msg}`);
48602
+ console.error(red(`✗ ${msg}`, colorEnabled(process.stderr)));
48409
48603
  }
48410
48604
  process.exitCode = e instanceof ReLoginRequired ? 2 : 1;
48411
48605
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krawlup/cli",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Official CLI for krawlup — manage products, insights and analytics from the terminal, with a free no-account site battery.",
5
5
  "license": "MIT",
6
6
  "author": "Nowshad Hossain Rahat",