@nbtca/prompt 1.0.8 → 1.0.13

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 (71) hide show
  1. package/README.md +16 -289
  2. package/dist/config/data.d.ts +1 -1
  3. package/dist/config/data.js +1 -1
  4. package/dist/config/data.js.map +1 -1
  5. package/dist/core/logo.d.ts.map +1 -1
  6. package/dist/core/logo.js +13 -2
  7. package/dist/core/logo.js.map +1 -1
  8. package/dist/core/menu.d.ts +5 -0
  9. package/dist/core/menu.d.ts.map +1 -1
  10. package/dist/core/menu.js +12 -5
  11. package/dist/core/menu.js.map +1 -1
  12. package/dist/core/ui.d.ts.map +1 -1
  13. package/dist/core/ui.js +5 -3
  14. package/dist/core/ui.js.map +1 -1
  15. package/dist/features/calendar.d.ts +13 -14
  16. package/dist/features/calendar.d.ts.map +1 -1
  17. package/dist/features/calendar.js +57 -59
  18. package/dist/features/calendar.js.map +1 -1
  19. package/dist/features/docs.d.ts.map +1 -1
  20. package/dist/features/docs.js +50 -47
  21. package/dist/features/docs.js.map +1 -1
  22. package/dist/features/repair.d.ts +4 -0
  23. package/dist/features/repair.d.ts.map +1 -1
  24. package/dist/features/repair.js +1 -1
  25. package/dist/features/repair.js.map +1 -1
  26. package/dist/features/website.d.ts +10 -0
  27. package/dist/features/website.d.ts.map +1 -1
  28. package/dist/features/website.js +14 -2
  29. package/dist/features/website.js.map +1 -1
  30. package/dist/i18n/index.d.ts +9 -0
  31. package/dist/i18n/index.d.ts.map +1 -1
  32. package/dist/i18n/index.js.map +1 -1
  33. package/dist/i18n/locales/en.json +10 -1
  34. package/dist/i18n/locales/zh.json +10 -1
  35. package/dist/index.d.ts +1 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +133 -4
  38. package/dist/index.js.map +1 -1
  39. package/dist/main.d.ts +4 -1
  40. package/dist/main.d.ts.map +1 -1
  41. package/dist/main.js +7 -3
  42. package/dist/main.js.map +1 -1
  43. package/package.json +8 -2
  44. package/.github/workflows/ci.yml +0 -40
  45. package/.github/workflows/publish.yml +0 -59
  46. package/CHANGELOG.md +0 -125
  47. package/DEVELOPMENT.md +0 -258
  48. package/TERMINAL_UX.md +0 -184
  49. package/assets/Prompt_demo.gif +0 -0
  50. package/src/config/data.js +0 -484
  51. package/src/config/data.ts +0 -28
  52. package/src/config/theme.js +0 -138
  53. package/src/config/theme.ts +0 -26
  54. package/src/core/logo.ts +0 -189
  55. package/src/core/menu.ts +0 -213
  56. package/src/core/ui.ts +0 -89
  57. package/src/core/vim-keys.ts +0 -70
  58. package/src/features/calendar.ts +0 -161
  59. package/src/features/docs.ts +0 -588
  60. package/src/features/repair.ts +0 -36
  61. package/src/features/website.ts +0 -45
  62. package/src/i18n/index.ts +0 -236
  63. package/src/i18n/locales/en.json +0 -107
  64. package/src/i18n/locales/zh.json +0 -107
  65. package/src/index.ts +0 -9
  66. package/src/logo/ascii-logo.txt +0 -6
  67. package/src/logo/logo.txt +0 -2
  68. package/src/logo/printLogo.js +0 -26
  69. package/src/main.ts +0 -45
  70. package/src/types.ts +0 -51
  71. package/tsconfig.json +0 -53
