@portel/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-formatter.d.ts +65 -0
- package/dist/cli-formatter.d.ts.map +1 -0
- package/dist/cli-formatter.js +585 -0
- package/dist/cli-formatter.js.map +1 -0
- package/dist/context.d.ts +23 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +25 -0
- package/dist/context.js.map +1 -0
- package/dist/fuzzy-matcher.d.ts +39 -0
- package/dist/fuzzy-matcher.d.ts.map +1 -0
- package/dist/fuzzy-matcher.js +89 -0
- package/dist/fuzzy-matcher.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +59 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +147 -0
- package/dist/logger.js.map +1 -0
- package/dist/progress.d.ts +67 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +165 -0
- package/dist/progress.js.map +1 -0
- package/dist/text-utils.d.ts +34 -0
- package/dist/text-utils.d.ts.map +1 -0
- package/dist/text-utils.js +104 -0
- package/dist/text-utils.js.map +1 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/dist/progress.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Rendering Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides ephemeral progress indicators that clear when done:
|
|
5
|
+
* - Spinners for indeterminate progress
|
|
6
|
+
* - Progress bars for determinate progress
|
|
7
|
+
*
|
|
8
|
+
* Always writes to stderr to avoid interfering with stdout data.
|
|
9
|
+
*/
|
|
10
|
+
import * as readline from 'readline';
|
|
11
|
+
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
12
|
+
/**
|
|
13
|
+
* Progress renderer that manages ephemeral output
|
|
14
|
+
* All progress is shown on stderr and clears when complete
|
|
15
|
+
*/
|
|
16
|
+
export class ProgressRenderer {
|
|
17
|
+
spinnerInterval;
|
|
18
|
+
currentFrame = 0;
|
|
19
|
+
isActive = false;
|
|
20
|
+
lastMessage = '';
|
|
21
|
+
lastLength = 0;
|
|
22
|
+
/**
|
|
23
|
+
* Start an indeterminate spinner with auto-animation
|
|
24
|
+
* Updates every 80ms until stopped
|
|
25
|
+
*/
|
|
26
|
+
startSpinner(message) {
|
|
27
|
+
this.stop();
|
|
28
|
+
this.isActive = true;
|
|
29
|
+
this.lastMessage = message;
|
|
30
|
+
this.renderSpinner();
|
|
31
|
+
this.spinnerInterval = setInterval(() => {
|
|
32
|
+
this.currentFrame = (this.currentFrame + 1) % SPINNER_FRAMES.length;
|
|
33
|
+
this.renderSpinner();
|
|
34
|
+
}, 80);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Show a single frame of spinner (no auto-animation)
|
|
38
|
+
*/
|
|
39
|
+
showSpinner(message) {
|
|
40
|
+
this.clearLine();
|
|
41
|
+
this.isActive = true;
|
|
42
|
+
this.lastMessage = message;
|
|
43
|
+
this.renderSpinner();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Show a progress bar with percentage (0-1)
|
|
47
|
+
*/
|
|
48
|
+
showProgress(value, message) {
|
|
49
|
+
this.stop();
|
|
50
|
+
this.isActive = true;
|
|
51
|
+
this.lastMessage = message || '';
|
|
52
|
+
this.renderProgressBar(value);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Render progress bar with spinner animation
|
|
56
|
+
*/
|
|
57
|
+
render(value, message) {
|
|
58
|
+
this.isActive = true;
|
|
59
|
+
this.lastMessage = message || '';
|
|
60
|
+
const pct = Math.round(value * 100);
|
|
61
|
+
const barWidth = 20;
|
|
62
|
+
const filled = Math.round(value * barWidth);
|
|
63
|
+
const empty = barWidth - filled;
|
|
64
|
+
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
65
|
+
const spinner = pct < 100 ? SPINNER_FRAMES[this.currentFrame++ % SPINNER_FRAMES.length] : '✓';
|
|
66
|
+
const text = `${spinner} [${bar}] ${pct.toString().padStart(3)}%${this.lastMessage ? ` ${this.lastMessage}` : ''}`;
|
|
67
|
+
this.clearLine();
|
|
68
|
+
process.stderr.write(text);
|
|
69
|
+
this.lastLength = text.length;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Update message without restarting animation
|
|
73
|
+
*/
|
|
74
|
+
updateMessage(message) {
|
|
75
|
+
if (this.isActive) {
|
|
76
|
+
this.lastMessage = message;
|
|
77
|
+
if (this.spinnerInterval) {
|
|
78
|
+
this.renderSpinner();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Stop and clear progress display
|
|
84
|
+
*/
|
|
85
|
+
stop() {
|
|
86
|
+
this.done();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* End progress display (clears the line)
|
|
90
|
+
*/
|
|
91
|
+
done() {
|
|
92
|
+
if (this.spinnerInterval) {
|
|
93
|
+
clearInterval(this.spinnerInterval);
|
|
94
|
+
this.spinnerInterval = undefined;
|
|
95
|
+
}
|
|
96
|
+
if (this.isActive) {
|
|
97
|
+
this.clearLine();
|
|
98
|
+
this.isActive = false;
|
|
99
|
+
}
|
|
100
|
+
this.currentFrame = 0;
|
|
101
|
+
this.lastMessage = '';
|
|
102
|
+
this.lastLength = 0;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Print a persistent status message
|
|
106
|
+
*/
|
|
107
|
+
status(message) {
|
|
108
|
+
this.done();
|
|
109
|
+
console.error(`ℹ ${message}`);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Check if progress is currently active
|
|
113
|
+
*/
|
|
114
|
+
get active() {
|
|
115
|
+
return this.isActive;
|
|
116
|
+
}
|
|
117
|
+
clearLine() {
|
|
118
|
+
if ((this.lastLength > 0 || this.isActive) && process.stderr.isTTY) {
|
|
119
|
+
readline.clearLine(process.stderr, 0);
|
|
120
|
+
readline.cursorTo(process.stderr, 0);
|
|
121
|
+
this.lastLength = 0;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
renderSpinner() {
|
|
125
|
+
const frame = SPINNER_FRAMES[this.currentFrame];
|
|
126
|
+
const text = `${frame} ${this.lastMessage}`;
|
|
127
|
+
this.clearLine();
|
|
128
|
+
process.stderr.write(text);
|
|
129
|
+
this.lastLength = text.length;
|
|
130
|
+
}
|
|
131
|
+
renderProgressBar(value) {
|
|
132
|
+
const percentage = Math.round(value * 100);
|
|
133
|
+
const barLength = 30;
|
|
134
|
+
const filled = Math.round(barLength * value);
|
|
135
|
+
const bar = '█'.repeat(filled) + '░'.repeat(barLength - filled);
|
|
136
|
+
const text = `[${bar}] ${percentage}%${this.lastMessage ? ` ${this.lastMessage}` : ''}`;
|
|
137
|
+
this.clearLine();
|
|
138
|
+
process.stderr.write(text);
|
|
139
|
+
this.lastLength = text.length;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Global instance
|
|
143
|
+
let globalRenderer = null;
|
|
144
|
+
export function getProgressRenderer() {
|
|
145
|
+
if (!globalRenderer) {
|
|
146
|
+
globalRenderer = new ProgressRenderer();
|
|
147
|
+
}
|
|
148
|
+
return globalRenderer;
|
|
149
|
+
}
|
|
150
|
+
export function startSpinner(message) {
|
|
151
|
+
getProgressRenderer().startSpinner(message);
|
|
152
|
+
}
|
|
153
|
+
export function showProgress(value, message) {
|
|
154
|
+
getProgressRenderer().showProgress(value, message);
|
|
155
|
+
}
|
|
156
|
+
export function updateProgressMessage(message) {
|
|
157
|
+
getProgressRenderer().updateMessage(message);
|
|
158
|
+
}
|
|
159
|
+
export function stopProgress() {
|
|
160
|
+
getProgressRenderer().stop();
|
|
161
|
+
}
|
|
162
|
+
export function isProgressActive() {
|
|
163
|
+
return getProgressRenderer().active;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Processing Utilities
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for text wrapping, formatting, and manipulation.
|
|
5
|
+
*/
|
|
6
|
+
import type { TextWrapOptions } from './types.js';
|
|
7
|
+
export declare class TextUtils {
|
|
8
|
+
/**
|
|
9
|
+
* Wrap text to fit within specified width with optional indentation
|
|
10
|
+
*/
|
|
11
|
+
static wrapText(text: string, options: TextWrapOptions): string;
|
|
12
|
+
/**
|
|
13
|
+
* Wrap text with background color applied to each line
|
|
14
|
+
*/
|
|
15
|
+
static wrapTextWithBackground(text: string, maxWidth: number, indent: string, backgroundFormatter: (text: string) => string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Truncate text with ellipsis if too long
|
|
18
|
+
*/
|
|
19
|
+
static truncate(text: string, maxLength: number, ellipsis?: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Pad a string to a fixed width
|
|
22
|
+
*/
|
|
23
|
+
static pad(text: string, width: number, align?: 'left' | 'right' | 'center'): string;
|
|
24
|
+
/**
|
|
25
|
+
* Strip ANSI escape codes from string
|
|
26
|
+
*/
|
|
27
|
+
static stripAnsi(text: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Get visible length of string (excluding ANSI codes)
|
|
30
|
+
*/
|
|
31
|
+
static visibleLength(text: string): number;
|
|
32
|
+
}
|
|
33
|
+
export { TextWrapOptions };
|
|
34
|
+
//# sourceMappingURL=text-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-utils.d.ts","sourceRoot":"","sources":["../src/text-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,SAAS;IACpB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM;IA+C/D;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAC3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC5C,MAAM;IAcT;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAc,GAAG,MAAM;IAKlF;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,OAAO,GAAG,QAAiB,GAAG,MAAM;IAgB5F;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKtC;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAG3C;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Processing Utilities
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for text wrapping, formatting, and manipulation.
|
|
5
|
+
*/
|
|
6
|
+
export class TextUtils {
|
|
7
|
+
/**
|
|
8
|
+
* Wrap text to fit within specified width with optional indentation
|
|
9
|
+
*/
|
|
10
|
+
static wrapText(text, options) {
|
|
11
|
+
const { maxWidth, indent = '', cleanupPrefixes = false, preserveWhitespace = false } = options;
|
|
12
|
+
if (!text)
|
|
13
|
+
return text;
|
|
14
|
+
let processedText = text;
|
|
15
|
+
if (cleanupPrefixes) {
|
|
16
|
+
processedText = text
|
|
17
|
+
.replace(/^[^:]+:\s*/, '')
|
|
18
|
+
.replace(/\s+/g, ' ')
|
|
19
|
+
.trim();
|
|
20
|
+
}
|
|
21
|
+
else if (!preserveWhitespace) {
|
|
22
|
+
processedText = text.trim();
|
|
23
|
+
}
|
|
24
|
+
if (processedText.length <= maxWidth) {
|
|
25
|
+
return processedText;
|
|
26
|
+
}
|
|
27
|
+
const words = processedText.split(' ');
|
|
28
|
+
const lines = [];
|
|
29
|
+
let currentLine = '';
|
|
30
|
+
for (const word of words) {
|
|
31
|
+
const testLine = currentLine ? `${currentLine} ${word}` : word;
|
|
32
|
+
if (testLine.length <= maxWidth) {
|
|
33
|
+
currentLine = testLine;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
if (currentLine) {
|
|
37
|
+
lines.push(currentLine);
|
|
38
|
+
currentLine = word;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
lines.push(word);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (currentLine) {
|
|
46
|
+
lines.push(currentLine);
|
|
47
|
+
}
|
|
48
|
+
return lines.map((line, index) => index === 0 ? line : `\n${indent}${line}`).join('');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wrap text with background color applied to each line
|
|
52
|
+
*/
|
|
53
|
+
static wrapTextWithBackground(text, maxWidth, indent, backgroundFormatter) {
|
|
54
|
+
if (text.length <= maxWidth) {
|
|
55
|
+
return `${indent}${backgroundFormatter(text)}`;
|
|
56
|
+
}
|
|
57
|
+
const wrappedText = this.wrapText(text, { maxWidth, indent: '', preserveWhitespace: true });
|
|
58
|
+
const lines = wrappedText.split('\n');
|
|
59
|
+
return lines.map((line, _index) => {
|
|
60
|
+
const formattedLine = backgroundFormatter(line);
|
|
61
|
+
return `${indent}${formattedLine}`;
|
|
62
|
+
}).join('\n');
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Truncate text with ellipsis if too long
|
|
66
|
+
*/
|
|
67
|
+
static truncate(text, maxLength, ellipsis = '...') {
|
|
68
|
+
if (text.length <= maxLength)
|
|
69
|
+
return text;
|
|
70
|
+
return text.slice(0, maxLength - ellipsis.length) + ellipsis;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Pad a string to a fixed width
|
|
74
|
+
*/
|
|
75
|
+
static pad(text, width, align = 'left') {
|
|
76
|
+
if (text.length >= width)
|
|
77
|
+
return text;
|
|
78
|
+
const padding = width - text.length;
|
|
79
|
+
switch (align) {
|
|
80
|
+
case 'right':
|
|
81
|
+
return ' '.repeat(padding) + text;
|
|
82
|
+
case 'center':
|
|
83
|
+
const left = Math.floor(padding / 2);
|
|
84
|
+
const right = padding - left;
|
|
85
|
+
return ' '.repeat(left) + text + ' '.repeat(right);
|
|
86
|
+
default:
|
|
87
|
+
return text + ' '.repeat(padding);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Strip ANSI escape codes from string
|
|
92
|
+
*/
|
|
93
|
+
static stripAnsi(text) {
|
|
94
|
+
// eslint-disable-next-line no-control-regex
|
|
95
|
+
return text.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, '');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get visible length of string (excluding ANSI codes)
|
|
99
|
+
*/
|
|
100
|
+
static visibleLength(text) {
|
|
101
|
+
return this.stripAnsi(text).length;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=text-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-utils.js","sourceRoot":"","sources":["../src/text-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @portel/core type definitions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Output format hints for CLI formatting
|
|
6
|
+
*
|
|
7
|
+
* Structural formats:
|
|
8
|
+
* - primitive: Single values (string, number, boolean)
|
|
9
|
+
* - table: Flat objects or arrays of flat objects
|
|
10
|
+
* - tree: Nested/hierarchical structures
|
|
11
|
+
* - list: Arrays of primitives
|
|
12
|
+
* - card: Bordered card view for objects
|
|
13
|
+
* - tabs: Tabbed sections for grouped data
|
|
14
|
+
* - accordion: Collapsible sections
|
|
15
|
+
* - none: No data to display
|
|
16
|
+
*
|
|
17
|
+
* Content formats:
|
|
18
|
+
* - json, markdown, yaml, xml, html: Syntax highlighted content
|
|
19
|
+
* - code / code:<lang>: Syntax highlighted code
|
|
20
|
+
*/
|
|
21
|
+
export type OutputFormat = 'primitive' | 'table' | 'tree' | 'list' | 'none' | 'card' | 'grid' | 'chips' | 'kv' | 'tabs' | 'accordion' | 'json' | 'markdown' | 'yaml' | 'xml' | 'html' | 'mermaid' | `code` | `code:${string}`;
|
|
22
|
+
/**
|
|
23
|
+
* Text wrapping options for CLI output
|
|
24
|
+
*/
|
|
25
|
+
export interface TextWrapOptions {
|
|
26
|
+
maxWidth: number;
|
|
27
|
+
indent?: string;
|
|
28
|
+
cleanupPrefixes?: boolean;
|
|
29
|
+
preserveWhitespace?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Fuzzy match result
|
|
33
|
+
*/
|
|
34
|
+
export interface FuzzyMatch {
|
|
35
|
+
text: string;
|
|
36
|
+
distance: number;
|
|
37
|
+
score: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execution context for async operations
|
|
41
|
+
*/
|
|
42
|
+
export interface ExecutionContext {
|
|
43
|
+
outputHandler?: (data: any) => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Log levels for logger
|
|
47
|
+
*/
|
|
48
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
49
|
+
/**
|
|
50
|
+
* Logger configuration options
|
|
51
|
+
*/
|
|
52
|
+
export interface LoggerOptions {
|
|
53
|
+
level?: LogLevel;
|
|
54
|
+
prefix?: string;
|
|
55
|
+
silent?: boolean;
|
|
56
|
+
debugMode?: boolean;
|
|
57
|
+
logFilePath?: string;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,GACpB,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAChD,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GACvD,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,GACzD,MAAM,GAAG,QAAQ,MAAM,EAAE,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@portel/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI toolkit for building terminal applications - formatting, progress, fuzzy matching, logging",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"clean": "rm -rf dist",
|
|
21
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"cli",
|
|
25
|
+
"formatter",
|
|
26
|
+
"progress",
|
|
27
|
+
"spinner",
|
|
28
|
+
"fuzzy",
|
|
29
|
+
"logging",
|
|
30
|
+
"terminal",
|
|
31
|
+
"utilities"
|
|
32
|
+
],
|
|
33
|
+
"author": "Portel",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/portel-dev/portel-cli"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"chalk": "^5.3.0",
|
|
41
|
+
"cli-highlight": "^2.1.11"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.0.0",
|
|
45
|
+
"typescript": "^5.3.0"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|