mepcli 0.6.1 → 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +512 -326
  3. package/dist/ansi.d.ts +8 -0
  4. package/dist/ansi.js +8 -0
  5. package/dist/base.d.ts +21 -0
  6. package/dist/base.js +57 -0
  7. package/dist/core.d.ts +48 -1
  8. package/dist/core.js +156 -0
  9. package/dist/data/licenses.d.ts +2 -0
  10. package/dist/data/licenses.js +109 -0
  11. package/dist/highlight.js +58 -26
  12. package/dist/index.d.ts +36 -0
  13. package/dist/index.js +36 -0
  14. package/dist/input.js +0 -3
  15. package/dist/prompts/box.d.ts +21 -0
  16. package/dist/prompts/box.js +192 -0
  17. package/dist/prompts/breadcrumb.d.ts +22 -0
  18. package/dist/prompts/breadcrumb.js +302 -0
  19. package/dist/prompts/byte.d.ts +13 -0
  20. package/dist/prompts/byte.js +159 -0
  21. package/dist/prompts/calculator.d.ts +16 -0
  22. package/dist/prompts/calculator.js +213 -0
  23. package/dist/prompts/calendar.js +0 -5
  24. package/dist/prompts/code.d.ts +2 -0
  25. package/dist/prompts/code.js +104 -70
  26. package/dist/prompts/connection-string.d.ts +18 -0
  27. package/dist/prompts/connection-string.js +97 -0
  28. package/dist/prompts/curl.d.ts +39 -0
  29. package/dist/prompts/curl.js +285 -0
  30. package/dist/prompts/data-inspector.d.ts +22 -0
  31. package/dist/prompts/data-inspector.js +256 -0
  32. package/dist/prompts/dependency.d.ts +16 -0
  33. package/dist/prompts/dependency.js +265 -0
  34. package/dist/prompts/dial.d.ts +10 -0
  35. package/dist/prompts/dial.js +110 -0
  36. package/dist/prompts/diff.d.ts +10 -0
  37. package/dist/prompts/diff.js +101 -0
  38. package/dist/prompts/draw.d.ts +20 -0
  39. package/dist/prompts/draw.js +188 -0
  40. package/dist/prompts/editor.js +0 -4
  41. package/dist/prompts/emoji.d.ts +18 -0
  42. package/dist/prompts/emoji.js +228 -0
  43. package/dist/prompts/exec.d.ts +13 -0
  44. package/dist/prompts/exec.js +83 -0
  45. package/dist/prompts/fuzzy.d.ts +12 -0
  46. package/dist/prompts/fuzzy.js +136 -0
  47. package/dist/prompts/gauge.d.ts +21 -0
  48. package/dist/prompts/gauge.js +130 -0
  49. package/dist/prompts/heatmap.d.ts +13 -0
  50. package/dist/prompts/heatmap.js +141 -0
  51. package/dist/prompts/ip.d.ts +11 -0
  52. package/dist/prompts/ip.js +118 -0
  53. package/dist/prompts/kanban.d.ts +17 -0
  54. package/dist/prompts/kanban.js +228 -0
  55. package/dist/prompts/keypress.js +0 -2
  56. package/dist/prompts/license.d.ts +9 -0
  57. package/dist/prompts/license.js +105 -0
  58. package/dist/prompts/map.d.ts +15 -0
  59. package/dist/prompts/map.js +199 -0
  60. package/dist/prompts/match.d.ts +19 -0
  61. package/dist/prompts/match.js +275 -0
  62. package/dist/prompts/miller.d.ts +15 -0
  63. package/dist/prompts/miller.js +221 -0
  64. package/dist/prompts/multi-column-select.d.ts +10 -0
  65. package/dist/prompts/multi-column-select.js +166 -0
  66. package/dist/prompts/number.js +0 -2
  67. package/dist/prompts/otp.d.ts +10 -0
  68. package/dist/prompts/otp.js +91 -0
  69. package/dist/prompts/pattern.d.ts +22 -0
  70. package/dist/prompts/pattern.js +249 -0
  71. package/dist/prompts/quiz-select.d.ts +10 -0
  72. package/dist/prompts/quiz-select.js +104 -0
  73. package/dist/prompts/quiz-text.d.ts +11 -0
  74. package/dist/prompts/quiz-text.js +82 -0
  75. package/dist/prompts/regex.d.ts +13 -0
  76. package/dist/prompts/regex.js +131 -0
  77. package/dist/prompts/region.d.ts +11 -0
  78. package/dist/prompts/region.js +164 -0
  79. package/dist/prompts/schedule.d.ts +18 -0
  80. package/dist/prompts/schedule.js +221 -0
  81. package/dist/prompts/scroll.d.ts +13 -0
  82. package/dist/prompts/scroll.js +152 -0
  83. package/dist/prompts/seat.d.ts +17 -0
  84. package/dist/prompts/seat.js +165 -0
  85. package/dist/prompts/select-range.d.ts +8 -0
  86. package/dist/prompts/select-range.js +136 -0
  87. package/dist/prompts/select.d.ts +9 -9
  88. package/dist/prompts/semver.d.ts +6 -0
  89. package/dist/prompts/semver.js +32 -0
  90. package/dist/prompts/shortcut.d.ts +9 -0
  91. package/dist/prompts/shortcut.js +135 -0
  92. package/dist/prompts/slot.d.ts +16 -0
  93. package/dist/prompts/slot.js +107 -0
  94. package/dist/prompts/snippet.js +0 -3
  95. package/dist/prompts/sort-grid.d.ts +16 -0
  96. package/dist/prompts/sort-grid.js +146 -0
  97. package/dist/prompts/sort.js +0 -1
  98. package/dist/prompts/spreadsheet.d.ts +21 -0
  99. package/dist/prompts/spreadsheet.js +239 -0
  100. package/dist/prompts/text.d.ts +9 -7
  101. package/dist/prompts/text.js +52 -0
  102. package/dist/prompts/time.d.ts +12 -0
  103. package/dist/prompts/time.js +202 -0
  104. package/dist/prompts/tree-select.d.ts +0 -1
  105. package/dist/prompts/tree-select.js +1 -5
  106. package/dist/symbols.d.ts +12 -0
  107. package/dist/symbols.js +14 -2
  108. package/dist/theme.js +10 -1
  109. package/dist/types.d.ts +264 -1
  110. package/dist/utils.d.ts +53 -0
  111. package/dist/utils.js +252 -0
  112. package/package.json +51 -47
  113. package/example.ts +0 -390
