@doccov/cli 0.28.0 → 0.28.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/cli.js +216 -807
  2. package/package.json +2 -3
package/dist/cli.js CHANGED
@@ -87,26 +87,75 @@ import {
87
87
  parseExamplesFlag,
88
88
  resolveTarget
89
89
  } from "@doccov/sdk";
90
- import chalk7 from "chalk";
90
+ import chalk6 from "chalk";
91
91
 
92
- // ../cli-utils/dist/index.js
92
+ // src/utils/filter-options.ts
93
+ import { mergeFilters, parseListFlag } from "@doccov/sdk";
93
94
  import chalk from "chalk";
95
+ var parseVisibilityFlag = (value) => {
96
+ if (!value)
97
+ return;
98
+ const validTags = ["public", "beta", "alpha", "internal"];
99
+ const parsed = parseListFlag(value);
100
+ if (!parsed)
101
+ return;
102
+ const result = [];
103
+ for (const tag of parsed) {
104
+ const lower = tag.toLowerCase();
105
+ if (validTags.includes(lower)) {
106
+ result.push(lower);
107
+ }
108
+ }
109
+ return result.length > 0 ? result : undefined;
110
+ };
111
+ var formatList = (label, values) => `${label}: ${values.map((value) => chalk.cyan(value)).join(", ")}`;
112
+ var mergeFilterOptions = (config, cliOptions) => {
113
+ const messages = [];
114
+ if (config?.include) {
115
+ messages.push(formatList("include filters from config", config.include));
116
+ }
117
+ if (config?.exclude) {
118
+ messages.push(formatList("exclude filters from config", config.exclude));
119
+ }
120
+ if (cliOptions.include) {
121
+ messages.push(formatList("apply include filters from CLI", cliOptions.include));
122
+ }
123
+ if (cliOptions.exclude) {
124
+ messages.push(formatList("apply exclude filters from CLI", cliOptions.exclude));
125
+ }
126
+ if (cliOptions.visibility) {
127
+ messages.push(formatList("apply visibility filter from CLI", cliOptions.visibility));
128
+ }
129
+ const resolved = mergeFilters(config, cliOptions);
130
+ if (!resolved.include && !resolved.exclude && !cliOptions.visibility) {
131
+ return { messages };
132
+ }
133
+ const source = resolved.source === "override" ? "cli" : resolved.source;
134
+ return {
135
+ include: resolved.include,
136
+ exclude: resolved.exclude,
137
+ visibility: cliOptions.visibility,
138
+ source,
139
+ messages
140
+ };
141
+ };
142
+
143
+ // src/utils/progress/colors.ts
94
144
  import chalk2 from "chalk";
95
- import { Worker } from "node:worker_threads";
96
145
  var colors = {
97
- success: chalk.green,
98
- error: chalk.red,
99
- warning: chalk.yellow,
100
- info: chalk.cyan,
101
- muted: chalk.gray,
102
- bold: chalk.bold,
103
- dim: chalk.dim,
104
- underline: chalk.underline,
105
- primary: chalk.cyan,
106
- secondary: chalk.magenta,
107
- path: chalk.cyan,
108
- number: chalk.yellow,
109
- code: chalk.gray
146
+ success: chalk2.green,
147
+ error: chalk2.red,
148
+ warning: chalk2.yellow,
149
+ info: chalk2.cyan,
150
+ muted: chalk2.gray,
151
+ bold: chalk2.bold,
152
+ dim: chalk2.dim,
153
+ underline: chalk2.underline,
154
+ primary: chalk2.cyan,
155
+ secondary: chalk2.magenta,
156
+ path: chalk2.cyan,
157
+ number: chalk2.yellow,
158
+ code: chalk2.gray
110
159
  };
