@claude-flow/cli 3.6.30 → 3.7.0-alpha.3

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.
@@ -1,133 +1,9 @@
1
1
  /**
2
- * V3 CLI Output Formatter
3
- * Advanced output formatting with tables, progress bars, and colors
2
+ * V3 CLI Output Formatter — re-export shim (ADR-100, alpha.5).
3
+ *
4
+ * Authoritative source: @claude-flow/cli-core/output. Was a byte-identical
5
+ * 640-line copy. The OutputFormatter class and `output` instance plus all
6
+ * helper exports flow through unchanged. Edit cli-core for behavior changes.
4
7
  */
5
- import type { TableOptions, ProgressOptions, SpinnerOptions } from './types.js';
6
- declare const COLORS: {
7
- readonly reset: "\u001B[0m";
8
- readonly bold: "\u001B[1m";
9
- readonly dim: "\u001B[2m";
10
- readonly italic: "\u001B[3m";
11
- readonly underline: "\u001B[4m";
12
- readonly black: "\u001B[30m";
13
- readonly red: "\u001B[31m";
14
- readonly green: "\u001B[32m";
15
- readonly yellow: "\u001B[33m";
16
- readonly blue: "\u001B[34m";
17
- readonly magenta: "\u001B[35m";
18
- readonly cyan: "\u001B[36m";
19
- readonly white: "\u001B[37m";
20
- readonly gray: "\u001B[90m";
21
- readonly brightRed: "\u001B[91m";
22
- readonly brightGreen: "\u001B[92m";
23
- readonly brightYellow: "\u001B[93m";
24
- readonly brightBlue: "\u001B[94m";
25
- readonly brightMagenta: "\u001B[95m";
26
- readonly brightCyan: "\u001B[96m";
27
- readonly brightWhite: "\u001B[97m";
28
- readonly bgBlack: "\u001B[40m";
29
- readonly bgRed: "\u001B[41m";
30
- readonly bgGreen: "\u001B[42m";
31
- readonly bgYellow: "\u001B[43m";
32
- readonly bgBlue: "\u001B[44m";
33
- readonly bgMagenta: "\u001B[45m";
34
- readonly bgCyan: "\u001B[46m";
35
- readonly bgWhite: "\u001B[47m";
36
- };
37
- type ColorName = keyof typeof COLORS;
38
- export type VerbosityLevel = 'quiet' | 'normal' | 'verbose' | 'debug';
39
- export declare class OutputFormatter {
40
- private colorEnabled;
41
- private outputStream;
42
- private errorStream;
43
- private verbosity;
44
- constructor(options?: {
45
- color?: boolean;
46
- verbosity?: VerbosityLevel;
47
- });
48
- /**
49
- * Set verbosity level
50
- * - quiet: Only errors and direct results
51
- * - normal: Errors, warnings, info, and results
52
- * - verbose: All of normal + debug messages
53
- * - debug: All output including trace
54
- */
55
- setVerbosity(level: VerbosityLevel): void;
56
- getVerbosity(): VerbosityLevel;
57
- isQuiet(): boolean;
58
- isVerbose(): boolean;
59
- isDebug(): boolean;
60
- private supportsColor;
61
- color(text: string, ...colors: ColorName[]): string;
62
- bold(text: string): string;
63
- dim(text: string): string;
64
- success(text: string): string;
65
- error(text: string): string;
66
- warning(text: string): string;
67
- info(text: string): string;
68
- highlight(text: string): string;
69
- write(text: string): void;
70
- writeln(text?: string): void;
71
- writeError(text: string): void;
72
- writeErrorln(text?: string): void;
73
- printSuccess(message: string): void;
74
- printError(message: string, details?: string): void;
75
- printWarning(message: string): void;
76
- printInfo(message: string): void;
77
- printDebug(message: string): void;
78
- printTrace(message: string): void;
79
- table(options: TableOptions): string;
80
- printTable(options: TableOptions): void;
81
- private calculateColumnWidths;
82
- private createBorderLine;
83
- private alignText;
84
- private truncate;
85
- private stripAnsi;
86
- createProgress(options: ProgressOptions): Progress;
87
- progressBar(current: number, total: number, width?: number): string;
88
- createSpinner(options: SpinnerOptions): Spinner;
89
- json(data: unknown, pretty?: boolean): string;
90
- printJson(data: unknown, pretty?: boolean): void;
91
- list(items: string[], bullet?: string): string;
92
- printList(items: string[], bullet?: string): void;
93
- numberedList(items: string[]): string;
94
- printNumberedList(items: string[]): void;
95
- box(content: string, title?: string): string;
96
- printBox(content: string, title?: string): void;
97
- setColorEnabled(enabled: boolean): void;
98
- isColorEnabled(): boolean;
99
- }
100
- export declare class Progress {
101
- private current;
102
- private total;
103
- private width;
104
- private startTime;
105
- private formatter;
106
- private showPercentage;
107
- private showETA;
108
- private lastRender;
109
- constructor(formatter: OutputFormatter, options: ProgressOptions);
110
- update(current: number): void;
111
- increment(amount?: number): void;
112
- render(): void;
113
- finish(): void;
114
- private formatTime;
115
- }
116
- export declare class Spinner {
117
- private formatter;
118
- private text;
119
- private frames;
120
- private interval;
121
- private frameIndex;
122
- private static readonly SPINNERS;
123
- constructor(formatter: OutputFormatter, options: SpinnerOptions);
124
- start(): void;
125
- stop(message?: string): void;
126
- succeed(message?: string): void;
127
- fail(message?: string): void;
128
- private render;
129
- setText(text: string): void;
130
- }
131
- export declare const output: OutputFormatter;
132
- export {};
8
+ export * from '@claude-flow/cli-core/output';
133
9
  //# sourceMappingURL=output.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,8BAA8B,CAAC"}