package/dist/index.js CHANGED
@@ -20,3 +20,39 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  __exportStar(require("./types"), exports);
22
22
  __exportStar(require("./core"), exports);
23
+ __exportStar(require("./prompts/map"), exports);
24
+ __exportStar(require("./prompts/semver"), exports);
25
+ __exportStar(require("./prompts/ip"), exports);
26
+ __exportStar(require("./prompts/kanban"), exports);
27
+ __exportStar(require("./prompts/time"), exports);
28
+ __exportStar(require("./prompts/heatmap"), exports);
29
+ __exportStar(require("./prompts/byte"), exports);
30
+ __exportStar(require("./prompts/slot"), exports);
31
+ __exportStar(require("./prompts/gauge"), exports);
32
+ __exportStar(require("./prompts/calculator"), exports);
33
+ __exportStar(require("./prompts/emoji"), exports);
34
+ __exportStar(require("./prompts/match"), exports);
35
+ __exportStar(require("./prompts/diff"), exports);
36
+ __exportStar(require("./prompts/dial"), exports);
37
+ __exportStar(require("./prompts/draw"), exports);
38
+ __exportStar(require("./prompts/multi-column-select"), exports);
39
+ __exportStar(require("./prompts/fuzzy"), exports);
40
+ __exportStar(require("./prompts/miller"), exports);
41
+ __exportStar(require("./prompts/pattern"), exports);
42
+ __exportStar(require("./prompts/region"), exports);
43
+ __exportStar(require("./prompts/spreadsheet"), exports);
44
+ __exportStar(require("./prompts/scroll"), exports);
45
+ __exportStar(require("./prompts/breadcrumb"), exports);
46
+ __exportStar(require("./prompts/schedule"), exports);
47
+ __exportStar(require("./prompts/data-inspector"), exports);
48
+ __exportStar(require("./prompts/exec"), exports);
49
+ __exportStar(require("./prompts/shortcut"), exports);
50
+ __exportStar(require("./prompts/seat"), exports);
51
+ __exportStar(require("./prompts/select-range"), exports);
52
+ __exportStar(require("./prompts/sort-grid"), exports);
53
+ __exportStar(require("./prompts/dependency"), exports);
54
+ __exportStar(require("./prompts/license"), exports);
55
+ __exportStar(require("./prompts/regex"), exports);
56
+ __exportStar(require("./prompts/box"), exports);
57
+ __exportStar(require("./prompts/connection-string"), exports);
58
+ __exportStar(require("./prompts/curl"), exports);
package/dist/input.js CHANGED
@@ -146,9 +146,6 @@ class InputParser extends events_1.EventEmitter {
146
146
  // Normalize Enter
147
147
  if (key === '\r')
148
148
  key = '\n';
149
- // We emit both the raw sequence and a normalized representation if needed,
150
- // but existing prompt logic handles raw strings like \x1b[A.
151
- // So we just emit the reconstructed sequence.
152
149
  this.emit('keypress', key, Buffer.from(key));
153
150
  }