package/src/core/logo.ts DELETED
@@ -1,189 +0,0 @@
1
- /**
2
- * Smart logo display module
3
- * Attempts to display iTerm2 image format logo, falls back to ASCII art
4
- */
5
-
6
- import { readFileSync } from 'fs';
7
- import { fileURLToPath } from 'url';
8
- import { dirname, join } from 'path';
9
- import gradient from 'gradient-string';
10
-
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = dirname(__filename);
13
-
14
- /**
15
- * Create blue-toned gradient effect
16
- */
17
- function createBlueGradient(text: string): string {
18
- // Blue gradient: deep blue -> sky blue -> cyan
19
- const blueGradient = gradient([
20
- { color: '#1e3a8a', pos: 0 }, // Deep blue
21
- { color: '#0ea5e9', pos: 0.5 }, // Sky blue
22
- { color: '#06b6d4', pos: 1 } // Cyan
23
- ]);
24
- return blueGradient(text);
25
- }
26
-
27
- /**
28
- * Convert hex color to RGB
29
- */
30
- function hexToRgb(hex: string): [number, number, number] {
31
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
32
- return result
33
- ? [parseInt(result[1]!, 16), parseInt(result[2]!, 16), parseInt(result[3]!, 16)]
34
- : [0, 0, 0];
35
- }
36
-
37
- /**
38
- * Convert RGB to hex color
39
- */
40
- function rgbToHex(r: number, g: number, b: number): string {
41
- return '#' + [r, g, b].map(x => {
42
- const hex = Math.round(x).toString(16);
43
- return hex.length === 1 ? '0' + hex : hex;
44
- }).join('');
45
- }
46
-
47
- /**
48
- * Linear interpolation between two colors
49
- */
50
- function interpolateColor(color1: string, color2: string, factor: number): string {
51
- const [r1, g1, b1] = hexToRgb(color1);
52
- const [r2, g2, b2] = hexToRgb(color2);
53
-
54
- const r = r1 + (r2 - r1) * factor;
55
- const g = g1 + (g2 - g1) * factor;
56
- const b = b1 + (b2 - b1) * factor;
57
-
58
- return rgbToHex(r, g, b);
59
- }
60
-
61
- /**
62
- * Easing function - smooth in-out effect
63
- */
64
- function easeInOutSine(t: number): number {
65
- return -(Math.cos(Math.PI * t) - 1) / 2;
66
- }
67
-
68
- /**
69
- * Display gradient animation effect (optimized - truly smooth animation)
70
- */
71
- async function animateGradient(text: string, duration: number = 1200): Promise<void> {
72
- const frames = 60; // 60 frames for truly smooth animation
73
- const frameDelay = duration / frames;
74
-
75
- // Define color sequence - forms complete blue spectrum cycle
76
- const colorSequence = [
77
- '#1e3a8a', // Deep blue
78
- '#2563eb', // Blue
79
- '#3b82f6', // Bright blue
80
- '#0ea5e9', // Sky blue
81
- '#06b6d4', // Cyan
82
- '#14b8a6', // Teal
83
- '#06b6d4', // Cyan
84
- '#0ea5e9', // Sky blue
85
- '#3b82f6', // Bright blue
86
- '#2563eb', // Blue
87
- '#1e3a8a', // Deep blue
88
- ];
89
-
90
- for (let i = 0; i < frames; i++) {
91
- // Use smooth sine easing
92
- const progress = easeInOutSine(i / frames);
93
-
94
- // Calculate position in color sequence
95
- const position = progress * (colorSequence.length - 1);
96
- const index1 = Math.floor(position);
97
- const index2 = Math.min(index1 + 1, colorSequence.length - 1);
98
- const localProgress = position - index1;
99
-
100
- // Interpolate between adjacent colors, generating three smoothly transitioning colors
101
- const color1 = interpolateColor(
102
- colorSequence[index1]!,
103
- colorSequence[index2]!,
104
- localProgress
105
- );
106
-
107
- const nextIndex1 = Math.min(index2, colorSequence.length - 1);
108
- const nextIndex2 = Math.min(nextIndex1 + 1, colorSequence.length - 1);
109
- const color2 = interpolateColor(
110
- colorSequence[nextIndex1]!,
111
- colorSequence[nextIndex2]!,
112
- localProgress
113
- );
114
-
115
- const nextIndex3 = Math.min(nextIndex2, colorSequence.length - 1);
116
- const nextIndex4 = Math.min(nextIndex3 + 1, colorSequence.length - 1);
117
- const color3 = interpolateColor(
118
- colorSequence[nextIndex3]!,
119
- colorSequence[nextIndex4]!,
120
- localProgress
121
- );
122
-
123
- // Create gradient for current frame
124
- const frameGradient = gradient(color1, color2, color3);
125
-
126
- // Clear current line and display new frame
127
- process.stdout.write('\r' + frameGradient(text));
128
-
129
- await new Promise(resolve => setTimeout(resolve, frameDelay));
130
- }
131
-
132
- // Finally display static blue gradient
133
- process.stdout.write('\r' + createBlueGradient(text) + '\n');
134
- }
135
-
136
- /**
137
- * Attempt to read and display logo file
138
- */
139
- export async function printLogo(): Promise<void> {
140
- try {
141
- // Try to read iTerm2 image format logo
142
- const logoPath = join(__dirname, '../logo/logo.txt');
143
- const logoContent = readFileSync(logoPath, 'utf-8');
144
-
145
- // If successfully read and content is valid, display directly
146
- if (logoContent && logoContent.length > 100) {
147
- console.log(logoContent);
148
- await printDescription();
149
- return;
150
- }
151
- } catch (error) {
152
- // iTerm2 logo read failed, continue trying ASCII logo
153
- }
154
-
155
- // Fallback: display ASCII art logo
156
- try {
157
- const asciiLogoPath = join(__dirname, '../logo/ascii-logo.txt');
158
- const asciiContent = readFileSync(asciiLogoPath, 'utf-8');
159
-
160
- // Display ASCII logo with gradient colors
161
- console.log();
162
- const lines = asciiContent.split('\n').filter(line => line.trim());
163
- lines.forEach(line => {
164
- console.log(createBlueGradient(line));
165
- });
166
-
167
- await printDescription();
168
- } catch (error) {
169
- // If ASCII logo also fails, display simple text logo
170
- console.log();
171
- console.log(createBlueGradient(' NBTCA'));
172
- await printDescription();
173
- }
174
- }
175
-
176
- /**
177
- * Display description text (with gradient animation)
178
- */
179
- async function printDescription(): Promise<void> {
180
- const tagline = 'To be at the intersection of technology and liberal arts.';
181
-
182
- console.log();
183
-
184
- // Display gradient animation
185
- await animateGradient(tagline, 1500);
186
-
187
- console.log();
188
- }
189
-
package/src/core/menu.ts DELETED
@@ -1,213 +0,0 @@
1
- /**
2
- * Minimalist menu system
3
- * Six core feature menus
4
- */
5
-
6
- import inquirer from 'inquirer';
7
- import chalk from 'chalk';
8
- import { showCalendar } from '../features/calendar.js';
9
- import { openRepairService } from '../features/repair.js';
10
- import { showDocsMenu } from '../features/docs.js';
11
- import { openHomepage, openGithub } from '../features/website.js';
12
- import { printDivider, printNewLine } from './ui.js';
13
- import { APP_INFO, URLS } from '../config/data.js';
14
- import { t, getCurrentLanguage, setLanguage, clearTranslationCache, type Language } from '../i18n/index.js';
15
-
16
- /**
17
- * Get main menu options
18
- */
19
- function getMainMenuOptions() {
20
- const trans = t();
21
- return [
22
- {
23
- name: '[*] ' + trans.menu.events.padEnd(16) + ' ' + chalk.gray(trans.menu.eventsDesc),
24
- value: 'events',
25
- short: trans.menu.events
26
- },
27
- {
28
- name: '[*] ' + trans.menu.repair.padEnd(16) + ' ' + chalk.gray(trans.menu.repairDesc),
29
- value: 'repair',
30
- short: trans.menu.repair
31
- },
32
- {
33
- name: '[*] ' + trans.menu.docs.padEnd(16) + ' ' + chalk.gray(trans.menu.docsDesc),
34
- value: 'docs',
35
- short: trans.menu.docs
36
- },
37
- {
38
- name: '[*] ' + trans.menu.website.padEnd(16) + ' ' + chalk.gray(trans.menu.websiteDesc),
39
- value: 'website',
40
- short: trans.menu.website
41
- },
42
- {
43
- name: '[*] ' + trans.menu.github.padEnd(16) + ' ' + chalk.gray(trans.menu.githubDesc),
44
- value: 'github',
45
- short: trans.menu.github
46
- },
47
- {
48
- name: '[?] ' + trans.menu.about.padEnd(16) + ' ' + chalk.gray(trans.menu.aboutDesc),
49
- value: 'about',
50
- short: trans.menu.about
51
- },
52
- {
53
- name: '[⚙] ' + trans.menu.language.padEnd(16) + ' ' + chalk.gray(trans.menu.languageDesc),
54
- value: 'language',
55
- short: trans.menu.language
56
- },
57
- new inquirer.Separator(' '),
58
- {
59
- name: chalk.dim('[x] ' + trans.common.exit),
60
- value: 'exit',
61
- short: trans.common.exit
62
- }
63
- ];
64
- }
65
-
66
- /**
67
- * Display main menu
68
- */
69
- export async function showMainMenu(): Promise<void> {
70
- while (true) {
71
- try {
72
- const trans = t();
73
-
74
- // Show keybinding hints
75
- console.log(chalk.dim(' ' + trans.menu.navigationHint));
76
- console.log();
77
-
78
- const { action } = await inquirer.prompt<{ action: string }>([
79
- {
80
- type: 'list',
81
- name: 'action',
82
- message: trans.menu.chooseAction,
83
- choices: getMainMenuOptions(),
84
- pageSize: 15,
85
- loop: false
86
- } as any
87
- ]);
88
-
89
- // Handle user selection
90
- if (action === 'exit') {
91
- console.log();
92
- console.log(chalk.dim(trans.common.goodbye));
93
- process.exit(0);
94
- }
95
-
96
- await handleAction(action);
97
-
98
- // Show divider after operation
99
- printNewLine();
100
- printDivider();
101
- printNewLine();
102
- } catch (err: any) {
103
- // Handle Ctrl+C exit
104
- if (err.message?.includes('User force closed')) {
105
- console.log();
106
- console.log(chalk.dim(t().common.goodbye));
107
- process.exit(0);
108
- }
109
- throw err;
110
- }
111
- }
112
- }
113
-
114
- /**
115
- * Handle user action
116
- */
117
- async function handleAction(action: string): Promise<void> {
118
- switch (action) {
119
- case 'events':
120
- await showCalendar();
121
- break;
122
-
123
- case 'repair':
124
- await openRepairService();
125
- break;
126
-
127
- case 'docs':
128
- await showDocsMenu();
129
- break;
130
-
131
- case 'website':
132
- await openHomepage();
133
- break;
134
-
135
- case 'github':
136
- await openGithub();
137
- break;
138
-
139
- case 'about':
140
- showAbout();
141
- break;
142
-
143
- case 'language':
144
- await showLanguageMenu();
145
- break;
146
-
147
- default:
148
- console.log(chalk.gray('Unknown action'));
149
- }
150
- }
151
-
152
- /**
153
- * Display about information
154
- */
155
- function showAbout(): void {
156
- const trans = t();
157
- console.log();
158
- console.log(chalk.bold('>> ' + trans.about.title));
159
- console.log();
160
- console.log(chalk.dim(trans.about.project.padEnd(12)) + APP_INFO.name);
161
- console.log(chalk.dim(trans.about.version.padEnd(12)) + `v${APP_INFO.version}`);
162
- console.log(chalk.dim(trans.about.description.padEnd(12)) + APP_INFO.fullDescription);
163
- console.log();
164
- console.log(chalk.dim(trans.about.github.padEnd(12)) + chalk.cyan(APP_INFO.repository));
165
- console.log(chalk.dim(trans.about.website.padEnd(12)) + chalk.cyan(URLS.homepage));
166
- console.log(chalk.dim(trans.about.email.padEnd(12)) + chalk.cyan(URLS.email));
167
- console.log();
168
- console.log(chalk.dim(trans.about.features));
169
- console.log(' ' + trans.about.feature1);
170
- console.log(' ' + trans.about.feature2);
171
- console.log(' ' + trans.about.feature3);
172
- console.log(' ' + trans.about.feature4);
173
- console.log();
174
- console.log(chalk.dim(trans.about.license.padEnd(12)) + 'MIT License');
175
- console.log(chalk.dim(trans.about.author.padEnd(12)) + 'm1ngsama');
176
- console.log();
177
- }
178
-
179
- /**
180
- * Display language selection menu
181
- */
182
- async function showLanguageMenu(): Promise<void> {
183
- const trans = t();
184
- const currentLang = getCurrentLanguage();
185
-
186
- console.log();
187
- console.log(chalk.bold('>> ' + trans.language.title));
188
- console.log();
189
- console.log(chalk.dim(trans.language.currentLanguage + ': ') + chalk.cyan(trans.language[currentLang]));
190
- console.log();
191
-
192
- const { language } = await inquirer.prompt<{ language: Language }>([
193
- {
194
- type: 'list',
195
- name: 'language',
196
- message: trans.language.selectLanguage,
197
- choices: [
198
- { name: trans.language.zh, value: 'zh' as Language },
199
- { name: trans.language.en, value: 'en' as Language }
200
- ],
201
- default: currentLang
202
- }
203
- ]);
204
-
205
- if (language !== currentLang) {
206
- setLanguage(language);
207
- clearTranslationCache();
208
- console.log();
209
- console.log(chalk.green('✓ ' + t().language.changed));
210
- console.log();
211
- }
212
- }
213
-
package/src/core/ui.ts DELETED
@@ -1,89 +0,0 @@
1
- /**
2
- * Minimalist UI component library
3
- * Provides basic terminal UI components
4
- */
5
-
6
- import chalk from 'chalk';
7
-
8
- /**
9
- * Display header title
10
- */
11
- export function printHeader(title: string): void {
12
- console.log(chalk.dim(title));
13
- console.log();
14
- }
15
-
16
- /**
17
- * Display divider line
18
- */
19
- export function printDivider(): void {
20
- const terminalWidth = process.stdout.columns || 80;
21
- console.log(chalk.dim('─'.repeat(Math.min(terminalWidth, 80))));
22
- }
23
-
24
- /**
25
- * Display loading spinner
26
- */
27
- export async function showSpinner(text: string, duration: number): Promise<void> {
28
- const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
29
- let i = 0;
30
- const startTime = Date.now();
31
-
32
- return new Promise((resolve) => {
33
- const interval = setInterval(() => {
34
- process.stdout.write(`\r${chalk.cyan(frames[i])} ${text}`);
35
- i = (i + 1) % frames.length;
36
-
37
- if (Date.now() - startTime >= duration) {
38
- clearInterval(interval);
39
- process.stdout.write('\r' + ' '.repeat(text.length + 5) + '\r');
40
- resolve();
41
- }
42
- }, 80);
43
- });
44
- }
45
-
46
- /**
47
- * Display success message
48
- */
49
- export function success(msg: string): void {
50
- console.log(chalk.green('[✓]') + ' ' + msg);
51
- }
52
-
53
- /**
54
- * Display error message
55
- */
56
- export function error(msg: string): void {
57
- console.log(chalk.red('[✗]') + ' ' + msg);
58
- }
59
-
60
- /**
61
- * Display info message
62
- */
63
- export function info(msg: string): void {
64
- console.log(chalk.blue('[ℹ]') + ' ' + msg);
65
- }
66
-
67
- /**
68
- * Display warning message
69
- */
70
- export function warning(msg: string): void {
71
- console.log(chalk.yellow('[⚠]') + ' ' + msg);
72
- }
73
-
74
- /**
75
- * Clear screen
76
- */
77
- export function clearScreen(): void {
78
- console.clear();
79
- }
80
-
81
- /**
82
- * Print empty lines
83
- */
84
- export function printNewLine(count: number = 1): void {
85
- for (let i = 0; i < count; i++) {
86
- console.log();
87
- }
88
- }
89
-
@@ -1,70 +0,0 @@
1
- /**
2
- * Vim keybindings support
3
- * Intercepts and translates keyboard input for j/k/g/G/q/ESC keys
4
- */
5
-
6
- /**
7
- * Enable Vim key mappings for stdin
8
- * Maps: j/k (down/up), g/G (home/end), q (quit), ESC (back)
9
- */
10
- export function enableVimKeys() {
11
- const stdin = process.stdin;
12
-
13
- // Only enable for TTY sessions
14
- if (!stdin.isTTY) {
15
- return;
16
- }
17
-
18
- // Save original input handler
19
- const originalEmit = stdin.emit.bind(stdin);
20
-
21
- // Override emit method to intercept keyboard events
22
- (stdin.emit as any) = function (event: string, ...args: any[]) {
23
- if (event === 'keypress') {
24
- const [, key] = args;
25
-
26
- if (key && key.name) {
27
- // j = down (mapped to down arrow)
28
- if (key.name === 'j' && !key.ctrl && !key.meta) {
29
- return originalEmit('keypress', null, { name: 'down' });
30
- }
31
-
32
- // k = up (mapped to up arrow)
33
- if (key.name === 'k' && !key.ctrl && !key.meta) {
34
- return originalEmit('keypress', null, { name: 'up' });
35
- }
36
-
37
- // g = jump to top (mapped to home)
38
- if (key.name === 'g' && !key.shift && !key.ctrl && !key.meta) {
39
- return originalEmit('keypress', null, { name: 'home' });
40
- }
41
-
42
- // G (Shift+g) = jump to bottom (mapped to end)
43
- if (key.name === 'g' && key.shift) {
44
- return originalEmit('keypress', null, { name: 'end' });
45
- }
46
-
47
- // ESC = back/cancel (pass through for menu handling)
48
- // Note: Applications should implement back navigation for ESC
49
- if (key.name === 'escape') {
50
- return originalEmit('keypress', null, { name: 'escape', sequence: '\x1b' });
51
- }
52
-
53
- // q = quit (mapped to Ctrl+C for application exit)
54
- if (key.name === 'q' && !key.ctrl && !key.meta) {
55
- return originalEmit('keypress', null, { name: 'c', ctrl: true });
56
- }
57
- }
58
- }
59
-
60
- return originalEmit(event, ...args);
61
- };
62
- }
63
-
64
- /**
65
- * Disable Vim key mappings
66
- * Currently not implemented as we use Vim keys throughout the application
67
- */
68
- export function disableVimKeys() {
69
- // Not needed for current implementation
70
- }