@@ -1,514 +1,9 @@
1
1
  /**
2
- * V3 CLI Output Formatter
3
- * Advanced output formatting with tables, progress bars, and colors
2
+ * V3 CLI Output Formatter — re-export shim (ADR-100, alpha.5).
3
+ *
4
+ * Authoritative source: @claude-flow/cli-core/output. Was a byte-identical
5
+ * 640-line copy. The OutputFormatter class and `output` instance plus all
6
+ * helper exports flow through unchanged. Edit cli-core for behavior changes.
4
7
  */
5
- // ============================================
6
- // Color Support
7
- // ============================================
8
- const COLORS = {
9
- // Standard colors
10
- reset: '\x1b[0m',
11
- bold: '\x1b[1m',
12
- dim: '\x1b[2m',
13
- italic: '\x1b[3m',
14
- underline: '\x1b[4m',
15
- // Foreground colors
16
- black: '\x1b[30m',
17
- red: '\x1b[31m',
18
- green: '\x1b[32m',
19
- yellow: '\x1b[33m',
20
- blue: '\x1b[34m',
21
- magenta: '\x1b[35m',
22
- cyan: '\x1b[36m',
23
- white: '\x1b[37m',
24
- gray: '\x1b[90m',
25
- // Bright foreground colors
26
- brightRed: '\x1b[91m',
27
- brightGreen: '\x1b[92m',
28
- brightYellow: '\x1b[93m',
29
- brightBlue: '\x1b[94m',
30
- brightMagenta: '\x1b[95m',
31
- brightCyan: '\x1b[96m',
32
- brightWhite: '\x1b[97m',
33
- // Background colors
34
- bgBlack: '\x1b[40m',
35
- bgRed: '\x1b[41m',
36
- bgGreen: '\x1b[42m',
37
- bgYellow: '\x1b[43m',
38
- bgBlue: '\x1b[44m',
39
- bgMagenta: '\x1b[45m',
40
- bgCyan: '\x1b[46m',
41
- bgWhite: '\x1b[47m'
42
- };
43
- export class OutputFormatter {
44
- colorEnabled;
45
- outputStream;
46
- errorStream;
47
- verbosity;
48
- constructor(options = {}) {
49
- this.colorEnabled = options.color ?? this.supportsColor();
50
- this.outputStream = process.stdout;
51
- this.errorStream = process.stderr;
52
- this.verbosity = options.verbosity ?? 'normal';
53
- }
54
- /**
55
- * Set verbosity level
56
- * - quiet: Only errors and direct results
57
- * - normal: Errors, warnings, info, and results
58
- * - verbose: All of normal + debug messages
59
- * - debug: All output including trace
60
- */
61
- setVerbosity(level) {
62
- this.verbosity = level;
63
- }
64
- getVerbosity() {
65
- return this.verbosity;
66
- }
67
- isQuiet() {
68
- return this.verbosity === 'quiet';
69
- }
70
- isVerbose() {
71
- return this.verbosity === 'verbose' || this.verbosity === 'debug';
72
- }
73
- isDebug() {
74
- return this.verbosity === 'debug';
75
- }
76
- supportsColor() {
77
- // Check for NO_COLOR environment variable
78
- if (process.env.NO_COLOR !== undefined)
79
- return false;
80
- // Check for FORCE_COLOR environment variable
81
- if (process.env.FORCE_COLOR !== undefined)
82
- return true;
83
- // Check if stdout is a TTY
84
- return process.stdout.isTTY ?? false;
85
- }
86
- // ============================================
87
- // Color Methods
88
- // ============================================
89
- color(text, ...colors) {
90
- if (!this.colorEnabled)
91
- return text;
92
- const codes = colors.map(c => COLORS[c]).join('');
93
- return `${codes}${text}${COLORS.reset}`;
94
- }
95
- bold(text) {
96
- return this.color(text, 'bold');
97
- }
98
- dim(text) {
99
- return this.color(text, 'dim');
100
- }
101
- success(text) {
102
- return this.color(text, 'green');
103
- }
104
- error(text) {
105
- return this.color(text, 'red');
106
- }
107
- warning(text) {
108
- return this.color(text, 'yellow');
109
- }
110
- info(text) {
111
- return this.color(text, 'blue');
112
- }
113
- highlight(text) {
114
- return this.color(text, 'cyan', 'bold');
115
- }
116
- // ============================================
117
- // Output Methods
118
- // ============================================
119
- write(text) {
120
- this.outputStream.write(text);
121
- }
122
- writeln(text = '') {
123
- this.outputStream.write(text + '\n');
124
- }
125
- writeError(text) {
126
- this.errorStream.write(text);
127
- }
128
- writeErrorln(text = '') {
129
- this.errorStream.write(text + '\n');
130
- }
131
- // ============================================
132
- // Formatted Output Methods
133
- // ============================================
134
- printSuccess(message) {
135
- // Success always shows (result output)
136
- const icon = this.color('[OK]', 'green', 'bold');
137
- this.writeln(`${icon} ${message}`);
138
- }
139
- printError(message, details) {
140
- // Errors always show
141
- const icon = this.color('[ERROR]', 'red', 'bold');
142
- this.writeErrorln(`${icon} ${message}`);
143
- if (details) {
144
- this.writeErrorln(this.dim(` ${details}`));
145
- }
146
- }
147
- printWarning(message) {
148
- // Warnings suppressed in quiet mode
149
- if (this.verbosity === 'quiet')
150
- return;
151
- const icon = this.color('[WARN]', 'yellow', 'bold');
152
- this.writeln(`${icon} ${message}`);
153
- }
154
- printInfo(message) {
155
- // Info suppressed in quiet mode
156
- if (this.verbosity === 'quiet')
157
- return;
158
- const icon = this.color('[INFO]', 'blue', 'bold');
159
- this.writeln(`${icon} ${message}`);
160
- }
161
- printDebug(message) {
162
- // Debug only shows in verbose/debug mode
163
- if (this.verbosity !== 'verbose' && this.verbosity !== 'debug')
164
- return;
165
- const icon = this.color('[DEBUG]', 'gray');
166
- this.writeln(`${icon} ${this.dim(message)}`);
167
- }
168
- printTrace(message) {
169
- // Trace only shows in debug mode
170
- if (this.verbosity !== 'debug')
171
- return;
172
- const icon = this.color('[TRACE]', 'gray', 'dim');
173
- this.writeln(`${icon} ${this.dim(message)}`);
174
- }
175
- // ============================================
176
- // Table Formatting
177
- // ============================================
178
- table(options) {
179
- const { columns, data, border = true, header = true, padding = 1, maxWidth } = options;
180
- // Calculate column widths
181
- const widths = this.calculateColumnWidths(columns, data, maxWidth);
182
- const lines = [];
183
- const pad = ' '.repeat(padding);
184
- // Border characters
185
- const borderChars = border ? {
186
- topLeft: '+', topRight: '+', bottomLeft: '+', bottomRight: '+',
187
- horizontal: '-', vertical: '|',
188
- leftT: '+', rightT: '+', topT: '+', bottomT: '+', cross: '+'
189
- } : {
190
- topLeft: '', topRight: '', bottomLeft: '', bottomRight: '',
191
- horizontal: '', vertical: ' ',
192
- leftT: '', rightT: '', topT: '', bottomT: '', cross: ''
193
- };
194
- // Top border
195
- if (border) {
196
- lines.push(this.createBorderLine(widths, borderChars, 'top', padding));
197
- }
198
- // Header row
199
- if (header) {
200
- const headerRow = columns.map((col, i) => {
201
- const text = this.truncate(col.header, widths[i]);
202
- return pad + this.alignText(this.bold(text), widths[i], col.align) + pad;
203
- }).join(borderChars.vertical);
204
- lines.push(`${borderChars.vertical}${headerRow}${borderChars.vertical}`);
205
- // Header separator
206
- if (border) {
207
- lines.push(this.createBorderLine(widths, borderChars, 'middle', padding));
208
- }
209
- }
210
- // Data rows
211
- for (const row of data) {
212
- const rowCells = columns.map((col, i) => {
213
- let value = row[col.key];
214
- // Apply formatter if provided
215
- if (col.format) {
216
- value = col.format(value);
217
- }
218
- else {
219
- value = String(value ?? '');
220
- }
221
- const text = this.truncate(String(value), widths[i]);
222
- return pad + this.alignText(text, widths[i], col.align) + pad;
223
- }).join(borderChars.vertical);
224
- lines.push(`${borderChars.vertical}${rowCells}${borderChars.vertical}`);
225
- }
226
- // Bottom border
227
- if (border) {
228
- lines.push(this.createBorderLine(widths, borderChars, 'bottom', padding));
229
- }
230
- return lines.join('\n');
231
- }
232
- printTable(options) {
233
- this.writeln(this.table(options));
234
- }
235
- calculateColumnWidths(columns, data, maxWidth) {
236
- const widths = columns.map((col, i) => {
237
- // Start with header width
238
- let width = col.header.length;
239
- // Check all data values
240
- for (const row of data) {
241
- let value = row[col.key];
242
- if (col.format) {
243
- value = col.format(value);
244
- }
245
- const len = this.stripAnsi(String(value ?? '')).length;
246
- width = Math.max(width, len);
247
- }
248
- // Apply column-specific width limit
249
- if (col.width) {
250
- width = Math.min(width, col.width);
251
- }
252
- return width;
253
- });
254
- // Apply max width constraint
255
- if (maxWidth) {
256
- const totalWidth = widths.reduce((a, b) => a + b, 0) + (columns.length * 3) + 1;
257
- if (totalWidth > maxWidth) {
258
- const reduction = (totalWidth - maxWidth) / columns.length;
259
- return widths.map(w => Math.max(3, Math.floor(w - reduction)));
260
- }
261
- }
262
- return widths;
263
- }
264
- createBorderLine(widths, chars, position, padding) {
265
- const cellWidth = (w) => chars.horizontal.repeat(w + (padding * 2));
266
- const cells = widths.map(cellWidth).join(position === 'top' ? chars.topT :
267
- position === 'bottom' ? chars.bottomT :
268
- chars.cross);
269
- const left = position === 'top' ? chars.topLeft : position === 'bottom' ? chars.bottomLeft : chars.leftT;
270
- const right = position === 'top' ? chars.topRight : position === 'bottom' ? chars.bottomRight : chars.rightT;
271
- return `${left}${cells}${right}`;
272
- }
273
- alignText(text, width, align = 'left') {
274
- const len = this.stripAnsi(text).length;
275
- const padding = width - len;
276
- if (padding <= 0)
277
- return text;
278
- switch (align) {
279
- case 'right':
280
- return ' '.repeat(padding) + text;
281
- case 'center':
282
- const left = Math.floor(padding / 2);
283
- const right = padding - left;
284
- return ' '.repeat(left) + text + ' '.repeat(right);
285
- default:
286
- return text + ' '.repeat(padding);
287
- }
288
- }
289
- truncate(text, maxLength) {
290
- const stripped = this.stripAnsi(text);
291
- if (stripped.length <= maxLength)
292
- return text;
293
- return stripped.slice(0, maxLength - 3) + '...';
294
- }
295
- stripAnsi(text) {
296
- return text.replace(/\x1b\[[0-9;]*m/g, '');
297
- }
298
- // ============================================
299
- // Progress Bar
300
- // ============================================
301
- createProgress(options) {
302
- return new Progress(this, options);
303
- }
304
- progressBar(current, total, width = 40) {
305
- const percent = Math.min(100, Math.max(0, (current / total) * 100));
306
- const filled = Math.round((width * percent) / 100);
307
- const empty = width - filled;
308
- const bar = this.color('#'.repeat(filled), 'green') +
309
- this.dim('-'.repeat(empty));
310
- return `[${bar}] ${percent.toFixed(1)}%`;
311
- }
312
- // ============================================
313
- // Spinner
314
- // ============================================
315
- createSpinner(options) {
316
- return new Spinner(this, options);
317
- }
318
- // ============================================
319
- // JSON Output
320
- // ============================================
321
- json(data, pretty = true) {
322
- return pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
323
- }
324
- printJson(data, pretty = true) {
325
- this.writeln(this.json(data, pretty));
326
- }
327
- // ============================================
328
- // List Output
329
- // ============================================
330
- list(items, bullet = '-') {
331
- return items.map(item => ` ${bullet} ${item}`).join('\n');
332
- }
333
- printList(items, bullet = '-') {
334
- this.writeln(this.list(items, bullet));
335
- }
336
- numberedList(items) {
337
- return items.map((item, i) => ` ${i + 1}. ${item}`).join('\n');
338
- }
339
- printNumberedList(items) {
340
- this.writeln(this.numberedList(items));
341
- }
342
- // ============================================
343
- // Box Output
344
- // ============================================
345
- box(content, title) {
346
- const lines = content.split('\n');
347
- const maxLen = Math.max(...lines.map(l => this.stripAnsi(l).length), title?.length ?? 0);
348
- const width = maxLen + 4;
349
- const border = {
350
- topLeft: '+', topRight: '+',
351
- bottomLeft: '+', bottomRight: '+',
352
- horizontal: '-', vertical: '|'
353
- };
354
- const result = [];
355
- // Top border with optional title
356
- if (title) {
357
- const titleText = ` ${title} `;
358
- const leftPad = Math.floor((width - titleText.length - 2) / 2);
359
- const rightPad = width - titleText.length - leftPad - 2;
360
- result.push(border.topLeft +
361
- border.horizontal.repeat(leftPad) +
362
- this.bold(titleText) +
363
- border.horizontal.repeat(rightPad) +
364
- border.topRight);
365
- }
366
- else {
367
- result.push(border.topLeft + border.horizontal.repeat(width - 2) + border.topRight);
368
- }
369
- // Content lines
370
- for (const line of lines) {
371
- const stripped = this.stripAnsi(line);
372
- const padding = maxLen - stripped.length;
373
- result.push(`${border.vertical} ${line}${' '.repeat(padding)} ${border.vertical}`);
374
- }
375
- // Bottom border
376
- result.push(border.bottomLeft + border.horizontal.repeat(width - 2) + border.bottomRight);
377
- return result.join('\n');
378
- }
379
- printBox(content, title) {
380
- this.writeln(this.box(content, title));
381
- }
382
- setColorEnabled(enabled) {
383
- this.colorEnabled = enabled;
384
- }
385
- isColorEnabled() {
386
- return this.colorEnabled;
387
- }
388
- }
389
- // ============================================
390
- // Progress Class
391
- // ============================================
392
- export class Progress {
393
- current;
394
- total;
395
- width;
396
- startTime;
397
- formatter;
398
- showPercentage;
399
- showETA;
400
- lastRender = '';
401
- constructor(formatter, options) {
402
- this.formatter = formatter;
403
- this.current = options.current ?? 0;
404
- this.total = options.total;
405
- this.width = options.width ?? 40;
406
- this.showPercentage = options.showPercentage ?? true;
407
- this.showETA = options.showETA ?? true;
408
- this.startTime = Date.now();
409
- }
410
- update(current) {
411
- this.current = current;
412
- this.render();
413
- }
414
- increment(amount = 1) {
415
- this.update(this.current + amount);
416
- }
417
- render() {
418
- const bar = this.formatter.progressBar(this.current, this.total, this.width);
419
- let output = bar;
420
- if (this.showETA && this.current > 0) {
421
- const elapsed = Date.now() - this.startTime;
422
- const rate = this.current / elapsed;
423
- const remaining = this.total - this.current;
424
- const eta = remaining / rate;
425
- if (isFinite(eta)) {
426
- output += ` ETA: ${this.formatTime(eta)}`;
427
- }
428
- }
429
- // Clear previous line and write new
430
- if (this.lastRender) {
431
- process.stdout.write('\r' + ' '.repeat(this.lastRender.length) + '\r');
432
- }
433
- process.stdout.write(output);
434
- this.lastRender = output;
435
- }
436
- finish() {
437
- this.current = this.total;
438
- this.render();
439
- process.stdout.write('\n');
440
- }
441
- formatTime(ms) {
442
- const seconds = Math.floor(ms / 1000);
443
- const minutes = Math.floor(seconds / 60);
444
- const hours = Math.floor(minutes / 60);
445
- if (hours > 0) {
446
- return `${hours}h ${minutes % 60}m`;
447
- }
448
- else if (minutes > 0) {
449
- return `${minutes}m ${seconds % 60}s`;
450
- }
451
- else {
452
- return `${seconds}s`;
453
- }
454
- }
455
- }
456
- // ============================================
457
- // Spinner Class
458
- // ============================================
459
- export class Spinner {
460
- formatter;
461
- text;
462
- frames;
463
- interval = null;
464
- frameIndex = 0;
465
- static SPINNERS = {
466
- dots: ['...', '..:', '.::', ':::', '::.', ':..',],
467
- line: ['-', '\\', '|', '/'],
468
- arc: ['◜', '◠', '◝', '◞', '◡', '◟'],
469
- circle: ['◐', '◓', '◑', '◒'],
470
- arrows: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙']
471
- };
472
- constructor(formatter, options) {
473
- this.formatter = formatter;
474
- this.text = options.text;
475
- this.frames = Spinner.SPINNERS[options.spinner ?? 'dots'];
476
- }
477
- start() {
478
- if (this.interval)
479
- return;
480
- this.interval = setInterval(() => {
481
- this.render();
482
- this.frameIndex = (this.frameIndex + 1) % this.frames.length;
483
- }, 100);
484
- this.interval.unref();
485
- this.render();
486
- }
487
- stop(message) {
488
- if (this.interval) {
489
- clearInterval(this.interval);
490
- this.interval = null;
491
- }
492
- // Clear the line
493
- process.stdout.write('\r' + ' '.repeat(this.text.length + 10) + '\r');
494
- if (message) {
495
- this.formatter.writeln(message);
496
- }
497
- }
498
- succeed(message) {
499
- this.stop(this.formatter.success(message ?? this.text));
500
- }
501
- fail(message) {
502
- this.stop(this.formatter.error(message ?? this.text));
503
- }
504
- render() {
505
- const frame = this.formatter.info(this.frames[this.frameIndex]);
506
- process.stdout.write(`\r${frame} ${this.text}`);
507
- }
508
- setText(text) {
509
- this.text = text;
510
- }
511
- }
512
- // Export singleton instance
513
- export const output = new OutputFormatter();
8
+ export * from '@claude-flow/cli-core/output';
514
9
  //# sourceMappingURL=output.js.map