154
151
  }
@@ -0,0 +1,21 @@
1
+ import { Prompt } from '../base';
2
+ import { BoxOptions, MouseEvent } from '../types';
3
+ interface BoxValues {
4
+ top: number;
5
+ right: number;
6
+ bottom: number;
7
+ left: number;
8
+ }
9
+ export declare class BoxPrompt extends Prompt<BoxValues, BoxOptions> {
10
+ private values;
11
+ private focus;
12
+ private inputBuffer;
13
+ constructor(options: BoxOptions);
14
+ private commitBuffer;
15
+ private changeFocus;
16
+ private increment;
17
+ protected render(_firstRender: boolean): void;
18
+ protected handleMouse(event: MouseEvent): void;
19
+ protected handleInput(char: string, _key: Buffer): void;
20
+ }
21
+ export {};
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BoxPrompt = void 0;
4
+ const base_1 = require("../base");
5
+ const ansi_1 = require("../ansi");
6
+ const theme_1 = require("../theme");
7
+ class BoxPrompt extends base_1.Prompt {
8
+ constructor(options) {
9
+ super(options);
10
+ this.focus = 'top';
11
+ this.inputBuffer = '';
12
+ const initial = options.initial;
13
+ if (typeof initial === 'number') {
14
+ this.values = { top: initial, right: initial, bottom: initial, left: initial };
15
+ }
16
+ else if (typeof initial === 'object') {
17
+ this.values = {
18
+ top: initial.top ?? 0,
19
+ right: initial.right ?? 0,
20
+ bottom: initial.bottom ?? 0,
21
+ left: initial.left ?? 0
22
+ };
23
+ }
24
+ else {
25
+ this.values = { top: 0, right: 0, bottom: 0, left: 0 };
26
+ }
27
+ this.inputBuffer = this.values.top.toString();
28
+ }
29
+ commitBuffer() {
30
+ let val = parseInt(this.inputBuffer, 10);
31
+ if (isNaN(val))
32
+ val = 0;
33
+ // Apply constraints
34
+ if (this.options.min !== undefined && val < this.options.min)
35
+ val = this.options.min;
36
+ if (this.options.max !== undefined && val > this.options.max)
37
+ val = this.options.max;
38
+ this.values[this.focus] = val;
39
+ this.inputBuffer = val.toString(); // Normalize buffer
40
+ }
41
+ changeFocus(newFocus) {
42
+ this.commitBuffer(); // Save current
43
+ this.focus = newFocus;
44
+ this.inputBuffer = this.values[newFocus].toString();
45
+ }
46
+ increment(amount) {
47
+ let val = parseInt(this.inputBuffer, 10);
48
+ if (isNaN(val))
49
+ val = 0;
50
+ val += amount;
51
+ if (this.options.min !== undefined && val < this.options.min)
52
+ val = this.options.min;
53
+ if (this.options.max !== undefined && val > this.options.max)
54
+ val = this.options.max;
55
+ this.inputBuffer = val.toString();
56
+ }
57
+ render(_firstRender) {
58
+ const title = `${theme_1.theme.success}? ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET} (Arrows to navigate, Numbers to edit)`;
59
+ // Format value function
60
+ const formatVal = (side) => {
61
+ const isFocused = this.focus === side;
62
+ const text = isFocused ? this.inputBuffer : this.values[side].toString();
63
+ if (isFocused) {
64
+ return `${ansi_1.ANSI.FG_CYAN}${ansi_1.ANSI.BOLD}[ ${text} ]${ansi_1.ANSI.RESET}`;
65
+ }
66
+ return ` ${text} `;
67
+ };
68
+ const vTop = formatVal('top');
69
+ const vRight = formatVal('right');
70
+ const vBottom = formatVal('bottom');
71
+ const vLeft = formatVal('left');
72
+ // Layout
73
+ // [ Top ]
74
+ // [ Left ] [ Right ]
75
+ // [ Bottom ]
76
+ // We need to pad to align them nicely.
77
+ // Simple manual padding for MVP.
78
+ // Calculate center padding based on longest string?
79
+ // Keep it simple.
80
+ let output = title + '\n\n';
81
+ // Top Row (Centered)
82
+ output += ` ${vTop}\n`;
83
+ // Middle Row
84
+ output += ` ${vLeft} ${vRight}\n`;
85
+ // Bottom Row
86
+ output += ` ${vBottom}\n`;
87
+ this.renderFrame(output);
88
+ }
89
+ handleMouse(event) {
90
+ if (event.name === 'mouse' && event.action === 'scroll') {
91
+ const order = ['top', 'right', 'bottom', 'left'];
92
+ const idx = order.indexOf(this.focus);
93
+ if (event.scroll === 'down') {
94
+ // Next (Down usually means going forward/down in list)
95
+ this.changeFocus(order[(idx + 1) % 4]);
96
+ }
97
+ else if (event.scroll === 'up') {
98
+ // Previous
99
+ this.changeFocus(order[(idx + 3) % 4]); // +3 is same as -1 in mod 4
100
+ }
101
+ this.render(false);
102
+ }
103
+ }
104
+ handleInput(char, _key) {
105
+ // Enter -> Submit
106
+ if (char === '\r' || char === '\n') {
107
+ this.commitBuffer();
108
+ this.submit(this.values);
109
+ return;
110
+ }
111
+ // Navigation
112
+ if (this.isUp(char)) {
113
+ if (this.focus === 'bottom' || this.focus === 'left' || this.focus === 'right') {
114
+ this.changeFocus('top');
115
+ }
116
+ this.render(false);
117
+ return;
118
+ }
119
+ if (this.isDown(char)) {
120
+ if (this.focus === 'top' || this.focus === 'left' || this.focus === 'right') {
121
+ this.changeFocus('bottom');
122
+ }
123
+ this.render(false);
124
+ return;
125
+ }
126
+ if (this.isLeft(char)) {
127
+ if (this.focus === 'right' || this.focus === 'top' || this.focus === 'bottom') {
128
+ this.changeFocus('left');
129
+ }
130
+ this.render(false);
131
+ return;
132
+ }
133
+ if (this.isRight(char)) {
134
+ if (this.focus === 'left' || this.focus === 'top' || this.focus === 'bottom') {
135
+ this.changeFocus('right');
136
+ }
137
+ this.render(false);
138
+ return;
139
+ }
140
+ // Tab Cycling
141
+ if (char === '\t') {
142
+ const order = ['top', 'right', 'bottom', 'left'];
143
+ const idx = order.indexOf(this.focus);
144
+ this.changeFocus(order[(idx + 1) % 4]);
145
+ this.render(false);
146
+ return;
147
+ }
148
+ // Shift+Tab Cycling (\u001b[Z)
149
+ if (char === '\u001b[Z') {
150
+ const order = ['top', 'right', 'bottom', 'left'];
151
+ const idx = order.indexOf(this.focus);
152
+ this.changeFocus(order[(idx + 3) % 4]); // (idx - 1) % 4 handling negative
153
+ this.render(false);
154
+ return;
155
+ }
156
+ // Increment/Decrement (+ / -)
157
+ const step = this.options.step || 1;
158
+ if (char === '+' || char === '=') { // = is usually unshifted +
159
+ this.increment(step);
160
+ this.render(false);
161
+ return;
162
+ }
163
+ if (char === '-' || char === '_') {
164
+ this.increment(-step);
165
+ this.render(false);
166
+ return;
167
+ }
168
+ // Typing Numbers
169
+ if (/^[0-9]$/.test(char)) {
170
+ // Special case: if buffer is "0", replace it unless we are appending
171
+ if (this.inputBuffer === '0') {
172
+ this.inputBuffer = char;
173
+ }
174
+ else {
175
+ this.inputBuffer += char;
176
+ }
177
+ this.render(false);
178
+ return;
179
+ }
180
+ // Backspace
181
+ if (char === '\u0008' || char === '\x7f') {
182
+ if (this.inputBuffer.length > 0) {
183
+ this.inputBuffer = this.inputBuffer.slice(0, -1);
184
+ if (this.inputBuffer === '')
185
+ this.inputBuffer = '0'; // default to 0
186
+ }
187
+ this.render(false);
188
+ return;
189
+ }
190
+ }
191
+ }
192
+ exports.BoxPrompt = BoxPrompt;
@@ -0,0 +1,22 @@
1
+ import { Prompt } from '../base';
2
+ import { BreadcrumbOptions, MouseEvent } from '../types';
3
+ export declare class BreadcrumbPrompt extends Prompt<string, BreadcrumbOptions> {
4
+ private stack;
5
+ private currentEntries;
6
+ private cursor;
7
+ private scrollTop;
8
+ private root;
9
+ private currentPath;
10
+ private separator;
11
+ private showHidden;
12
+ private isLoading;
13
+ private error;
14
+ private readonly pageSize;
15
+ constructor(options: BreadcrumbOptions);
16
+ private loadDirectory;
17
+ private drillDown;
18
+ private goUp;
19
+ protected render(_firstRender: boolean): void;
20
+ protected handleInput(char: string, _key: Buffer): void;
21
+ protected handleMouse(_event: MouseEvent): void;
22
+ }
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.BreadcrumbPrompt = void 0;
37
+ const base_1 = require("../base");
38
+ const ansi_1 = require("../ansi");
39
+ const theme_1 = require("../theme");
40
+ const symbols_1 = require("../symbols");
41
+ const fs = __importStar(require("fs/promises"));
42
+ const path = __importStar(require("path"));
43
+ class BreadcrumbPrompt extends base_1.Prompt {
44
+ constructor(options) {
45
+ super(options);
46
+ this.stack = [];
47
+ this.currentEntries = [];
48
+ this.cursor = 0;
49
+ this.scrollTop = 0;
50
+ this.isLoading = false;
51
+ this.error = null;
52
+ this.pageSize = 10;
53
+ this.root = path.resolve(options.root || process.cwd());
54
+ this.currentPath = this.root;
55
+ this.separator = options.separator || ' › ';
56
+ this.showHidden = options.showHidden || false;
57
+ this.loadDirectory(this.currentPath);
58
+ }
59
+ async loadDirectory(dir) {
60
+ this.isLoading = true;
61
+ this.error = null;
62
+ this.render(false);
63
+ try {
64
+ await fs.access(dir);
65
+ const dirents = await fs.readdir(dir, { withFileTypes: true });
66
+ let entries = dirents.map(d => ({
67
+ name: d.name,
68
+ isDirectory: d.isDirectory()
69
+ }));
70
+ if (!this.showHidden) {
71
+ entries = entries.filter(e => !e.name.startsWith('.'));
72
+ }
73
+ entries.sort((a, b) => {
74
+ if (a.isDirectory === b.isDirectory) {
75
+ return a.name.localeCompare(b.name);
76
+ }
77
+ return a.isDirectory ? -1 : 1;
78
+ });
79
+ this.currentEntries = entries;
80
+ if (this.currentEntries.length === 0) {
81
+ this.cursor = 0;
82
+ }
83
+ else if (this.cursor >= this.currentEntries.length) {
84
+ this.cursor = this.currentEntries.length - 1;
85
+ }
86
+ }
87
+ catch (err) {
88
+ this.error = err.message || 'Error reading directory';
89
+ this.currentEntries = [];
90
+ }
91
+ finally {
92
+ this.isLoading = false;
93
+ this.render(false);
94
+ }
95
+ }
96
+ async drillDown() {
97
+ const entry = this.currentEntries[this.cursor];
98
+ if (!entry || !entry.isDirectory)
99
+ return;
100
+ const nextPath = path.join(this.currentPath, entry.name);
101
+ this.stack.push({
102
+ path: this.currentPath,
103
+ cursor: this.cursor,
104
+ scrollTop: this.scrollTop
105
+ });
106
+ this.currentPath = nextPath;
107
+ this.cursor = 0;
108
+ this.scrollTop = 0;
109
+ await this.loadDirectory(nextPath);
110
+ }
111
+ async goUp() {
112
+ if (this.stack.length === 0)
113
+ return;
114
+ const prevState = this.stack.pop();
115
+ if (prevState) {
116
+ this.currentPath = prevState.path;
117
+ this.cursor = prevState.cursor;
118
+ this.scrollTop = prevState.scrollTop;
119
+ await this.loadDirectory(this.currentPath);
120
+ }
121
+ }
122
+ render(_firstRender) {
123
+ const width = this.stdout.columns || 80;
124
+ let output = '';
125
+ // --- Breadcrumb Line Construction ---
126
+ const relative = path.relative(this.root, this.currentPath);
127
+ const parts = relative ? relative.split(path.sep) : [];
128
+ const rootName = path.basename(this.root);
129
+ const segments = [rootName, ...parts];
130
+ // Calculate available space for path
131
+ // Prefix: "? Message: "
132
+ const prefix = `${theme_1.theme.success}?${ansi_1.ANSI.RESET} ${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET} `;
133
+ const prefixWidth = this.stripAnsi(prefix).length;
134
+ const availableWidth = Math.max(20, width - prefixWidth - 5); // Reserve 5 chars buffer
135
+ let breadcrumbStr = segments.join(this.separator);
136
+ if (breadcrumbStr.length > availableWidth) {
137
+ // Truncate logic: Keep root and tail segments that fit
138
+ // e.g., root > ... > folder > subfolder
139
+ let suffix = segments[segments.length - 1];
140
+ for (let i = segments.length - 2; i >= 1; i--) { // Stop before root (index 0)
141
+ const next = segments[i] + this.separator + suffix;
142
+ if (next.length + 4 > availableWidth)
143
+ break; // +4 for "... "
144
+ suffix = next;
145
+ }
146
+ breadcrumbStr = `${segments[0]}${this.separator}...${this.separator}${suffix}`;
147
+ // If even that is too long (extreme case), just truncate tail
148
+ if (breadcrumbStr.length > availableWidth) {
149
+ breadcrumbStr = '...' + breadcrumbStr.slice(-(availableWidth - 3));
150
+ }
151
+ }
152
+ output += `${prefix}${breadcrumbStr}\n`;
153
+ // --- Content / List ---
154
+ if (this.isLoading) {
155
+ output += ` ${theme_1.theme.muted}Loading...${ansi_1.ANSI.RESET}`;
156
+ }
157
+ else if (this.error) {
158
+ output += ` ${theme_1.theme.error}${this.error}${ansi_1.ANSI.RESET}`;
159
+ }
160
+ else if (this.currentEntries.length === 0) {
161
+ output += ` ${theme_1.theme.muted}(Empty directory)${ansi_1.ANSI.RESET}\n ${theme_1.theme.muted}(Backspace to go back)${ansi_1.ANSI.RESET}`;
162
+ }
163
+ else {
164
+ // Adjust Scroll Top
165
+ if (this.cursor < this.scrollTop) {
166
+ this.scrollTop = this.cursor;
167
+ }
168
+ else if (this.cursor >= this.scrollTop + this.pageSize) {
169
+ this.scrollTop = this.cursor - this.pageSize + 1;
170
+ }
171
+ // Sanity check
172
+ if (this.scrollTop > this.currentEntries.length - 1) {
173
+ this.scrollTop = Math.max(0, this.currentEntries.length - this.pageSize);
174
+ }
175
+ const visibleEntries = this.currentEntries.slice(this.scrollTop, this.scrollTop + this.pageSize);
176
+ visibleEntries.forEach((entry, index) => {
177
+ const absoluteIndex = this.scrollTop + index;
178
+ const isSelected = absoluteIndex === this.cursor;
179
+ const icon = entry.isDirectory ? '📂' : '📄';
180
+ let line = '';
181
+ if (isSelected) {
182
+ line += `${theme_1.theme.main}${symbols_1.symbols.pointer} ${icon} ${entry.name}${ansi_1.ANSI.RESET}`;
183
+ }
184
+ else {
185
+ line += ` ${icon} ${entry.name}`;
186
+ }
187
+ if (index > 0 || index === 0)
188
+ output += line;
189
+ if (index < visibleEntries.length - 1)
190
+ output += '\n';
191
+ });
192
+ // Add a hint about navigation if plenty of space?
193
+ // Optional: output += `\n${theme.muted}(Use Arrow Keys, Enter to Select, Backspace to Up)${ANSI.RESET}`;
194
+ }
195
+ this.renderFrame(output);
196
+ }
197
+ handleInput(char, _key) {
198
+ if (this.isLoading)
199
+ return;
200
+ // Enter
201
+ if (char === '\r' || char === '\n') {
202
+ if (this.currentEntries.length === 0)
203
+ return;
204
+ const entry = this.currentEntries[this.cursor];
205
+ if (entry.isDirectory) {
206
+ this.drillDown();
207
+ }
208
+ else {
209
+ const fullPath = path.join(this.currentPath, entry.name);
210
+ this.submit(fullPath);
211
+ }
212
+ return;
213
+ }
214
+ // Backspace or Left Arrow
215
+ if (char === '\x7f' || char === '\x08' || this.isLeft(char)) {
216
+ this.goUp();
217
+ return;
218
+ }
219
+ // Right Arrow
220
+ if (this.isRight(char)) {
221
+ const entry = this.currentEntries[this.cursor];
222
+ if (entry && entry.isDirectory) {
223
+ this.drillDown();
224
+ }
225
+ return;
226
+ }
227
+ // Tab (Next)
228
+ if (char === '\t') {
229
+ if (this.currentEntries.length === 0)
230
+ return;
231
+ this.cursor = (this.cursor + 1) % this.currentEntries.length;
232
+ this.render(false);
233
+ return;
234
+ }
235
+ // Shift+Tab (Prev)
236
+ if (char === '\x1b[Z') {
237
+ if (this.currentEntries.length === 0)
238
+ return;
239
+ this.cursor = (this.cursor - 1 + this.currentEntries.length) % this.currentEntries.length;
240
+ this.render(false);
241
+ return;
242
+ }
243
+ // Up
244
+ if (this.isUp(char)) {
245
+ if (this.cursor > 0) {
246
+ this.cursor--;
247
+ this.render(false);
248
+ }
249
+ else if (this.currentEntries.length > 0) {
250
+ // Cycle to bottom?
251
+ this.cursor = this.currentEntries.length - 1;
252
+ this.render(false);
253
+ }
254
+ return;
255
+ }
256
+ // Down
257
+ if (this.isDown(char)) {
258
+ if (this.cursor < this.currentEntries.length - 1) {
259
+ this.cursor++;
260
+ this.render(false);
261
+ }
262
+ else if (this.currentEntries.length > 0) {
263
+ // Cycle to top?
264
+ this.cursor = 0;
265
+ this.render(false);
266
+ }
267
+ return;
268
+ }
269
+ // Page Up
270
+ if (char === '\x1b[5~') {
271
+ this.cursor = Math.max(0, this.cursor - this.pageSize);
272
+ this.render(false);
273
+ return;
274
+ }
275
+ // Page Down
276
+ if (char === '\x1b[6~') {
277
+ this.cursor = Math.min(this.currentEntries.length - 1, this.cursor + this.pageSize);
278
+ this.render(false);
279
+ return;
280
+ }
281
+ }
282
+ handleMouse(_event) {
283
+ // Scroll up and down
284
+ if (this.isLoading)
285
+ return;
286
+ if (_event.action === 'scroll') {
287
+ if (_event.scroll === 'up') {
288
+ if (this.cursor > 0) {
289
+ this.cursor--;
290
+ this.render(false);
291
+ }
292
+ }
293
+ else if (_event.scroll === 'down') {
294
+ if (this.cursor < this.currentEntries.length - 1) {
295
+ this.cursor++;
296
+ this.render(false);
297
+ }
298
+ }
299
+ }
300
+ }
301
+ }
302
+ exports.BreadcrumbPrompt = BreadcrumbPrompt;
@@ -0,0 +1,13 @@
1
+ import { Prompt } from '../base';
2
+ import { ByteOptions, MouseEvent } from '../types';
3
+ export declare class BytePrompt extends Prompt<number, ByteOptions> {
4
+ private inputValue;
5
+ private buffer;
6
+ private unitIndex;
7
+ private errorMsg;
8
+ constructor(options: ByteOptions);
9
+ protected render(_firstRender: boolean): void;
10
+ protected handleInput(char: string): void;
11
+ private formatBytes;
12
+ protected handleMouse(event: MouseEvent): void;
13
+ }