111
160
  var symbols = {
112
161
  success: "✓",
@@ -145,6 +194,10 @@ var prefix = {
145
194
  warning: colors.warning(symbols.warning),
146
195
  info: colors.info(symbols.info)
147
196
  };
197
+ // src/utils/progress/spinner.ts
198
+ import chalk3 from "chalk";
199
+
200
+ // src/utils/progress/utils.ts
148
201
  function isTTY() {
149
202
  return Boolean(process.stdout.isTTY);
150
203
  }
@@ -166,18 +219,6 @@ function getTerminalWidth() {
166
219
  const width = process.stdout.columns || DEFAULT_TERMINAL_WIDTH;
167
220
  return Math.max(width, MIN_TERMINAL_WIDTH);
168
221
  }
169
- function formatDuration(ms) {
170
- if (ms < 1000) {
171
- return `${ms}ms`;
172
- }
173
- const seconds = ms / 1000;
174
- if (seconds < 60) {
175
- return `${seconds.toFixed(1)}s`;
176
- }
177
- const minutes = Math.floor(seconds / 60);
178
- const remainingSeconds = Math.floor(seconds % 60);
179
- return `${minutes}m ${remainingSeconds}s`;
180
- }
181
222
  var cursor = {
182
223
  hide: "\x1B[?25l",
183
224
  show: "\x1B[?25h",
@@ -196,11 +237,6 @@ function clearLine() {
196
237
  process.stdout.write(cursor.clearLine + cursor.left);
197
238
  }
198
239
  }
199
- function moveCursorUp(lines = 1) {
200
- if (isTTY()) {
201
- process.stdout.write(cursor.up(lines));
202
- }
203
- }
204
240
  function hideCursor() {
205
241
  if (isTTY()) {
206
242
  process.stdout.write(cursor.hide);
@@ -221,391 +257,15 @@ function stripAnsi(text) {
221
257
  return text.replace(ANSI_REGEX, "");
222
258
  }
223
259
 
224
- class MultiProgress {
225
- bars = new Map;
226
- barOrder = [];
227
- options;
228
- spinnerFrames;
229
- spinnerIndex = 0;
230
- timer = null;
231
- lastRenderedLines = 0;
232
- symbols = getSymbols(supportsUnicode());
233
- sigintHandler = null;
234
- filledChar;
235
- emptyChar;
236
- constructor(options = {}) {
237
- this.options = {
238
- barWidth: options.barWidth,
239
- showPercent: options.showPercent ?? true,
240
- showCount: options.showCount ?? true,
241
- spinnerInterval: options.spinnerInterval ?? 80
242
- };
243
- this.spinnerFrames = supportsUnicode() ? ["◐", "◓", "◑", "◒"] : ["-", "\\", "|", "/"];
244
- const unicode = supportsUnicode();
245
- this.filledChar = unicode ? "█" : "#";
246
- this.emptyChar = unicode ? "░" : "-";
247
- }
248
- start() {
249
- if (!isInteractive())
250
- return this;
251
- hideCursor();
252
- this.setupSignalHandler();
253
- this.timer = setInterval(() => {
254
- if (this.bars.size > 0 && [...this.bars.values()].some((b) => b.status === "active")) {
255
- this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
256
- this.render();
257
- }
258
- }, this.options.spinnerInterval);
259
- return this;
260
- }
261
- add(config) {
262
- const state = {
263
- id: config.id,
264
- label: config.label,
265
- total: config.total ?? 100,
266
- current: config.current ?? 0,
267
- status: "active",
268
- startTime: Date.now()
269
- };
270
- this.bars.set(config.id, state);
271
- if (!this.barOrder.includes(config.id)) {
272
- this.barOrder.push(config.id);
273
- }
274
- if (!isInteractive()) {
275
- console.log(`${this.symbols.bullet} ${config.label}`);
276
- } else {
277
- this.render();
278
- }
279
- return this;
280
- }
281
- update(id, current, label) {
282
- const bar = this.bars.get(id);
283
- if (!bar)
284
- return this;
285
- bar.current = Math.min(current, bar.total);
286
- if (label !== undefined)
287
- bar.label = label;
288
- if (isInteractive()) {
289
- this.render();
290
- }
291
- return this;
292
- }
293
- increment(id, amount = 1) {
294
- const bar = this.bars.get(id);
295
- if (!bar)
296
- return this;
297
- return this.update(id, bar.current + amount);
298
- }
299
- complete(id, label) {
300
- const bar = this.bars.get(id);
301
- if (!bar)
302
- return this;
303
- bar.status = "completed";
304
- bar.current = bar.total;
305
- if (label !== undefined)
306
- bar.label = label;
307
- if (!isInteractive()) {
308
- console.log(`${colors.success(this.symbols.success)} ${bar.label}`);
309
- } else {
310
- this.render();
311
- }
312
- return this;
313
- }
314
- fail(id, label) {
315
- const bar = this.bars.get(id);
316
- if (!bar)
317
- return this;
318
- bar.status = "failed";
319
- if (label !== undefined)
320
- bar.label = label;
321
- if (!isInteractive()) {
322
- console.log(`${colors.error(this.symbols.error)} ${bar.label}`);
323
- } else {
324
- this.render();
325
- }
326
- return this;
327
- }
328
- remove(id) {
329
- this.bars.delete(id);
330
- this.barOrder = this.barOrder.filter((i) => i !== id);
331
- if (isInteractive()) {
332
- this.render();
333
- }
334
- return this;
335
- }
336
- get(id) {
337
- return this.bars.get(id);
338
- }
339
- get allDone() {
340
- if (this.bars.size === 0)
341
- return true;
342
- return [...this.bars.values()].every((b) => b.status !== "active");
343
- }
344
- stop() {
345
- if (this.timer) {
346
- clearInterval(this.timer);
347
- this.timer = null;
348
- }
349
- this.cleanup();
350
- return this;
351
- }
352
- render() {
353
- if (!isTTY())
354
- return;
355
- this.clearOutput();
356
- const width = getTerminalWidth();
357
- const lines = [];
358
- for (const id of this.barOrder) {
359
- const bar = this.bars.get(id);
360
- if (!bar)
361
- continue;
362
- const line = this.renderBar(bar, width);
363
- lines.push(line);
364
- }
365
- if (lines.length > 0) {
366
- process.stdout.write(lines.join(`
367
- `));
368
- this.lastRenderedLines = lines.length;
369
- }
370
- }
371
- renderBar(bar, termWidth) {
372
- const parts = [];
373
- let symbol;
374
- switch (bar.status) {
375
- case "completed":
376
- symbol = colors.success(this.symbols.success);
377
- break;
378
- case "failed":
379
- symbol = colors.error(this.symbols.error);
380
- break;
381
- default:
382
- symbol = colors.primary(this.spinnerFrames[this.spinnerIndex]);
383
- }
384
- parts.push(symbol);
385
- parts.push(bar.label);
386
- const suffixParts = [];
387
- if (this.options.showPercent) {
388
- const pct = bar.total === 0 ? 0 : Math.round(bar.current / bar.total * 100);
389
- suffixParts.push(`${pct}%`);
390
- }
391
- if (this.options.showCount) {
392
- suffixParts.push(`${bar.current}/${bar.total}`);
393
- }
394
- const suffix = suffixParts.length > 0 ? ` ${suffixParts.join(" ")}` : "";
395
- const labelLen = stripAnsi(parts.join(" ")).length + 1;
396
- const bracketLen = 2;
397
- const suffixLen = stripAnsi(suffix).length;
398
- const minBarWidth = 10;
399
- const availableWidth = termWidth - labelLen - bracketLen - suffixLen - 1;
400
- const barWidth = this.options.barWidth ?? Math.max(minBarWidth, Math.min(30, availableWidth));
401
- const filledWidth = Math.round(bar.current / bar.total * barWidth);
402
- const emptyWidth = barWidth - filledWidth;
403
- const barViz = `[${this.filledChar.repeat(filledWidth)}${this.emptyChar.repeat(emptyWidth)}]`;
404
- parts.push(barViz);
405
- return truncate(parts.join(" ") + suffix, termWidth);
406
- }
407
- clearOutput() {
408
- if (!isTTY() || this.lastRenderedLines === 0)
409
- return;
410
- for (let i = 0;i < this.lastRenderedLines; i++) {
411
- if (i > 0)
412
- process.stdout.write(cursor.up(1));
413
- clearLine();
414
- }
415
- this.lastRenderedLines = 0;
416
- }
417
- setupSignalHandler() {
418
- this.sigintHandler = () => {
419
- this.cleanup();
420
- process.exit(130);
421
- };
422
- process.on("SIGINT", this.sigintHandler);
423
- }
424
- cleanup() {
425
- if (this.sigintHandler) {
426
- process.removeListener("SIGINT", this.sigintHandler);
427
- this.sigintHandler = null;
428
- }
429
- showCursor();
430
- if (isTTY() && this.lastRenderedLines > 0) {
431
- process.stdout.write(`
432
- `);
433
- }
434
- }
435
- }
436
- class ProgressBar {
437
- total;
438
- current;
439
- label;
440
- width;
441
- showPercent;
442
- showCount;
443
- showETA;
444
- filledChar;
445
- emptyChar;
446
- startTime = null;
447
- lastRender = "";
448
- symbols = getSymbols(supportsUnicode());
449
- sigintHandler = null;
450
- isComplete = false;
451
- constructor(options = {}) {
452
- this.total = options.total ?? 100;
453
- this.current = options.current ?? 0;
454
- this.label = options.label ?? "";
455
- this.width = options.width;
456
- this.showPercent = options.showPercent ?? true;
457
- this.showCount = options.showCount ?? true;
458
- this.showETA = options.showETA ?? true;
459
- const unicode = supportsUnicode();
460
- this.filledChar = options.chars?.filled ?? (unicode ? "█" : "#");
461
- this.emptyChar = options.chars?.empty ?? (unicode ? "░" : "-");
462
- }
463
- start(label) {
464
- if (label !== undefined)
465
- this.label = label;
466
- this.startTime = Date.now();
467
- this.current = 0;
468
- this.isComplete = false;
469
- if (!isInteractive()) {
470
- console.log(`${this.symbols.bullet} ${this.label}`);
471
- return this;
472
- }
473
- hideCursor();
474
- this.setupSignalHandler();
475
- this.render();
476
- return this;
477
- }
478
- update(current) {
479
- this.current = Math.min(current, this.total);
480
- if (isInteractive()) {
481
- this.render();
482
- }
483
- return this;
484
- }
485
- increment(amount = 1) {
486
- return this.update(this.current + amount);
487
- }
488
- setLabel(label) {
489
- this.label = label;
490
- if (isInteractive()) {
491
- this.render();
492
- }
493
- return this;
494
- }
495
- setTotal(total) {
496
- this.total = total;
497
- if (isInteractive()) {
498
- this.render();
499
- }
500
- return this;
501
- }
502
- complete(label) {
503
- if (label !== undefined)
504
- this.label = label;
505
- this.current = this.total;
506
- this.isComplete = true;
507
- if (!isInteractive()) {
508
- console.log(`${colors.success(this.symbols.success)} ${this.label}`);
509
- } else {
510
- clearLine();
511
- process.stdout.write(`${colors.success(this.symbols.success)} ${this.label}
512
- `);
513
- }
514
- this.cleanup();
515
- return this;
516
- }
517
- fail(label) {
518
- if (label !== undefined)
519
- this.label = label;
520
- this.isComplete = true;
521
- if (!isInteractive()) {
522
- console.log(`${colors.error(this.symbols.error)} ${this.label}`);
523
- } else {
524
- clearLine();
525
- process.stdout.write(`${colors.error(this.symbols.error)} ${this.label}
526
- `);
527
- }
528
- this.cleanup();
529
- return this;
530
- }
531
- get percentage() {
532
- return this.total === 0 ? 0 : Math.round(this.current / this.total * 100);
533
- }
534
- get isDone() {
535
- return this.isComplete || this.current >= this.total;
536
- }
537
- render() {
538
- if (!isTTY())
539
- return;
540
- const termWidth = getTerminalWidth();
541
- const parts = [];
542
- if (this.label) {
543
- parts.push(this.label);
544
- }
545
- const suffixParts = [];
546
- if (this.showPercent) {
547
- suffixParts.push(`${this.percentage}%`);
548
- }
549
- if (this.showCount) {
550
- suffixParts.push(`${this.current}/${this.total}`);
551
- }
552
- if (this.showETA && this.startTime) {
553
- const eta = this.calculateETA();
554
- if (eta)
555
- suffixParts.push(eta);
556
- }
557
- const suffix = suffixParts.length > 0 ? ` ${suffixParts.join(" ")}` : "";
558
- const labelLen = this.label ? stripAnsi(this.label).length + 1 : 0;
559
- const bracketLen = 2;
560
- const suffixLen = stripAnsi(suffix).length;
561
- const minBarWidth = 10;
562
- const availableWidth = termWidth - labelLen - bracketLen - suffixLen - 1;
563
- const barWidth = this.width ?? Math.max(minBarWidth, Math.min(40, availableWidth));
564
- const filledWidth = Math.round(this.current / this.total * barWidth);
565
- const emptyWidth = barWidth - filledWidth;
566
- const bar = `[${this.filledChar.repeat(filledWidth)}${this.emptyChar.repeat(emptyWidth)}]`;
567
- parts.push(bar);
568
- const line = truncate(parts.join(" ") + suffix, termWidth);
569
- if (line !== this.lastRender) {
570
- clearLine();
571
- process.stdout.write(line);
572
- this.lastRender = line;
573
- }
574
- }
575
- calculateETA() {
576
- if (!this.startTime || this.current === 0)
577
- return null;
578
- const elapsed = Date.now() - this.startTime;
579
- if (elapsed < 1000)
580
- return null;
581
- const rate = this.current / elapsed;
582
- const remaining = this.total - this.current;
583
- const etaMs = remaining / rate;
584
- return `ETA ${formatDuration(etaMs)}`;
585
- }
586
- setupSignalHandler() {
587
- this.sigintHandler = () => {
588
- this.cleanup();
589
- process.exit(130);
590
- };
591
- process.on("SIGINT", this.sigintHandler);
592
- }
593
- cleanup() {
594
- if (this.sigintHandler) {
595
- process.removeListener("SIGINT", this.sigintHandler);
596
- this.sigintHandler = null;
597
- }
598
- showCursor();
599
- }
600
- }
260
+ // src/utils/progress/spinner.ts
601
261
  var spinnerColors = {
602
- cyan: chalk2.cyan,
603
- yellow: chalk2.yellow,
604
- green: chalk2.green,
605
- red: chalk2.red,
606
- magenta: chalk2.magenta,
607
- blue: chalk2.blue,
608
- white: chalk2.white
262
+ cyan: chalk3.cyan,
263
+ yellow: chalk3.yellow,
264
+ green: chalk3.green,
265
+ red: chalk3.red,
266
+ magenta: chalk3.magenta,
267
+ blue: chalk3.blue,
268
+ white: chalk3.white
609
269
  };
610
270
  var FRAME_SETS = {
611
271
  dots: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
@@ -625,13 +285,11 @@ class Spinner {
625
285
  symbols = getSymbols(supportsUnicode());
626
286
  lastRenderedLines = 0;
627
287
  sigintHandler = null;
628
- animate;
629
288
  constructor(options = {}) {
630
289
  this.label = options.label ?? "";
631
290
  this.detail = options.detail;
632
291
  this.interval = options.interval ?? 80;
633
292
  this.colorFn = spinnerColors[options.color ?? "cyan"];
634
- this.animate = options.animate ?? true;
635
293
  const style = options.style ?? "circle";
636
294
  this.frames = supportsUnicode() ? FRAME_SETS[style] : ASCII_FRAME_SET;
637
295
  }
@@ -643,7 +301,7 @@ class Spinner {
643
301
  this.state = "spinning";
644
302
  this.frameIndex = 0;
645
303
  this.lastRenderedLines = 0;
646
- if (!isInteractive() || !this.animate) {
304
+ if (!isInteractive()) {
647
305
  console.log(`${this.symbols.bullet} ${this.label}`);
648
306
  return this;
649
307
  }
@@ -701,12 +359,14 @@ class Spinner {
701
359
  this.timer = null;
702
360
  }
703
361
  this.state = state;
704
- const symbol = state === "success" ? this.symbols.success : this.symbols.error;
705
- const colorFn = state === "success" ? colors.success : colors.error;
706
- if (!isInteractive() || !this.animate) {
362
+ if (!isInteractive()) {
363
+ const symbol = state === "success" ? this.symbols.success : this.symbols.error;
364
+ const colorFn = state === "success" ? colors.success : colors.error;
707
365
  console.log(`${colorFn(symbol)} ${this.label}`);
708
366
  } else {
709
367
  this.clearOutput();
368
+ const symbol = state === "success" ? this.symbols.success : this.symbols.error;
369
+ const colorFn = state === "success" ? colors.success : colors.error;
710
370
  process.stdout.write(`${colorFn(symbol)} ${this.label}
711
371
  `);
712
372
  }
@@ -756,206 +416,7 @@ ${detailLine}`);
756
416
  function spinner(label, options) {
757
417
  return new Spinner({ ...options, label }).start();
758
418
  }
759
-
760
- class StepProgress {
761
- steps = [];
762
- showNumbers;
763
- spinnerInterval;
764
- spinnerFrames;
765
- spinnerIndex = 0;
766
- timer = null;
767
- symbols = getSymbols(supportsUnicode());
768
- lastRenderedLines = 0;
769
- sigintHandler = null;
770
- constructor(options = {}) {
771
- this.showNumbers = options.showNumbers ?? true;
772
- this.spinnerInterval = options.spinnerInterval ?? 80;
773
- this.spinnerFrames = supportsUnicode() ? ["◐", "◓", "◑", "◒"] : ["-", "\\", "|", "/"];
774
- if (options.steps) {
775
- this.steps = options.steps.map((label) => ({ label, status: "pending" }));
776
- }
777
- }
778
- start() {
779
- if (!isInteractive())
780
- return this;
781
- hideCursor();
782
- this.setupSignalHandler();
783
- this.render();
784
- this.timer = setInterval(() => {
785
- if (this.steps.some((s) => s.status === "active")) {
786
- this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
787
- this.render();
788
- }
789
- }, this.spinnerInterval);
790
- return this;
791
- }
792
- addStep(label) {
793
- this.steps.push({ label, status: "pending" });
794
- if (isInteractive())
795
- this.render();
796
- return this;
797
- }
798
- startStep(index) {
799
- if (index >= 0 && index < this.steps.length) {
800
- this.steps[index].status = "active";
801
- this.steps[index].startTime = Date.now();
802
- if (isInteractive()) {
803
- this.render();
804
- } else {
805
- const step = this.steps[index];
806
- const prefix2 = this.showNumbers ? `[${index + 1}/${this.steps.length}] ` : "";
807
- console.log(`${this.symbols.bullet} ${prefix2}${step.label}...`);
808
- }
809
- }
810
- return this;
811
- }
812
- completeStep(index) {
813
- if (index >= 0 && index < this.steps.length) {
814
- this.steps[index].status = "completed";
815
- this.steps[index].endTime = Date.now();
816
- if (isInteractive()) {
817
- this.render();
818
- } else {
819
- const step = this.steps[index];
820
- const duration = this.getStepDuration(step);
821
- const prefix2 = this.showNumbers ? `[${index + 1}/${this.steps.length}] ` : "";
822
- console.log(`${colors.success(this.symbols.success)} ${prefix2}${step.label}${duration}`);
823
- }
824
- }
825
- return this;
826
- }
827
- failStep(index) {
828
- if (index >= 0 && index < this.steps.length) {
829
- this.steps[index].status = "failed";
830
- this.steps[index].endTime = Date.now();
831
- if (isInteractive()) {
832
- this.render();
833
- } else {
834
- const step = this.steps[index];
835
- const prefix2 = this.showNumbers ? `[${index + 1}/${this.steps.length}] ` : "";
836
- console.log(`${colors.error(this.symbols.error)} ${prefix2}${step.label}`);
837
- }
838
- }
839
- return this;
840
- }
841
- skipStep(index) {
842
- if (index >= 0 && index < this.steps.length) {
843
- this.steps[index].status = "skipped";
844
- if (isInteractive())
845
- this.render();
846
- }
847
- return this;
848
- }
849
- async run(tasks) {
850
- this.steps = tasks.map((t) => ({ label: t.label, status: "pending" }));
851
- this.start();
852
- const results = [];
853
- let failed = false;
854
- for (let i = 0;i < tasks.length; i++) {
855
- if (failed) {
856
- this.skipStep(i);
857
- continue;
858
- }
859
- this.startStep(i);
860
- try {
861
- results.push(await tasks[i].task());
862
- this.completeStep(i);
863
- } catch {
864
- this.failStep(i);
865
- failed = true;
866
- }
867
- }
868
- this.stop();
869
- return { results, failed };
870
- }
871
- stop() {
872
- if (this.timer) {
873
- clearInterval(this.timer);
874
- this.timer = null;
875
- }
876
- this.cleanup();
877
- return this;
878
- }
879
- get currentStepIndex() {
880
- const activeIdx = this.steps.findIndex((s) => s.status === "active");
881
- if (activeIdx >= 0)
882
- return activeIdx;
883
- return this.steps.findIndex((s) => s.status === "pending");
884
- }
885
- render() {
886
- if (!isTTY())
887
- return;
888
- if (this.lastRenderedLines > 0) {
889
- moveCursorUp(this.lastRenderedLines - 1);
890
- for (let i = 0;i < this.lastRenderedLines; i++) {
891
- clearLine();
892
- if (i < this.lastRenderedLines - 1) {
893
- process.stdout.write(cursor.down(1));
894
- }
895
- }
896
- moveCursorUp(this.lastRenderedLines - 1);
897
- }
898
- const width = getTerminalWidth();
899
- const lines = [];
900
- for (let i = 0;i < this.steps.length; i++) {
901
- const step = this.steps[i];
902
- const prefix2 = this.showNumbers ? `[${i + 1}/${this.steps.length}] ` : "";
903
- const duration = this.getStepDuration(step);
904
- let symbol;
905
- let text;
906
- switch (step.status) {
907
- case "completed":
908
- symbol = colors.success(this.symbols.success);
909
- text = `${prefix2}${step.label}${duration}`;
910
- break;
911
- case "failed":
912
- symbol = colors.error(this.symbols.error);
913
- text = `${prefix2}${step.label}`;
914
- break;
915
- case "active":
916
- symbol = colors.primary(this.spinnerFrames[this.spinnerIndex]);
917
- text = `${prefix2}${step.label}`;
918
- break;
919
- case "skipped":
920
- symbol = colors.muted(this.symbols.bullet);
921
- text = colors.muted(`${prefix2}${step.label} (skipped)`);
922
- break;
923
- default:
924
- symbol = colors.muted("○");
925
- text = colors.muted(`${prefix2}${step.label}`);
926
- }
927
- lines.push(truncate(`${symbol} ${text}`, width));
928
- }
929
- process.stdout.write(lines.join(`
930
- `));
931
- this.lastRenderedLines = lines.length;
932
- }
933
- getStepDuration(step) {
934
- if (step.startTime && step.endTime) {
935
- const ms = step.endTime - step.startTime;
936
- return colors.muted(` (${formatDuration(ms)})`);
937
- }
938
- return "";
939
- }
940
- setupSignalHandler() {
941
- this.sigintHandler = () => {
942
- this.cleanup();
943
- process.exit(130);
944
- };
945
- process.on("SIGINT", this.sigintHandler);
946
- }
947
- cleanup() {
948
- if (this.sigintHandler) {
949
- process.removeListener("SIGINT", this.sigintHandler);
950
- this.sigintHandler = null;
951
- }
952
- showCursor();
953
- if (isTTY() && this.lastRenderedLines > 0) {
954
- process.stdout.write(`
955
- `);
956
- }
957
- }
958
- }
419
+ // src/utils/progress/summary.ts
959
420
  class Summary {
960
421
  items = [];
961
422
  title;
@@ -1078,58 +539,6 @@ class Summary {
1078
539
  function summary(options) {
1079
540
  return new Summary(options);
1080
541
  }
1081
-
1082
- // src/utils/filter-options.ts
1083
- import { mergeFilters, parseListFlag } from "@doccov/sdk";
1084
- import chalk3 from "chalk";
1085
- var parseVisibilityFlag = (value) => {
1086
- if (!value)
1087
- return;
1088
- const validTags = ["public", "beta", "alpha", "internal"];
1089
- const parsed = parseListFlag(value);
1090
- if (!parsed)
1091
- return;
1092
- const result = [];
1093
- for (const tag of parsed) {
1094
- const lower = tag.toLowerCase();
1095
- if (validTags.includes(lower)) {
1096
- result.push(lower);
1097
- }
1098
- }
1099
- return result.length > 0 ? result : undefined;
1100
- };
1101
- var formatList = (label, values) => `${label}: ${values.map((value) => chalk3.cyan(value)).join(", ")}`;
1102
- var mergeFilterOptions = (config, cliOptions) => {
1103
- const messages = [];
1104
- if (config?.include) {
1105
- messages.push(formatList("include filters from config", config.include));
1106
- }
1107
- if (config?.exclude) {
1108
- messages.push(formatList("exclude filters from config", config.exclude));
1109
- }
1110
- if (cliOptions.include) {
1111
- messages.push(formatList("apply include filters from CLI", cliOptions.include));
1112
- }
1113
- if (cliOptions.exclude) {
1114
- messages.push(formatList("apply exclude filters from CLI", cliOptions.exclude));
1115
- }
1116
- if (cliOptions.visibility) {
1117
- messages.push(formatList("apply visibility filter from CLI", cliOptions.visibility));
1118
- }
1119
- const resolved = mergeFilters(config, cliOptions);
1120
- if (!resolved.include && !resolved.exclude && !cliOptions.visibility) {
1121
- return { messages };
1122
- }
1123
- const source = resolved.source === "override" ? "cli" : resolved.source;
1124
- return {
1125
- include: resolved.include,
1126
- exclude: resolved.exclude,
1127
- visibility: cliOptions.visibility,
1128
- source,
1129
- messages
1130
- };
1131
- };
1132
-
1133
542
  // src/utils/validation.ts
1134
543
  function clampPercentage(value, fallback = 80) {
1135
544
  if (Number.isNaN(value))
@@ -1157,7 +566,7 @@ import {
1157
566
  previewForgottenExportFixes,
1158
567
  serializeJSDoc
1159
568
  } from "@doccov/sdk";
1160
- import chalk5 from "chalk";
569
+ import chalk4 from "chalk";
1161
570
 
1162
571
  // src/commands/check/utils.ts
1163
572
  import * as fs from "node:fs";
@@ -1231,13 +640,13 @@ async function handleFixes(openpkg, doccov, options, deps) {
1231
640
  }
1232
641
  const { fixable, nonFixable } = categorizeDrifts(allDrifts.map((d) => d.drift));
1233
642
  if (fixable.length === 0) {
1234
- log(chalk5.yellow(`Found ${nonFixable.length} drift issue(s), but none are auto-fixable.`));
643
+ log(chalk4.yellow(`Found ${nonFixable.length} drift issue(s), but none are auto-fixable.`));
1235
644
  return { fixedDriftKeys, editsApplied: 0, filesModified: 0, forgottenExportsFixed: 0 };
1236
645
  }
1237
646
  log("");
1238
- log(chalk5.bold(`Found ${fixable.length} fixable issue(s)`));
647
+ log(chalk4.bold(`Found ${fixable.length} fixable issue(s)`));
1239
648
  if (nonFixable.length > 0) {
1240
- log(chalk5.gray(`(${nonFixable.length} non-fixable issue(s) skipped)`));
649
+ log(chalk4.gray(`(${nonFixable.length} non-fixable issue(s) skipped)`));
1241
650
  }
1242
651
  log("");
1243
652
  const groupedDrifts = groupByExport(allDrifts.filter((d) => fixable.includes(d.drift)));
@@ -1270,20 +679,20 @@ async function handleFixes(openpkg, doccov, options, deps) {
1270
679
  const applyResult = await applyEdits(edits);
1271
680
  if (applyResult.errors.length > 0) {
1272
681
  for (const err of applyResult.errors) {
1273
- error(chalk5.red(` ${err.file}: ${err.error}`));
682
+ error(chalk4.red(` ${err.file}: ${err.error}`));
1274
683
  }
1275
684
  }
1276
685
  const totalFixes = Array.from(editsByFile.values()).reduce((sum, fileEdits) => sum + fileEdits.reduce((s, e) => s + e.fixes.length, 0), 0);
1277
686
  log("");
1278
- log(chalk5.green(`✓ Applied ${totalFixes} fix(es) to ${applyResult.filesModified} file(s)`));
687
+ log(chalk4.green(`✓ Applied ${totalFixes} fix(es) to ${applyResult.filesModified} file(s)`));
1279
688
  for (const [filePath, fileEdits] of editsByFile) {
1280
689
  const relativePath = path3.relative(targetDir, filePath);
1281
690
  const fixCount = fileEdits.reduce((s, e) => s + e.fixes.length, 0);
1282
- log(chalk5.dim(` ${relativePath} (${fixCount} fixes)`));
691
+ log(chalk4.dim(` ${relativePath} (${fixCount} fixes)`));
1283
692
  }
1284
693
  if (options.healthScore !== undefined) {
1285
694
  log("");
1286
- log(chalk5.cyan("Run doccov check again to see updated health score"));
695
+ log(chalk4.cyan("Run doccov check again to see updated health score"));
1287
696
  }
1288
697
  return {
1289
698
  fixedDriftKeys,
@@ -1310,7 +719,7 @@ async function handleForgottenExportFixes(doccov, options, deps) {
1310
719
  return { fixesApplied: 0, filesModified: 0 };
1311
720
  }
1312
721
  log("");
1313
- log(chalk5.bold(`Found ${fixes.length} forgotten export(s) to fix`));
722
+ log(chalk4.bold(`Found ${fixes.length} forgotten export(s) to fix`));
1314
723
  if (isPreview) {
1315
724
  displayForgottenExportPreview(fixes, targetDir, log);
1316
725
  return { fixesApplied: 0, filesModified: 0 };
@@ -1318,12 +727,12 @@ async function handleForgottenExportFixes(doccov, options, deps) {
1318
727
  const result = await applyForgottenExportFixes(fixes);
1319
728
  if (result.errors.length > 0) {
1320
729
  for (const err of result.errors) {
1321
- error(chalk5.red(` ${err.file}: ${err.error}`));
730
+ error(chalk4.red(` ${err.file}: ${err.error}`));
1322
731
  }
1323
732
  }
1324
733
  if (result.fixesApplied > 0) {
1325
734
  log("");
1326
- log(chalk5.green(`✓ Added ${result.fixesApplied} export(s) to ${result.filesModified} file(s)`));
735
+ log(chalk4.green(`✓ Added ${result.fixesApplied} export(s) to ${result.filesModified} file(s)`));
1327
736
  const grouped = new Map;
1328
737
  for (const fix of fixes) {
1329
738
  const relativePath = path3.relative(targetDir, fix.targetFile);
@@ -1332,45 +741,45 @@ async function handleForgottenExportFixes(doccov, options, deps) {
1332
741
  grouped.set(relativePath, types);
1333
742
  }
1334
743
  for (const [file, types] of grouped) {
1335
- log(chalk5.dim(` ${file}: ${types.join(", ")}`));
744
+ log(chalk4.dim(` ${file}: ${types.join(", ")}`));
1336
745
  }
1337
746
  }
1338
747
  return { fixesApplied: result.fixesApplied, filesModified: result.filesModified };
1339
748
  }
1340
749
  function displayForgottenExportPreview(fixes, targetDir, log) {
1341
- log(chalk5.bold("Preview - forgotten exports that would be added:"));
750
+ log(chalk4.bold("Preview - forgotten exports that would be added:"));
1342
751
  log("");
1343
752
  const previews = previewForgottenExportFixes(fixes);
1344
753
  for (const [filePath, preview] of previews) {
1345
754
  const relativePath = path3.relative(targetDir, filePath);
1346
- log(chalk5.cyan(`${relativePath}:${preview.insertLine + 1}`));
755
+ log(chalk4.cyan(`${relativePath}:${preview.insertLine + 1}`));
1347
756
  log("");
1348
757
  for (const stmt of preview.statements) {
1349
- log(chalk5.green(` + ${stmt}`));
758
+ log(chalk4.green(` + ${stmt}`));
1350
759
  }
1351
760
  log("");
1352
761
  }
1353
- log(chalk5.yellow(`${fixes.length} export(s) would be added.`));
1354
- log(chalk5.gray("Run with --fix to apply these changes."));
762
+ log(chalk4.yellow(`${fixes.length} export(s) would be added.`));
763
+ log(chalk4.gray("Run with --fix to apply these changes."));
1355
764
  }
1356
765
  function generateEditForExport(exp, drifts, targetDir, log) {
1357
766
  if (!exp.source?.file) {
1358
- log(chalk5.gray(` Skipping ${exp.name}: no source location`));
767
+ log(chalk4.gray(` Skipping ${exp.name}: no source location`));
1359
768
  return null;
1360
769
  }
1361
770
  if (exp.source.file.endsWith(".d.ts")) {
1362
- log(chalk5.gray(` Skipping ${exp.name}: declaration file`));
771
+ log(chalk4.gray(` Skipping ${exp.name}: declaration file`));
1363
772
  return null;
1364
773
  }
1365
774
  const filePath = path3.resolve(targetDir, exp.source.file);
1366
775
  if (!fs2.existsSync(filePath)) {
1367
- log(chalk5.gray(` Skipping ${exp.name}: file not found`));
776
+ log(chalk4.gray(` Skipping ${exp.name}: file not found`));
1368
777
  return null;
1369
778
  }
1370
779
  const sourceFile = createSourceFile(filePath);
1371
780
  const location = findJSDocLocation(sourceFile, exp.name, exp.source.line);
1372
781
  if (!location) {
1373
- log(chalk5.gray(` Skipping ${exp.name}: could not find declaration`));
782
+ log(chalk4.gray(` Skipping ${exp.name}: could not find declaration`));
1374
783
  return null;
1375
784
  }
1376
785
  let existingPatch = {};
@@ -1395,13 +804,13 @@ function generateEditForExport(exp, drifts, targetDir, log) {
1395
804
  return { filePath, edit, fixes, existingPatch };
1396
805
  }
1397
806
  function displayPreview(editsByFile, targetDir, log) {
1398
- log(chalk5.bold("Preview - changes that would be made:"));
807
+ log(chalk4.bold("Preview - changes that would be made:"));
1399
808
  log("");
1400
809
  for (const [filePath, fileEdits] of editsByFile) {
1401
810
  const relativePath = path3.relative(targetDir, filePath);
1402
811
  for (const { export: exp, edit, fixes } of fileEdits) {
1403
- log(chalk5.cyan(`${relativePath}:${edit.startLine + 1}`));
1404
- log(chalk5.bold(` ${exp.name}`));
812
+ log(chalk4.cyan(`${relativePath}:${edit.startLine + 1}`));
813
+ log(chalk4.bold(` ${exp.name}`));
1405
814
  log("");
1406
815
  if (edit.hasExisting && edit.existingJSDoc) {
1407
816
  const oldLines = edit.existingJSDoc.split(`
@@ -1409,26 +818,26 @@ function displayPreview(editsByFile, targetDir, log) {
1409
818
  const newLines = edit.newJSDoc.split(`
1410
819
  `);
1411
820
  for (const line of oldLines) {
1412
- log(chalk5.red(` - ${line}`));
821
+ log(chalk4.red(` - ${line}`));
1413
822
  }
1414
823
  for (const line of newLines) {
1415
- log(chalk5.green(` + ${line}`));
824
+ log(chalk4.green(` + ${line}`));
1416
825
  }
1417
826
  } else {
1418
827
  const newLines = edit.newJSDoc.split(`
1419
828
  `);
1420
829
  for (const line of newLines) {
1421
- log(chalk5.green(` + ${line}`));
830
+ log(chalk4.green(` + ${line}`));
1422
831
  }
1423
832
  }
1424
833
  log("");
1425
- log(chalk5.dim(` Fixes: ${fixes.map((f) => f.description).join(", ")}`));
834
+ log(chalk4.dim(` Fixes: ${fixes.map((f) => f.description).join(", ")}`));
1426
835
  log("");
1427
836
  }
1428
837
  }
1429
838
  const totalFixes = Array.from(editsByFile.values()).reduce((sum, fileEdits) => sum + fileEdits.reduce((s, e) => s + e.fixes.length, 0), 0);
1430
- log(chalk5.yellow(`${totalFixes} fix(es) across ${editsByFile.size} file(s) would be applied.`));
1431
- log(chalk5.gray("Run with --fix to apply these changes."));
839
+ log(chalk4.yellow(`${totalFixes} fix(es) across ${editsByFile.size} file(s) would be applied.`));
840
+ log(chalk4.gray("Run with --fix to apply these changes."));
1432
841
  }
1433
842
 
1434
843
  // src/commands/check/output.ts
@@ -1885,7 +1294,7 @@ function computeStats(openpkg, doccov) {
1885
1294
  import * as fs3 from "node:fs";
1886
1295
  import * as path5 from "node:path";
1887
1296
  import { DEFAULT_REPORT_DIR, getReportPath } from "@doccov/sdk";
1888
- import chalk6 from "chalk";
1297
+ import chalk5 from "chalk";
1889
1298
  function writeReport(options) {
1890
1299
  const { format, content, outputPath, cwd = process.cwd(), silent = false } = options;
1891
1300
  const reportPath = outputPath ? path5.resolve(cwd, outputPath) : path5.resolve(cwd, getReportPath(format));
@@ -1896,7 +1305,7 @@ function writeReport(options) {
1896
1305
  fs3.writeFileSync(reportPath, content);
1897
1306
  const relativePath = path5.relative(cwd, reportPath);
1898
1307
  if (!silent) {
1899
- console.log(chalk6.green(`✓ Wrote ${format} report to ${relativePath}`));
1308
+ console.log(chalk5.green(`✓ Wrote ${format} report to ${relativePath}`));
1900
1309
  }
1901
1310
  return { path: reportPath, format, relativePath };
1902
1311
  }
@@ -2356,7 +1765,7 @@ function registerCheckCommand(program, dependencies = {}) {
2356
1765
  };
2357
1766
  const resolvedFilters = mergeFilterOptions(config, cliFilters);
2358
1767
  if (resolvedFilters.visibility) {
2359
- log(chalk7.dim(`Filtering by visibility: ${resolvedFilters.visibility.join(", ")}`));
1768
+ log(chalk6.dim(`Filtering by visibility: ${resolvedFilters.visibility.join(", ")}`));
2360
1769
  }
2361
1770
  const resolveExternalTypes = !options.skipResolve;
2362
1771
  const analyzer = createDocCov({
@@ -2461,7 +1870,7 @@ function registerCheckCommand(program, dependencies = {}) {
2461
1870
  process.exit(1);
2462
1871
  }
2463
1872
  } catch (commandError) {
2464
- error(chalk7.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
1873
+ error(chalk6.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
2465
1874
  process.exit(1);
2466
1875
  }
2467
1876
  });
@@ -2479,7 +1888,7 @@ import {
2479
1888
  parseMarkdownFiles as parseMarkdownFiles2
2480
1889
  } from "@doccov/sdk";
2481
1890
  import { calculateNextVersion, recommendSemverBump } from "@openpkg-ts/spec";
2482
- import chalk8 from "chalk";
1891
+ import chalk7 from "chalk";
2483
1892
  import { glob as glob2 } from "glob";
2484
1893
  var defaultDependencies2 = {
2485
1894
  readFileSync: fs4.readFileSync,
@@ -2554,9 +1963,9 @@ function registerDiffCommand(program, dependencies = {}) {
2554
1963
  }, null, 2));
2555
1964
  } else {
2556
1965
  log("");
2557
- log(chalk8.bold("Semver Recommendation"));
1966
+ log(chalk7.bold("Semver Recommendation"));
2558
1967
  log(` Current version: ${currentVersion}`);
2559
- log(` Recommended: ${chalk8.cyan(nextVersion)} (${chalk8.yellow(recommendation.bump.toUpperCase())})`);
1968
+ log(` Recommended: ${chalk7.cyan(nextVersion)} (${chalk7.yellow(recommendation.bump.toUpperCase())})`);
2560
1969
  log(` Reason: ${recommendation.reason}`);
2561
1970
  }
2562
1971
  return;
@@ -2586,8 +1995,8 @@ function registerDiffCommand(program, dependencies = {}) {
2586
1995
  silent: true
2587
1996
  });
2588
1997
  }
2589
- const cacheNote = fromCache ? chalk8.cyan(" (cached)") : "";
2590
- log(chalk8.dim(`Report: ${jsonPath}`) + cacheNote);
1998
+ const cacheNote = fromCache ? chalk7.cyan(" (cached)") : "";
1999
+ log(chalk7.dim(`Report: ${jsonPath}`) + cacheNote);
2591
2000
  }
2592
2001
  break;
2593
2002
  case "json": {
@@ -2645,18 +2054,18 @@ function registerDiffCommand(program, dependencies = {}) {
2645
2054
  checks
2646
2055
  });
2647
2056
  if (failures.length > 0) {
2648
- log(chalk8.red(`
2057
+ log(chalk7.red(`
2649
2058
  ✗ Check failed`));
2650
2059
  for (const f of failures) {
2651
- log(chalk8.red(` - ${f}`));
2060
+ log(chalk7.red(` - ${f}`));
2652
2061
  }
2653
2062
  process.exitCode = 1;
2654
2063
  } else if (options.strict || minCoverage !== undefined || maxDrift !== undefined) {
2655
- log(chalk8.green(`
2064
+ log(chalk7.green(`
2656
2065
  ✓ All checks passed`));
2657
2066
  }
2658
2067
  } catch (commandError) {
2659
- error(chalk8.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
2068
+ error(chalk7.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
2660
2069
  process.exitCode = 1;
2661
2070
  }
2662
2071
  });
@@ -2683,7 +2092,7 @@ async function generateDiff(baseSpec, headSpec, options, config, log) {
2683
2092
  if (!docsPatterns || docsPatterns.length === 0) {
2684
2093
  if (config?.docs?.include) {
2685
2094
  docsPatterns = config.docs.include;
2686
- log(chalk8.gray(`Using docs patterns from config: ${docsPatterns.join(", ")}`));
2095
+ log(chalk7.gray(`Using docs patterns from config: ${docsPatterns.join(", ")}`));
2687
2096
  }
2688
2097
  }
2689
2098
  if (docsPatterns && docsPatterns.length > 0) {
@@ -2706,37 +2115,37 @@ function loadSpec(filePath, readFileSync3) {
2706
2115
  }
2707
2116
  function printSummary(diff, baseName, headName, fromCache, log) {
2708
2117
  log("");
2709
- const cacheIndicator = fromCache ? chalk8.cyan(" (cached)") : "";
2710
- log(chalk8.bold(`Comparing: ${baseName} → ${headName}`) + cacheIndicator);
2118
+ const cacheIndicator = fromCache ? chalk7.cyan(" (cached)") : "";
2119
+ log(chalk7.bold(`Comparing: ${baseName} → ${headName}`) + cacheIndicator);
2711
2120
  log("─".repeat(40));
2712
2121
  log("");
2713
- const coverageColor = diff.coverageDelta > 0 ? chalk8.green : diff.coverageDelta < 0 ? chalk8.red : chalk8.gray;
2122
+ const coverageColor = diff.coverageDelta > 0 ? chalk7.green : diff.coverageDelta < 0 ? chalk7.red : chalk7.gray;
2714
2123
  const coverageSign = diff.coverageDelta > 0 ? "+" : "";
2715
2124
  log(` Coverage: ${diff.oldCoverage}% → ${diff.newCoverage}% ${coverageColor(`(${coverageSign}${diff.coverageDelta}%)`)}`);
2716
2125
  const breakingCount = diff.breaking.length;
2717
2126
  const highSeverity = diff.categorizedBreaking?.filter((c) => c.severity === "high").length ?? 0;
2718
2127
  if (breakingCount > 0) {
2719
- const severityNote = highSeverity > 0 ? chalk8.red(` (${highSeverity} high severity)`) : "";
2720
- log(` Breaking: ${chalk8.red(breakingCount)} changes${severityNote}`);
2128
+ const severityNote = highSeverity > 0 ? chalk7.red(` (${highSeverity} high severity)`) : "";
2129
+ log(` Breaking: ${chalk7.red(breakingCount)} changes${severityNote}`);
2721
2130
  } else {
2722
- log(` Breaking: ${chalk8.green("0")} changes`);
2131
+ log(` Breaking: ${chalk7.green("0")} changes`);
2723
2132
  }
2724
2133
  const newCount = diff.nonBreaking.length;
2725
2134
  const undocCount = diff.newUndocumented.length;
2726
2135
  if (newCount > 0) {
2727
- const undocNote = undocCount > 0 ? chalk8.yellow(` (${undocCount} undocumented)`) : "";
2728
- log(` New: ${chalk8.green(newCount)} exports${undocNote}`);
2136
+ const undocNote = undocCount > 0 ? chalk7.yellow(` (${undocCount} undocumented)`) : "";
2137
+ log(` New: ${chalk7.green(newCount)} exports${undocNote}`);
2729
2138
  }
2730
2139
  if (diff.driftIntroduced > 0 || diff.driftResolved > 0) {
2731
2140
  const parts = [];
2732
2141
  if (diff.driftIntroduced > 0)
2733
- parts.push(chalk8.red(`+${diff.driftIntroduced}`));
2142
+ parts.push(chalk7.red(`+${diff.driftIntroduced}`));
2734
2143
  if (diff.driftResolved > 0)
2735
- parts.push(chalk8.green(`-${diff.driftResolved}`));
2144
+ parts.push(chalk7.green(`-${diff.driftResolved}`));
2736
2145
  log(` Drift: ${parts.join(", ")}`);
2737
2146
  }
2738
2147
  const recommendation = recommendSemverBump(diff);
2739
- const bumpColor = recommendation.bump === "major" ? chalk8.red : recommendation.bump === "minor" ? chalk8.yellow : chalk8.green;
2148
+ const bumpColor = recommendation.bump === "major" ? chalk7.red : recommendation.bump === "minor" ? chalk7.yellow : chalk7.green;
2740
2149
  log(` Semver: ${bumpColor(recommendation.bump.toUpperCase())} (${recommendation.reason})`);
2741
2150
  log("");
2742
2151
  }
@@ -2819,7 +2228,7 @@ function printGitHubAnnotations(diff, log) {
2819
2228
  // src/commands/init.ts
2820
2229
  import * as fs5 from "node:fs";
2821
2230
  import * as path7 from "node:path";
2822
- import chalk9 from "chalk";
2231
+ import chalk8 from "chalk";
2823
2232
  var defaultDependencies3 = {
2824
2233
  fileExists: fs5.existsSync,
2825
2234
  writeFileSync: fs5.writeFileSync,
@@ -2837,7 +2246,7 @@ function registerInitCommand(program, dependencies = {}) {
2837
2246
  const cwd = path7.resolve(options.cwd);
2838
2247
  const existing = findExistingConfig(cwd, fileExists2);
2839
2248
  if (existing) {
2840
- error(chalk9.red(`A DocCov config already exists at ${path7.relative(cwd, existing) || "./doccov.config.*"}.`));
2249
+ error(chalk8.red(`A DocCov config already exists at ${path7.relative(cwd, existing) || "./doccov.config.*"}.`));
2841
2250
  process.exitCode = 1;
2842
2251
  return;
2843
2252
  }
@@ -2846,7 +2255,7 @@ function registerInitCommand(program, dependencies = {}) {
2846
2255
  const fileName = `doccov.config.${targetFormat}`;
2847
2256
  const outputPath = path7.join(cwd, fileName);
2848
2257
  if (fileExists2(outputPath)) {
2849
- error(chalk9.red(`Cannot create ${fileName}; file already exists.`));
2258
+ error(chalk8.red(`Cannot create ${fileName}; file already exists.`));
2850
2259
  process.exitCode = 1;
2851
2260
  return;
2852
2261
  }
@@ -2867,16 +2276,16 @@ function registerInitCommand(program, dependencies = {}) {
2867
2276
  }
2868
2277
  const repoInfo = detectRepoInfo(cwd, fileExists2, readFileSync4);
2869
2278
  log("");
2870
- log(chalk9.bold("Add this badge to your README:"));
2279
+ log(chalk8.bold("Add this badge to your README:"));
2871
2280
  log("");
2872
2281
  if (repoInfo) {
2873
- log(chalk9.cyan(`[![DocCov](https://doccov.dev/badge/${repoInfo.owner}/${repoInfo.repo})](https://doccov.dev/${repoInfo.owner}/${repoInfo.repo})`));
2282
+ log(chalk8.cyan(`[![DocCov](https://doccov.dev/badge/${repoInfo.owner}/${repoInfo.repo})](https://doccov.dev/${repoInfo.owner}/${repoInfo.repo})`));
2874
2283
  } else {
2875
- log(chalk9.cyan(`[![DocCov](https://doccov.dev/badge/OWNER/REPO)](https://doccov.dev/OWNER/REPO)`));
2876
- log(chalk9.dim(" Replace OWNER/REPO with your GitHub repo"));
2284
+ log(chalk8.cyan(`[![DocCov](https://doccov.dev/badge/OWNER/REPO)](https://doccov.dev/OWNER/REPO)`));
2285
+ log(chalk8.dim(" Replace OWNER/REPO with your GitHub repo"));
2877
2286
  }
2878
2287
  log("");
2879
- log(chalk9.dim("Run `doccov check` to verify your documentation coverage"));
2288
+ log(chalk8.dim("Run `doccov check` to verify your documentation coverage"));
2880
2289
  });
2881
2290
  }
2882
2291
  var findExistingConfig = (cwd, fileExists2) => {
@@ -3015,7 +2424,7 @@ import {
3015
2424
  normalize,
3016
2425
  validateSpec
3017
2426
  } from "@openpkg-ts/spec";
3018
- import chalk10 from "chalk";
2427
+ import chalk9 from "chalk";
3019
2428
  var defaultDependencies4 = {
3020
2429
  createDocCov: (options) => new DocCov2(options),
3021
2430
  writeFileSync: fs6.writeFileSync,
@@ -3028,7 +2437,7 @@ function getArrayLength(value) {
3028
2437
  function formatDiagnosticOutput(prefix2, diagnostic, baseDir) {
3029
2438
  const location = diagnostic.location;
3030
2439
  const relativePath = location?.file ? path8.relative(baseDir, location.file) || location.file : undefined;
3031
- const locationText = location && relativePath ? chalk10.gray(`${relativePath}:${location.line ?? 1}:${location.column ?? 1}`) : null;
2440
+ const locationText = location && relativePath ? chalk9.gray(`${relativePath}:${location.line ?? 1}:${location.column ?? 1}`) : null;
3032
2441
  const locationPrefix = locationText ? `${locationText} ` : "";
3033
2442
  return `${prefix2} ${locationPrefix}${diagnostic.message}`;
3034
2443
  }
@@ -3052,7 +2461,7 @@ function registerSpecCommand(program, dependencies = {}) {
3052
2461
  config = await loadDocCovConfig(targetDir);
3053
2462
  } catch (configError) {
3054
2463
  spin.fail("Failed to load config");
3055
- error(chalk10.red("Failed to load DocCov config:"), configError instanceof Error ? configError.message : configError);
2464
+ error(chalk9.red("Failed to load DocCov config:"), configError instanceof Error ? configError.message : configError);
3056
2465
  process.exit(1);
3057
2466
  }
3058
2467
  const cliFilters = {
@@ -3085,9 +2494,9 @@ function registerSpecCommand(program, dependencies = {}) {
3085
2494
  const validation = validateSpec(normalized);
3086
2495
  if (!validation.ok) {
3087
2496
  spin.fail("Validation failed");
3088
- error(chalk10.red("Spec failed schema validation"));
2497
+ error(chalk9.red("Spec failed schema validation"));
3089
2498
  for (const err of validation.errors) {
3090
- error(chalk10.red(`schema: ${err.instancePath || "/"} ${err.message}`));
2499
+ error(chalk9.red(`schema: ${err.instancePath || "/"} ${err.message}`));
3091
2500
  }
3092
2501
  process.exit(1);
3093
2502
  }
@@ -3102,9 +2511,9 @@ function registerSpecCommand(program, dependencies = {}) {
3102
2511
  const doccovValidation = validateDocCovSpec(doccovSpec);
3103
2512
  if (!doccovValidation.ok) {
3104
2513
  spin.fail("DocCov validation failed");
3105
- error(chalk10.red("DocCov spec failed schema validation"));
2514
+ error(chalk9.red("DocCov spec failed schema validation"));
3106
2515
  for (const err of doccovValidation.errors) {
3107
- error(chalk10.red(`doccov: ${err.instancePath || "/"} ${err.message}`));
2516
+ error(chalk9.red(`doccov: ${err.instancePath || "/"} ${err.message}`));
3108
2517
  }
3109
2518
  process.exit(1);
3110
2519
  }
@@ -3124,12 +2533,12 @@ function registerSpecCommand(program, dependencies = {}) {
3124
2533
  const doccovPath = path8.join(outputDir, "doccov.json");
3125
2534
  writeFileSync4(doccovPath, JSON.stringify(doccovSpec, null, 2));
3126
2535
  spin.success(`Generated ${options.output}/`);
3127
- log(chalk10.gray(` openpkg.json: ${getArrayLength(normalized.exports)} exports`));
3128
- log(chalk10.gray(` doccov.json: ${doccovSpec.summary.score}% coverage, ${doccovSpec.summary.drift.total} drift issues`));
2536
+ log(chalk9.gray(` openpkg.json: ${getArrayLength(normalized.exports)} exports`));
2537
+ log(chalk9.gray(` doccov.json: ${doccovSpec.summary.score}% coverage, ${doccovSpec.summary.drift.total} drift issues`));
3129
2538
  } else {
3130
2539
  spin.success(`Generated ${options.output}/openpkg.json`);
3131
- log(chalk10.gray(` ${getArrayLength(normalized.exports)} exports`));
3132
- log(chalk10.gray(` ${getArrayLength(normalized.types)} types`));
2540
+ log(chalk9.gray(` ${getArrayLength(normalized.exports)} exports`));
2541
+ log(chalk9.gray(` ${getArrayLength(normalized.types)} types`));
3133
2542
  }
3134
2543
  }
3135
2544
  const isFullGenerationInfo = (gen) => {
@@ -3141,62 +2550,62 @@ function registerSpecCommand(program, dependencies = {}) {
3141
2550
  const pm = await detectPackageManager(fileSystem);
3142
2551
  const buildCmd = pm.name === "npm" ? "npm run build" : `${pm.name} run build`;
3143
2552
  log("");
3144
- log(chalk10.yellow("⚠ Runtime extraction requested but no schemas extracted."));
3145
- log(chalk10.yellow(` Ensure project is built (${buildCmd}) and dist/ exists.`));
2553
+ log(chalk9.yellow("⚠ Runtime extraction requested but no schemas extracted."));
2554
+ log(chalk9.yellow(` Ensure project is built (${buildCmd}) and dist/ exists.`));
3146
2555
  }
3147
2556
  if (options.verbose && fullGen) {
3148
2557
  log("");
3149
- log(chalk10.bold("Generation Info"));
3150
- log(chalk10.gray(` Timestamp: ${fullGen.timestamp}`));
3151
- log(chalk10.gray(` Generator: ${fullGen.generator.name}@${fullGen.generator.version}`));
3152
- log(chalk10.gray(` Entry point: ${fullGen.analysis.entryPoint}`));
3153
- log(chalk10.gray(` Detected via: ${fullGen.analysis.entryPointSource}`));
3154
- log(chalk10.gray(` Declaration only: ${fullGen.analysis.isDeclarationOnly ? "yes" : "no"}`));
3155
- log(chalk10.gray(` External types: ${fullGen.analysis.resolvedExternalTypes ? "resolved" : "skipped"}`));
2558
+ log(chalk9.bold("Generation Info"));
2559
+ log(chalk9.gray(` Timestamp: ${fullGen.timestamp}`));
2560
+ log(chalk9.gray(` Generator: ${fullGen.generator.name}@${fullGen.generator.version}`));
2561
+ log(chalk9.gray(` Entry point: ${fullGen.analysis.entryPoint}`));
2562
+ log(chalk9.gray(` Detected via: ${fullGen.analysis.entryPointSource}`));
2563
+ log(chalk9.gray(` Declaration only: ${fullGen.analysis.isDeclarationOnly ? "yes" : "no"}`));
2564
+ log(chalk9.gray(` External types: ${fullGen.analysis.resolvedExternalTypes ? "resolved" : "skipped"}`));
3156
2565
  if (fullGen.analysis.maxTypeDepth) {
3157
- log(chalk10.gray(` Max type depth: ${fullGen.analysis.maxTypeDepth}`));
2566
+ log(chalk9.gray(` Max type depth: ${fullGen.analysis.maxTypeDepth}`));
3158
2567
  }
3159
2568
  if (fullGen.analysis.schemaExtraction) {
3160
2569
  const se = fullGen.analysis.schemaExtraction;
3161
- log(chalk10.gray(` Schema extraction: ${se.method}`));
2570
+ log(chalk9.gray(` Schema extraction: ${se.method}`));
3162
2571
  if (se.runtimeCount) {
3163
- log(chalk10.gray(` Runtime schemas: ${se.runtimeCount} (${se.vendors?.join(", ")})`));
2572
+ log(chalk9.gray(` Runtime schemas: ${se.runtimeCount} (${se.vendors?.join(", ")})`));
3164
2573
  }
3165
2574
  }
3166
2575
  log("");
3167
- log(chalk10.bold("Environment"));
3168
- log(chalk10.gray(` node_modules: ${fullGen.environment.hasNodeModules ? "found" : "not found"}`));
2576
+ log(chalk9.bold("Environment"));
2577
+ log(chalk9.gray(` node_modules: ${fullGen.environment.hasNodeModules ? "found" : "not found"}`));
3169
2578
  if (fullGen.environment.packageManager) {
3170
- log(chalk10.gray(` Package manager: ${fullGen.environment.packageManager}`));
2579
+ log(chalk9.gray(` Package manager: ${fullGen.environment.packageManager}`));
3171
2580
  }
3172
2581
  if (fullGen.environment.isMonorepo) {
3173
- log(chalk10.gray(` Monorepo: yes`));
2582
+ log(chalk9.gray(` Monorepo: yes`));
3174
2583
  }
3175
2584
  if (fullGen.environment.targetPackage) {
3176
- log(chalk10.gray(` Target package: ${fullGen.environment.targetPackage}`));
2585
+ log(chalk9.gray(` Target package: ${fullGen.environment.targetPackage}`));
3177
2586
  }
3178
2587
  if (fullGen.issues.length > 0) {
3179
2588
  log("");
3180
- log(chalk10.bold("Issues"));
2589
+ log(chalk9.bold("Issues"));
3181
2590
  for (const issue of fullGen.issues) {
3182
- const prefix2 = issue.severity === "error" ? chalk10.red(">") : issue.severity === "warning" ? chalk10.yellow(">") : chalk10.cyan(">");
2591
+ const prefix2 = issue.severity === "error" ? chalk9.red(">") : issue.severity === "warning" ? chalk9.yellow(">") : chalk9.cyan(">");
3183
2592
  log(`${prefix2} [${issue.code}] ${issue.message}`);
3184
2593
  if (issue.suggestion) {
3185
- log(chalk10.gray(` ${issue.suggestion}`));
2594
+ log(chalk9.gray(` ${issue.suggestion}`));
3186
2595
  }
3187
2596
  }
3188
2597
  }
3189
2598
  }
3190
2599
  if (options.showDiagnostics && result.diagnostics.length > 0) {
3191
2600
  log("");
3192
- log(chalk10.bold("Diagnostics"));
2601
+ log(chalk9.bold("Diagnostics"));
3193
2602
  for (const diagnostic of result.diagnostics) {
3194
- const prefix2 = diagnostic.severity === "error" ? chalk10.red(">") : diagnostic.severity === "warning" ? chalk10.yellow(">") : chalk10.cyan(">");
2603
+ const prefix2 = diagnostic.severity === "error" ? chalk9.red(">") : diagnostic.severity === "warning" ? chalk9.yellow(">") : chalk9.cyan(">");
3195
2604
  log(formatDiagnosticOutput(prefix2, diagnostic, targetDir));
3196
2605
  }
3197
2606
  }
3198
2607
  } catch (commandError) {
3199
- error(chalk10.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
2608
+ error(chalk9.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
3200
2609
  process.exit(1);
3201
2610
  }
3202
2611
  });
@@ -3214,7 +2623,7 @@ import {
3214
2623
  renderSparkline,
3215
2624
  saveSnapshot
3216
2625
  } from "@doccov/sdk";
3217
- import chalk11 from "chalk";
2626
+ import chalk10 from "chalk";
3218
2627
  function formatDate(timestamp) {
3219
2628
  const date = new Date(timestamp);
3220
2629
  return date.toLocaleDateString("en-US", {
@@ -3227,19 +2636,19 @@ function formatDate(timestamp) {
3227
2636
  }
3228
2637
  function getColorForScore(score) {
3229
2638
  if (score >= 90)
3230
- return chalk11.green;
2639
+ return chalk10.green;
3231
2640
  if (score >= 70)
3232
- return chalk11.yellow;
2641
+ return chalk10.yellow;
3233
2642
  if (score >= 50)
3234
- return chalk11.hex("#FFA500");
3235
- return chalk11.red;
2643
+ return chalk10.hex("#FFA500");
2644
+ return chalk10.red;
3236
2645
  }
3237
2646
  function formatSnapshot(snapshot) {
3238
2647
  const color = getColorForScore(snapshot.coverageScore);
3239
2648
  const date = formatDate(snapshot.timestamp);
3240
2649
  const version = snapshot.version ? ` v${snapshot.version}` : "";
3241
- const commit = snapshot.commit ? chalk11.gray(` (${snapshot.commit.slice(0, 7)})`) : "";
3242
- return `${chalk11.gray(date)} ${color(`${snapshot.coverageScore}%`)} ${snapshot.documentedExports}/${snapshot.totalExports} exports${version}${commit}`;
2650
+ const commit = snapshot.commit ? chalk10.gray(` (${snapshot.commit.slice(0, 7)})`) : "";
2651
+ return `${chalk10.gray(date)} ${color(`${snapshot.coverageScore}%`)} ${snapshot.documentedExports}/${snapshot.totalExports} exports${version}${commit}`;
3243
2652
  }
3244
2653
  function formatWeekDate(timestamp) {
3245
2654
  const date = new Date(timestamp);
@@ -3247,10 +2656,10 @@ function formatWeekDate(timestamp) {
3247
2656
  }
3248
2657
  function formatVelocity(velocity) {
3249
2658
  if (velocity > 0)
3250
- return chalk11.green(`+${velocity}%/day`);
2659
+ return chalk10.green(`+${velocity}%/day`);
3251
2660
  if (velocity < 0)
3252
- return chalk11.red(`${velocity}%/day`);
3253
- return chalk11.gray("0%/day");
2661
+ return chalk10.red(`${velocity}%/day`);
2662
+ return chalk10.gray("0%/day");
3254
2663
  }
3255
2664
  function registerTrendsCommand(program) {
3256
2665
  program.command("trends").description("Show coverage trends over time").option("--cwd <dir>", "Working directory", process.cwd()).option("-n, --limit <count>", "Number of snapshots to show", "10").option("--prune <count>", "Prune history to keep only N snapshots").option("--record", "Record current coverage to history").option("--json", "Output as JSON").option("--extended", "Show extended trend analysis (velocity, projections)").option("--weekly", "Show weekly summary breakdown").action(async (options) => {
@@ -3259,14 +2668,14 @@ function registerTrendsCommand(program) {
3259
2668
  const keepCount = parseInt(options.prune, 10);
3260
2669
  if (!Number.isNaN(keepCount)) {
3261
2670
  const deleted = pruneHistory(cwd, keepCount);
3262
- console.log(chalk11.green(`Pruned ${deleted} old snapshots, kept ${keepCount} most recent`));
2671
+ console.log(chalk10.green(`Pruned ${deleted} old snapshots, kept ${keepCount} most recent`));
3263
2672
  }
3264
2673
  return;
3265
2674
  }
3266
2675
  if (options.record) {
3267
2676
  const specPath = path9.resolve(cwd, "openpkg.json");
3268
2677
  if (!fs7.existsSync(specPath)) {
3269
- console.error(chalk11.red("No openpkg.json found. Run `doccov spec` first to generate a spec."));
2678
+ console.error(chalk10.red("No openpkg.json found. Run `doccov spec` first to generate a spec."));
3270
2679
  process.exit(1);
3271
2680
  }
3272
2681
  const spin = spinner("Recording coverage snapshot");
@@ -3279,21 +2688,21 @@ function registerTrendsCommand(program) {
3279
2688
  console.log(formatSnapshot(trend.current));
3280
2689
  if (trend.delta !== undefined) {
3281
2690
  const deltaStr = formatDelta2(trend.delta);
3282
- const deltaColor = trend.delta > 0 ? chalk11.green : trend.delta < 0 ? chalk11.red : chalk11.gray;
3283
- console.log(chalk11.gray("Change from previous:"), deltaColor(deltaStr));
2691
+ const deltaColor = trend.delta > 0 ? chalk10.green : trend.delta < 0 ? chalk10.red : chalk10.gray;
2692
+ console.log(chalk10.gray("Change from previous:"), deltaColor(deltaStr));
3284
2693
  }
3285
2694
  return;
3286
2695
  } catch (error) {
3287
2696
  spin.fail("Failed to record snapshot");
3288
- console.error(chalk11.red("Failed to read openpkg.json:"), error instanceof Error ? error.message : error);
2697
+ console.error(chalk10.red("Failed to read openpkg.json:"), error instanceof Error ? error.message : error);
3289
2698
  process.exit(1);
3290
2699
  }
3291
2700
  }
3292
2701
  const snapshots = loadSnapshots(cwd);
3293
2702
  const limit = parseInt(options.limit ?? "10", 10);
3294
2703
  if (snapshots.length === 0) {
3295
- console.log(chalk11.yellow("No coverage history found."));
3296
- console.log(chalk11.gray("Run `doccov trends --record` to save the current coverage."));
2704
+ console.log(chalk10.yellow("No coverage history found."));
2705
+ console.log(chalk10.gray("Run `doccov trends --record` to save the current coverage."));
3297
2706
  return;
3298
2707
  }
3299
2708
  if (options.json) {
@@ -3308,17 +2717,17 @@ function registerTrendsCommand(program) {
3308
2717
  }
3309
2718
  const sparklineData = snapshots.slice(0, 10).map((s) => s.coverageScore).reverse();
3310
2719
  const sparkline = renderSparkline(sparklineData);
3311
- console.log(chalk11.bold("Coverage Trends"));
3312
- console.log(chalk11.gray(`Package: ${snapshots[0].package}`));
3313
- console.log(chalk11.gray(`Sparkline: ${sparkline}`));
2720
+ console.log(chalk10.bold("Coverage Trends"));
2721
+ console.log(chalk10.gray(`Package: ${snapshots[0].package}`));
2722
+ console.log(chalk10.gray(`Sparkline: ${sparkline}`));
3314
2723
  console.log("");
3315
2724
  if (snapshots.length >= 2) {
3316
2725
  const oldest = snapshots[snapshots.length - 1];
3317
2726
  const newest = snapshots[0];
3318
2727
  const overallDelta = newest.coverageScore - oldest.coverageScore;
3319
2728
  const deltaStr = formatDelta2(overallDelta);
3320
- const deltaColor = overallDelta > 0 ? chalk11.green : overallDelta < 0 ? chalk11.red : chalk11.gray;
3321
- console.log(chalk11.gray("Overall trend:"), deltaColor(deltaStr), chalk11.gray(`(${snapshots.length} snapshots)`));
2729
+ const deltaColor = overallDelta > 0 ? chalk10.green : overallDelta < 0 ? chalk10.red : chalk10.gray;
2730
+ console.log(chalk10.gray("Overall trend:"), deltaColor(deltaStr), chalk10.gray(`(${snapshots.length} snapshots)`));
3322
2731
  console.log("");
3323
2732
  }
3324
2733
  if (options.extended) {
@@ -3328,55 +2737,55 @@ function registerTrendsCommand(program) {
3328
2737
  const specContent = fs7.readFileSync(specPath, "utf-8");
3329
2738
  const spec = JSON.parse(specContent);
3330
2739
  const extended = getExtendedTrend(spec, cwd);
3331
- console.log(chalk11.bold("Extended Analysis"));
3332
- console.log(chalk11.gray("90-day retention"));
2740
+ console.log(chalk10.bold("Extended Analysis"));
2741
+ console.log(chalk10.gray("90-day retention"));
3333
2742
  console.log("");
3334
2743
  console.log(" Velocity:");
3335
2744
  console.log(` 7-day: ${formatVelocity(extended.velocity7d)}`);
3336
2745
  console.log(` 30-day: ${formatVelocity(extended.velocity30d)}`);
3337
2746
  console.log(` 90-day: ${formatVelocity(extended.velocity90d)}`);
3338
2747
  console.log("");
3339
- const projColor = extended.projected30d >= extended.trend.current.coverageScore ? chalk11.green : chalk11.red;
2748
+ const projColor = extended.projected30d >= extended.trend.current.coverageScore ? chalk10.green : chalk10.red;
3340
2749
  console.log(` Projected (30d): ${projColor(`${extended.projected30d}%`)}`);
3341
- console.log(` All-time high: ${chalk11.green(`${extended.allTimeHigh}%`)}`);
3342
- console.log(` All-time low: ${chalk11.red(`${extended.allTimeLow}%`)}`);
2750
+ console.log(` All-time high: ${chalk10.green(`${extended.allTimeHigh}%`)}`);
2751
+ console.log(` All-time low: ${chalk10.red(`${extended.allTimeLow}%`)}`);
3343
2752
  if (extended.dataRange) {
3344
2753
  const startDate = formatWeekDate(extended.dataRange.start);
3345
2754
  const endDate = formatWeekDate(extended.dataRange.end);
3346
- console.log(chalk11.gray(` Data range: ${startDate} - ${endDate}`));
2755
+ console.log(chalk10.gray(` Data range: ${startDate} - ${endDate}`));
3347
2756
  }
3348
2757
  console.log("");
3349
2758
  if (options.weekly && extended.weeklySummaries.length > 0) {
3350
- console.log(chalk11.bold("Weekly Summary"));
2759
+ console.log(chalk10.bold("Weekly Summary"));
3351
2760
  const weekLimit = Math.min(extended.weeklySummaries.length, 8);
3352
2761
  for (let i = 0;i < weekLimit; i++) {
3353
2762
  const week = extended.weeklySummaries[i];
3354
2763
  const weekStart = formatWeekDate(week.weekStart);
3355
2764
  const weekEnd = formatWeekDate(week.weekEnd);
3356
- const deltaColor = week.delta > 0 ? chalk11.green : week.delta < 0 ? chalk11.red : chalk11.gray;
2765
+ const deltaColor = week.delta > 0 ? chalk10.green : week.delta < 0 ? chalk10.red : chalk10.gray;
3357
2766
  const deltaStr = week.delta > 0 ? `+${week.delta}%` : `${week.delta}%`;
3358
2767
  console.log(` ${weekStart} - ${weekEnd}: ${week.avgCoverage}% avg ${deltaColor(deltaStr)} (${week.snapshotCount} snapshots)`);
3359
2768
  }
3360
2769
  if (extended.weeklySummaries.length > weekLimit) {
3361
- console.log(chalk11.gray(` ... and ${extended.weeklySummaries.length - weekLimit} more weeks`));
2770
+ console.log(chalk10.gray(` ... and ${extended.weeklySummaries.length - weekLimit} more weeks`));
3362
2771
  }
3363
2772
  console.log("");
3364
2773
  }
3365
2774
  } catch {
3366
- console.log(chalk11.yellow("Could not load openpkg.json for extended analysis"));
2775
+ console.log(chalk10.yellow("Could not load openpkg.json for extended analysis"));
3367
2776
  console.log("");
3368
2777
  }
3369
2778
  }
3370
2779
  }
3371
- console.log(chalk11.bold("History"));
2780
+ console.log(chalk10.bold("History"));
3372
2781
  const displaySnapshots = snapshots.slice(0, limit);
3373
2782
  for (let i = 0;i < displaySnapshots.length; i++) {
3374
2783
  const snapshot = displaySnapshots[i];
3375
- const prefix2 = i === 0 ? chalk11.cyan("→") : " ";
2784
+ const prefix2 = i === 0 ? chalk10.cyan("→") : " ";
3376
2785
  console.log(`${prefix2} ${formatSnapshot(snapshot)}`);
3377
2786
  }
3378
2787
  if (snapshots.length > limit) {
3379
- console.log(chalk11.gray(` ... and ${snapshots.length - limit} more`));
2788
+ console.log(chalk10.gray(` ... and ${snapshots.length - limit} more`));
3380
2789
  }
3381
2790
  });
3382
2791
  }