mepcli 0.2.1 → 0.2.5

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.
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiSelectPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ // --- Implementation: MultiSelect Prompt ---
8
+ class MultiSelectPrompt extends base_1.Prompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.selectedIndex = 0;
12
+ this.searchBuffer = '';
13
+ this.scrollTop = 0;
14
+ this.pageSize = 7;
15
+ this.errorMsg = '';
16
+ this.checkedState = options.choices.map(c => !!c.selected);
17
+ this.selectedIndex = 0;
18
+ }
19
+ getFilteredChoices() {
20
+ if (!this.searchBuffer)
21
+ return this.options.choices.map((c, i) => ({ ...c, originalIndex: i }));
22
+ return this.options.choices
23
+ .map((c, i) => ({ ...c, originalIndex: i }))
24
+ .filter(c => c.title.toLowerCase().includes(this.searchBuffer.toLowerCase()));
25
+ }
26
+ render(firstRender) {
27
+ this.print(ansi_1.ANSI.HIDE_CURSOR);
28
+ // This is tricky because height changes with filter.
29
+ // Simplified clearing:
30
+ if (!firstRender) {
31
+ this.print(ansi_1.ANSI.ERASE_DOWN); // Clear everything below cursor
32
+ // But we need to move cursor up to start of prompt
33
+ // We can store last height?
34
+ }
35
+ // Wait, standard render loop usually assumes fixed position or we manually handle it.
36
+ // Let's use ERASE_LINE + UP loop like SelectPrompt but simpler since we have full screen control in a way
37
+ // Actually, let's just clear screen? No, that's bad.
38
+ // Let's stick to SelectPrompt's strategy.
39
+ if (!firstRender) {
40
+ // Hack: Just clear last 10 lines to be safe? No.
41
+ // We will implement proper tracking later if needed, for now standard clear
42
+ // Let's re-use SelectPrompt logic structure if possible, but distinct implementation here.
43
+ // Simplest: Always move to top of prompt and erase down.
44
+ // Assuming we track how many lines we printed.
45
+ }
46
+ // ... Implementation detail: use a simpler clear strategy:
47
+ // Move to start of prompt line (we need to track lines printed in previous frame)
48
+ if (this.lastRenderLines) {
49
+ this.print(`\x1b[${this.lastRenderLines}A`);
50
+ this.print(ansi_1.ANSI.ERASE_DOWN);
51
+ }
52
+ let output = '';
53
+ const choices = this.getFilteredChoices();
54
+ // Adjust Scroll
55
+ if (this.selectedIndex < this.scrollTop) {
56
+ this.scrollTop = this.selectedIndex;
57
+ }
58
+ else if (this.selectedIndex >= this.scrollTop + this.pageSize) {
59
+ this.scrollTop = this.selectedIndex - this.pageSize + 1;
60
+ }
61
+ if (this.scrollTop > choices.length - 1) {
62
+ this.scrollTop = Math.max(0, choices.length - this.pageSize);
63
+ }
64
+ const icon = this.errorMsg ? `${theme_1.theme.error}✖` : `${theme_1.theme.success}?`;
65
+ const searchStr = this.searchBuffer ? ` ${theme_1.theme.muted}(Filter: ${this.searchBuffer})${ansi_1.ANSI.RESET}` : '';
66
+ output += `${icon} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}${searchStr}\n`;
67
+ if (choices.length === 0) {
68
+ output += ` ${theme_1.theme.muted}No results found${ansi_1.ANSI.RESET}\n`;
69
+ }
70
+ else {
71
+ const visible = choices.slice(this.scrollTop, this.scrollTop + this.pageSize);
72
+ visible.forEach((choice, index) => {
73
+ const actualIndex = this.scrollTop + index;
74
+ const cursor = actualIndex === this.selectedIndex ? `${theme_1.theme.main}❯${ansi_1.ANSI.RESET}` : ' ';
75
+ const isChecked = this.checkedState[choice.originalIndex];
76
+ const checkbox = isChecked
77
+ ? `${theme_1.theme.success}◉${ansi_1.ANSI.RESET}`
78
+ : `${theme_1.theme.muted}◯${ansi_1.ANSI.RESET}`;
79
+ output += `${cursor} ${checkbox} ${choice.title}\n`;
80
+ });
81
+ }
82
+ if (this.errorMsg) {
83
+ output += `${theme_1.theme.error}>> ${this.errorMsg}${ansi_1.ANSI.RESET}\n`;
84
+ }
85
+ this.print(output);
86
+ // Count lines
87
+ const lines = 1 + (choices.length === 0 ? 1 : Math.min(choices.length, this.pageSize)) + (this.errorMsg ? 1 : 0);
88
+ this.lastRenderLines = lines;
89
+ }
90
+ handleInput(char) {
91
+ const choices = this.getFilteredChoices();
92
+ if (char === '\r' || char === '\n') {
93
+ const selectedCount = this.checkedState.filter(Boolean).length;
94
+ const { min = 0, max } = this.options;
95
+ if (selectedCount < min) {
96
+ this.errorMsg = `Select at least ${min}.`;
97
+ this.render(false);
98
+ return;
99
+ }
100
+ if (max && selectedCount > max) {
101
+ this.errorMsg = `Max ${max} allowed.`;
102
+ this.render(false);
103
+ return;
104
+ }
105
+ const results = this.options.choices
106
+ .filter((_, i) => this.checkedState[i])
107
+ .map(c => c.value);
108
+ this.submit(results);
109
+ return;
110
+ }
111
+ if (char === ' ') {
112
+ if (choices.length > 0) {
113
+ const choice = choices[this.selectedIndex];
114
+ const originalIndex = choice.originalIndex;
115
+ this.checkedState[originalIndex] = !this.checkedState[originalIndex];
116
+ this.render(false);
117
+ }
118
+ return;
119
+ }
120
+ if (this.isUp(char)) { // Up
121
+ if (choices.length > 0) {
122
+ this.selectedIndex = (this.selectedIndex - 1 + choices.length) % choices.length;
123
+ this.render(false);
124
+ }
125
+ return;
126
+ }
127
+ if (this.isDown(char)) { // Down
128
+ if (choices.length > 0) {
129
+ this.selectedIndex = (this.selectedIndex + 1) % choices.length;
130
+ this.render(false);
131
+ }
132
+ return;
133
+ }
134
+ if (char === '\u0008' || char === '\x7f') { // Backspace
135
+ if (this.searchBuffer.length > 0) {
136
+ this.searchBuffer = this.searchBuffer.slice(0, -1);
137
+ this.selectedIndex = 0;
138
+ this.render(false);
139
+ }
140
+ return;
141
+ }
142
+ if (!/^[\x00-\x1F]/.test(char) && !char.startsWith('\x1b')) {
143
+ this.searchBuffer += char;
144
+ this.selectedIndex = 0;
145
+ this.render(false);
146
+ }
147
+ }
148
+ }
149
+ exports.MultiSelectPrompt = MultiSelectPrompt;
@@ -0,0 +1,10 @@
1
+ import { Prompt } from '../base';
2
+ import { NumberOptions } from '../types';
3
+ export declare class NumberPrompt extends Prompt<number, NumberOptions> {
4
+ private cursor;
5
+ private stringValue;
6
+ private errorMsg;
7
+ constructor(options: NumberOptions);
8
+ protected render(firstRender: boolean): void;
9
+ protected handleInput(char: string): void;
10
+ }
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NumberPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ // --- Implementation: Number Prompt ---
8
+ class NumberPrompt extends base_1.Prompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.cursor = 0;
12
+ this.errorMsg = '';
13
+ this.value = options.initial ?? 0;
14
+ this.stringValue = this.value.toString();
15
+ this.cursor = this.stringValue.length;
16
+ }
17
+ render(firstRender) {
18
+ this.print(ansi_1.ANSI.SHOW_CURSOR);
19
+ if (!firstRender) {
20
+ this.print(ansi_1.ANSI.ERASE_LINE + ansi_1.ANSI.CURSOR_LEFT);
21
+ if (this.errorMsg) {
22
+ this.print(ansi_1.ANSI.UP + ansi_1.ANSI.ERASE_LINE + ansi_1.ANSI.CURSOR_LEFT);
23
+ }
24
+ }
25
+ // 1. Render the Prompt Message
26
+ this.print(ansi_1.ANSI.ERASE_LINE + ansi_1.ANSI.CURSOR_LEFT);
27
+ const icon = this.errorMsg ? `${theme_1.theme.error}✖` : `${theme_1.theme.success}?`;
28
+ this.print(`${icon} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET} `);
29
+ // 2. Render the Value
30
+ this.print(`${theme_1.theme.main}${this.stringValue}${ansi_1.ANSI.RESET}`);
31
+ // 3. Handle Error Message
32
+ if (this.errorMsg) {
33
+ this.print(`\n${ansi_1.ANSI.ERASE_LINE}${theme_1.theme.error}>> ${this.errorMsg}${ansi_1.ANSI.RESET}`);
34
+ this.print(ansi_1.ANSI.UP);
35
+ const promptLen = this.options.message.length + 3;
36
+ const valLen = this.stringValue.length;
37
+ this.print(`\x1b[1000D\x1b[${promptLen + valLen}C`);
38
+ }
39
+ // 4. Position Cursor
40
+ const diff = this.stringValue.length - this.cursor;
41
+ if (diff > 0) {
42
+ this.print(`\x1b[${diff}D`);
43
+ }
44
+ }
45
+ handleInput(char) {
46
+ // Enter
47
+ if (char === '\r' || char === '\n') {
48
+ const num = parseFloat(this.stringValue);
49
+ if (isNaN(num)) {
50
+ this.errorMsg = 'Please enter a valid number.';
51
+ this.render(false);
52
+ return;
53
+ }
54
+ if (this.options.min !== undefined && num < this.options.min) {
55
+ this.errorMsg = `Minimum value is ${this.options.min}`;
56
+ this.render(false);
57
+ return;
58
+ }
59
+ if (this.options.max !== undefined && num > this.options.max) {
60
+ this.errorMsg = `Maximum value is ${this.options.max}`;
61
+ this.render(false);
62
+ return;
63
+ }
64
+ if (this.errorMsg) {
65
+ this.print(`\n${ansi_1.ANSI.ERASE_LINE}${ansi_1.ANSI.UP}`);
66
+ }
67
+ this.submit(num);
68
+ return;
69
+ }
70
+ // Up Arrow (Increment)
71
+ if (this.isUp(char)) {
72
+ let num = parseFloat(this.stringValue) || 0;
73
+ num += (this.options.step ?? 1);
74
+ if (this.options.max !== undefined && num > this.options.max)
75
+ num = this.options.max;
76
+ this.stringValue = num.toString();
77
+ this.cursor = this.stringValue.length;
78
+ this.errorMsg = '';
79
+ this.render(false);
80
+ return;
81
+ }
82
+ // Down Arrow (Decrement)
83
+ if (this.isDown(char)) {
84
+ let num = parseFloat(this.stringValue) || 0;
85
+ num -= (this.options.step ?? 1);
86
+ if (this.options.min !== undefined && num < this.options.min)
87
+ num = this.options.min;
88
+ this.stringValue = num.toString();
89
+ this.cursor = this.stringValue.length;
90
+ this.errorMsg = '';
91
+ this.render(false);
92
+ return;
93
+ }
94
+ // Backspace
95
+ if (char === '\u0008' || char === '\x7f') {
96
+ if (this.cursor > 0) {
97
+ this.stringValue = this.stringValue.slice(0, this.cursor - 1) + this.stringValue.slice(this.cursor);
98
+ this.cursor--;
99
+ this.errorMsg = '';
100
+ this.render(false);
101
+ }
102
+ return;
103
+ }
104
+ // Arrow Left
105
+ if (this.isLeft(char)) {
106
+ if (this.cursor > 0) {
107
+ this.cursor--;
108
+ this.render(false);
109
+ }
110
+ return;
111
+ }
112
+ // Arrow Right
113
+ if (this.isRight(char)) {
114
+ if (this.cursor < this.stringValue.length) {
115
+ this.cursor++;
116
+ this.render(false);
117
+ }
118
+ return;
119
+ }
120
+ // Numeric Input (and . and -)
121
+ // Simple paste support for numbers is also good
122
+ if (/^[0-9.\-]+$/.test(char)) {
123
+ // Basic validation for pasted content
124
+ if (char.includes('-') && (this.cursor !== 0 || this.stringValue.includes('-') || char.lastIndexOf('-') > 0)) {
125
+ // If complex paste fails simple checks, ignore or let user correct
126
+ // For now, strict check on single char logic is preserved if we want,
127
+ // but let's allow pasting valid number strings
128
+ }
129
+ // Allow if it looks like a number part
130
+ this.stringValue = this.stringValue.slice(0, this.cursor) + char + this.stringValue.slice(this.cursor);
131
+ this.cursor += char.length;
132
+ this.errorMsg = '';
133
+ this.render(false);
134
+ }
135
+ }
136
+ }
137
+ exports.NumberPrompt = NumberPrompt;
@@ -0,0 +1,16 @@
1
+ import { Prompt } from '../base';
2
+ import { SelectOptions } from '../types';
3
+ export declare class SelectPrompt extends Prompt<any, SelectOptions> {
4
+ private selectedIndex;
5
+ private searchBuffer;
6
+ private scrollTop;
7
+ private readonly pageSize;
8
+ constructor(options: SelectOptions);
9
+ private isSeparator;
10
+ private findNextSelectableIndex;
11
+ private getFilteredChoices;
12
+ private lastRenderHeight;
13
+ protected renderWrapper(firstRender: boolean): void;
14
+ protected render(firstRender: boolean): void;
15
+ protected handleInput(char: string): void;
16
+ }
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ // --- Implementation: Select Prompt ---
8
+ class SelectPrompt extends base_1.Prompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.selectedIndex = 0;
12
+ this.searchBuffer = '';
13
+ this.scrollTop = 0;
14
+ this.pageSize = 7;
15
+ // Custom render to handle variable height clearing
16
+ this.lastRenderHeight = 0;
17
+ // Find first non-separator index
18
+ this.selectedIndex = this.findNextSelectableIndex(-1, 1);
19
+ }
20
+ isSeparator(item) {
21
+ return item && item.separator === true;
22
+ }
23
+ findNextSelectableIndex(currentIndex, direction) {
24
+ let nextIndex = currentIndex + direction;
25
+ const choices = this.getFilteredChoices();
26
+ // Loop around logic
27
+ if (nextIndex < 0)
28
+ nextIndex = choices.length - 1;
29
+ if (nextIndex >= choices.length)
30
+ nextIndex = 0;
31
+ if (choices.length === 0)
32
+ return 0;
33
+ // Safety check to prevent infinite loop if all are separators (shouldn't happen in practice)
34
+ let count = 0;
35
+ while (this.isSeparator(choices[nextIndex]) && count < choices.length) {
36
+ nextIndex += direction;
37
+ if (nextIndex < 0)
38
+ nextIndex = choices.length - 1;
39
+ if (nextIndex >= choices.length)
40
+ nextIndex = 0;
41
+ count++;
42
+ }
43
+ return nextIndex;
44
+ }
45
+ getFilteredChoices() {
46
+ if (!this.searchBuffer)
47
+ return this.options.choices;
48
+ return this.options.choices.filter(c => {
49
+ if (this.isSeparator(c))
50
+ return false; // Hide separators when searching
51
+ return c.title.toLowerCase().includes(this.searchBuffer.toLowerCase());
52
+ });
53
+ }
54
+ renderWrapper(firstRender) {
55
+ if (!firstRender && this.lastRenderHeight > 0) {
56
+ this.print(`\x1b[${this.lastRenderHeight}A`);
57
+ }
58
+ let output = '';
59
+ const choices = this.getFilteredChoices();
60
+ // Adjust Scroll Top
61
+ if (this.selectedIndex < this.scrollTop) {
62
+ this.scrollTop = this.selectedIndex;
63
+ }
64
+ else if (this.selectedIndex >= this.scrollTop + this.pageSize) {
65
+ this.scrollTop = this.selectedIndex - this.pageSize + 1;
66
+ }
67
+ // Handle Filtering Edge Case: if list shrinks, scrollTop might be too high
68
+ if (this.scrollTop > choices.length - 1) {
69
+ this.scrollTop = Math.max(0, choices.length - this.pageSize);
70
+ }
71
+ // Header
72
+ const searchStr = this.searchBuffer ? ` ${theme_1.theme.muted}(Filter: ${this.searchBuffer})${ansi_1.ANSI.RESET}` : '';
73
+ output += `${ansi_1.ANSI.ERASE_LINE}${ansi_1.ANSI.CURSOR_LEFT}${theme_1.theme.success}?${ansi_1.ANSI.RESET} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}${searchStr}\n`;
74
+ if (choices.length === 0) {
75
+ output += `${ansi_1.ANSI.ERASE_LINE}${ansi_1.ANSI.CURSOR_LEFT} ${theme_1.theme.muted}No results found${ansi_1.ANSI.RESET}\n`;
76
+ }
77
+ else {
78
+ const visibleChoices = choices.slice(this.scrollTop, this.scrollTop + this.pageSize);
79
+ visibleChoices.forEach((choice, index) => {
80
+ const actualIndex = this.scrollTop + index;
81
+ output += `${ansi_1.ANSI.ERASE_LINE}${ansi_1.ANSI.CURSOR_LEFT}`;
82
+ if (this.isSeparator(choice)) {
83
+ output += ` ${ansi_1.ANSI.DIM}${choice.text || '────────'}${ansi_1.ANSI.RESET}\n`;
84
+ }
85
+ else {
86
+ if (actualIndex === this.selectedIndex) {
87
+ output += `${theme_1.theme.main}❯ ${choice.title}${ansi_1.ANSI.RESET}\n`;
88
+ }
89
+ else {
90
+ output += ` ${choice.title}\n`;
91
+ }
92
+ }
93
+ });
94
+ }
95
+ this.print(output);
96
+ // Clear remaining lines if list shrunk
97
+ const visibleCount = Math.min(choices.length, this.pageSize);
98
+ const currentHeight = visibleCount + 1 + (choices.length === 0 ? 1 : 0);
99
+ const linesToClear = this.lastRenderHeight - currentHeight;
100
+ if (linesToClear > 0) {
101
+ for (let i = 0; i < linesToClear; i++) {
102
+ this.print(`${ansi_1.ANSI.ERASE_LINE}\n`);
103
+ }
104
+ this.print(`\x1b[${linesToClear}A`); // Move back up
105
+ }
106
+ this.lastRenderHeight = currentHeight;
107
+ }
108
+ render(firstRender) {
109
+ this.print(ansi_1.ANSI.HIDE_CURSOR);
110
+ this.renderWrapper(firstRender);
111
+ }
112
+ handleInput(char) {
113
+ const choices = this.getFilteredChoices();
114
+ if (char === '\r' || char === '\n') {
115
+ if (choices.length === 0) {
116
+ this.searchBuffer = '';
117
+ this.selectedIndex = this.findNextSelectableIndex(-1, 1);
118
+ this.render(false);
119
+ return;
120
+ }
121
+ if (this.isSeparator(choices[this.selectedIndex]))
122
+ return;
123
+ this.cleanup();
124
+ this.print(ansi_1.ANSI.SHOW_CURSOR);
125
+ if (this._resolve)
126
+ this._resolve(choices[this.selectedIndex].value);
127
+ return;
128
+ }
129
+ if (this.isUp(char)) { // Up
130
+ if (choices.length > 0) {
131
+ this.selectedIndex = this.findNextSelectableIndex(this.selectedIndex, -1);
132
+ this.render(false);
133
+ }
134
+ return;
135
+ }
136
+ if (this.isDown(char)) { // Down
137
+ if (choices.length > 0) {
138
+ this.selectedIndex = this.findNextSelectableIndex(this.selectedIndex, 1);
139
+ this.render(false);
140
+ }
141
+ return;
142
+ }
143
+ // Backspace
144
+ if (char === '\u0008' || char === '\x7f') {
145
+ if (this.searchBuffer.length > 0) {
146
+ this.searchBuffer = this.searchBuffer.slice(0, -1);
147
+ this.selectedIndex = 0; // Reset selection
148
+ this.selectedIndex = this.findNextSelectableIndex(-1, 1);
149
+ this.render(false);
150
+ }
151
+ return;
152
+ }
153
+ // Typing
154
+ if (char.length === 1 && !/^[\x00-\x1F]/.test(char)) {
155
+ this.searchBuffer += char;
156
+ this.selectedIndex = 0; // Reset selection
157
+ this.selectedIndex = this.findNextSelectableIndex(-1, 1);
158
+ this.render(false);
159
+ }
160
+ }
161
+ }
162
+ exports.SelectPrompt = SelectPrompt;
@@ -0,0 +1,7 @@
1
+ import { Prompt } from '../base';
2
+ import { SliderOptions } from '../types';
3
+ export declare class SliderPrompt extends Prompt<number, SliderOptions> {
4
+ constructor(options: SliderOptions);
5
+ protected render(firstRender: boolean): void;
6
+ protected handleInput(char: string): void;
7
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SliderPrompt = void 0;
4
+ const ansi_1 = require("../ansi");
5
+ const base_1 = require("../base");
6
+ const theme_1 = require("../theme");
7
+ // --- Implementation: Slider Prompt ---
8
+ class SliderPrompt extends base_1.Prompt {
9
+ constructor(options) {
10
+ super(options);
11
+ this.value = options.initial ?? options.min;
12
+ }
13
+ render(firstRender) {
14
+ this.print(ansi_1.ANSI.HIDE_CURSOR);
15
+ if (!firstRender) {
16
+ this.print(ansi_1.ANSI.ERASE_LINE + ansi_1.ANSI.CURSOR_LEFT);
17
+ }
18
+ const width = 20;
19
+ const range = this.options.max - this.options.min;
20
+ const ratio = (this.value - this.options.min) / range;
21
+ const pos = Math.round(ratio * width);
22
+ let bar = '';
23
+ for (let i = 0; i <= width; i++) {
24
+ if (i === pos)
25
+ bar += `${theme_1.theme.main}O${ansi_1.ANSI.RESET}`;
26
+ else
27
+ bar += '─';
28
+ }
29
+ const unit = this.options.unit || '';
30
+ this.print(`${theme_1.theme.success}?${ansi_1.ANSI.RESET} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET} [${bar}] ${this.value}${unit}`);
31
+ }
32
+ handleInput(char) {
33
+ if (char === '\r' || char === '\n') {
34
+ this.submit(this.value);
35
+ return;
36
+ }
37
+ const step = this.options.step || 1;
38
+ if (this.isLeft(char)) { // Left
39
+ this.value = Math.max(this.options.min, this.value - step);
40
+ this.render(false);
41
+ }
42
+ if (this.isRight(char)) { // Right
43
+ this.value = Math.min(this.options.max, this.value + step);
44
+ this.render(false);
45
+ }
46
+ }
47
+ }
48
+ exports.SliderPrompt = SliderPrompt;
@@ -0,0 +1,12 @@
1
+ import { Prompt } from '../base';
2
+ import { TextOptions } from '../types';
3
+ export declare class TextPrompt extends Prompt<string, TextOptions> {
4
+ private errorMsg;
5
+ private cursor;
6
+ private hasTyped;
7
+ private renderLines;
8
+ constructor(options: TextOptions);
9
+ protected render(firstRender: boolean): void;
10
+ protected handleInput(char: string): void;
11
+ private validateAndSubmit;
12
+ }