@kikkimo/claude-launcher 2.0.0 → 2.2.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/CHANGELOG.md +112 -0
- package/README.md +9 -6
- package/claude-launcher +57 -3
- package/docs/README-zh.md +9 -6
- package/lib/auth/password-input.js +101 -87
- package/lib/i18n/locales/de.js +17 -2
- package/lib/i18n/locales/en.js +17 -2
- package/lib/i18n/locales/es.js +17 -2
- package/lib/i18n/locales/fr.js +18 -3
- package/lib/i18n/locales/it.js +16 -0
- package/lib/i18n/locales/ja.js +17 -2
- package/lib/i18n/locales/ko.js +17 -2
- package/lib/i18n/locales/pt.js +16 -0
- package/lib/i18n/locales/ru.js +16 -0
- package/lib/i18n/locales/zh-TW.js +17 -2
- package/lib/i18n/locales/zh.js +17 -2
- package/lib/launcher.js +153 -47
- package/lib/presets/providers.js +65 -3
- package/lib/ui/interactive-table.js +102 -24
- package/lib/ui/menu.js +213 -144
- package/lib/ui/prompts.js +116 -85
- package/lib/utils/stdin-manager.js +715 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,118 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.2.0] - 2025-11-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Kimi for Coding Provider**: New specialized provider for coding-focused AI assistance:
|
|
12
|
+
- `kimi_for_coding`: Dedicated endpoint optimized for software development workflows
|
|
13
|
+
- Specialized coding model: `kimi-for-coding` with enhanced code generation capabilities
|
|
14
|
+
- Extended timeout configuration (50 minutes) for large code generation and complex development tasks
|
|
15
|
+
- Anthropic-compatible API interface for seamless integration with existing tooling
|
|
16
|
+
- Consistent configuration patterns mirroring moonshot provider settings
|
|
17
|
+
- **Enhanced Kimi Thinking Models**: Expanded support for Kimi's thinking-capable models:
|
|
18
|
+
- `kimi-k2-thinking`: Standard thinking model for complex reasoning tasks
|
|
19
|
+
- `kimi-k2-thinking-turbo`: Optimized thinking model for faster response times
|
|
20
|
+
- Additional model options for users requiring different performance characteristics
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **Provider Selection Interface**: Updated UI prompts to include new `kimi_for_coding` provider in third-party API selection menu
|
|
24
|
+
- **Provider Configuration**: Extended provider validation logic to properly handle new specialized coding provider
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Provider Recognition**: Fixed provider ID validation to include `kimi_for_coding` in the list of supported providers for third-party API configuration
|
|
28
|
+
|
|
29
|
+
## [2.1.0] - 2025-10-27
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- **GLM (ZhiPu AI) Provider Support**: Full integration for ZhiPu AI's GLM models with two provider options:
|
|
33
|
+
- `zhipu`: For mainland China users (智谱清言)
|
|
34
|
+
- `zai`: For international users (Z.ai Global)
|
|
35
|
+
- Support for GLM-4.5 and GLM-4.6 models
|
|
36
|
+
- Extended timeout configuration (50 minutes) for large response handling
|
|
37
|
+
- Optimized network traffic settings for better performance
|
|
38
|
+
- **Moonshot Provider Enhancements**: Added extended timeout configuration and traffic optimization for Moonshot AI provider
|
|
39
|
+
- **Enhanced Ctrl+C Interaction**: Comprehensive Ctrl+C handling with four distinct scenarios:
|
|
40
|
+
- Basic trigger with warning message display
|
|
41
|
+
- Auto-cancel after 3-second timeout
|
|
42
|
+
- Double Ctrl+C for immediate exit confirmation
|
|
43
|
+
- Any other key press to cancel warning and continue operation
|
|
44
|
+
- **StdinManager Centralized Control**: New singleton class for unified stdin state management:
|
|
45
|
+
- Scope-based stdin acquisition with automatic cleanup
|
|
46
|
+
- Detach/reattach mechanism for proper scope isolation
|
|
47
|
+
- Suspension API for child process coordination
|
|
48
|
+
- Comprehensive Ctrl+C state tracking and handling
|
|
49
|
+
- **Provider-specific Configuration System**: Dynamic provider configuration framework:
|
|
50
|
+
- Flexible environment variable configuration per provider
|
|
51
|
+
- Provider-specific optimization display with validation
|
|
52
|
+
- Internationalized provider notes and recommendations
|
|
53
|
+
- **Complete i18n Coverage**: Extended internationalization support to all supported languages (English, Simplified Chinese, Traditional Chinese, German, French, Spanish, Italian, Portuguese, Japanese, Korean, Russian):
|
|
54
|
+
- Provider optimization messages (timeout, traffic control, custom variables)
|
|
55
|
+
- Provider-specific notes and recommendations
|
|
56
|
+
- Consistent terminology across all supported languages
|
|
57
|
+
- **Automated Test Suites**: Comprehensive test coverage for stdin management:
|
|
58
|
+
- Interactive test scripts for manual validation
|
|
59
|
+
- Automated test scripts for CI/CD integration
|
|
60
|
+
- Test fixture files for isolated testing
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
- **Provider Configuration Architecture**: Refactored from hardcoded switch statements to dynamic config lookup system
|
|
64
|
+
- **Stdin Operations**: Migrated all stdin operations to use centralized StdinManager:
|
|
65
|
+
- Menu navigation
|
|
66
|
+
- Interactive tables
|
|
67
|
+
- Prompt inputs
|
|
68
|
+
- Confirmation dialogs
|
|
69
|
+
- Password input
|
|
70
|
+
- **Console Control Handover**: Redesigned parent-child process coordination:
|
|
71
|
+
- Clean console relinquishment before launching Claude Code
|
|
72
|
+
- Suspension-aware SIGINT handling
|
|
73
|
+
- Proper console restoration after child process exit
|
|
74
|
+
- **Error Handling**: Unified error handling with `handleLaunchFailure` function
|
|
75
|
+
- **Ctrl+C Monitoring**: Disabled during Claude Code subprocess launch to prevent interception conflicts
|
|
76
|
+
- **Test Configuration Files**: Renamed test-config.json to test-config.fixture for better semantic clarity
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
- **Stdin State Management**: Resolved critical hanging issues in CLI interaction:
|
|
80
|
+
- Fixed Promise deadlocks caused by cross-scope listener interference
|
|
81
|
+
- Eliminated dangerous `removeAllListeners` calls that destroyed active listeners
|
|
82
|
+
- Added proper timeout handling (60 seconds) for user input operations
|
|
83
|
+
- Fixed redundant isPaused check that incorrectly tested both property and method
|
|
84
|
+
- **Listener Conflicts**: Prevented stdin listener conflicts between nested scopes:
|
|
85
|
+
- Implemented scope-aware listener management
|
|
86
|
+
- Added detach/reattach pattern for safe scope transitions
|
|
87
|
+
- Tracked active scope for accurate nested scope handling
|
|
88
|
+
- Fixed waitForKey listener removal bug causing Promise hangs on Ctrl+C
|
|
89
|
+
- **Password Input**: Properly cleanup and reject Promise on Ctrl+C to prevent resource leaks
|
|
90
|
+
- **Input Processing**: Fixed consecutive operation hangs (e.g., API switch followed by deletion)
|
|
91
|
+
- **Ctrl+C Reliability**: Enhanced Ctrl+C responsiveness across all interfaces with proper state tracking
|
|
92
|
+
- **Terminal State Cleanup**: Improved stdin cleanup before and after Claude Code launch
|
|
93
|
+
- **Character Encoding**: Replaced mojibake characters (����, ��) with proper Unicode glyphs (↑↓, →) in menu
|
|
94
|
+
- **ANSI Escape Sequences**: Added TTY checks to prevent ANSI codes from polluting non-TTY output (logs, CI/CD)
|
|
95
|
+
- **Global Signal Handlers**: Removed dangerous `removeAllListeners('SIGINT/SIGTERM')` calls that could break other modules
|
|
96
|
+
- **Timeout Display**: Added validation for API_TIMEOUT_MS parsing to prevent NaN display in provider optimizations
|
|
97
|
+
- **Test File Tracking**: Removed incorrect .gitignore rules that prevented test files from being tracked
|
|
98
|
+
- **Code Quality**: Removed unused variables and dead code from test files
|
|
99
|
+
|
|
100
|
+
### Security
|
|
101
|
+
- **Enhanced Secret Masking**: Expanded environment variable masking to detect and hide:
|
|
102
|
+
- API tokens, keys, secrets
|
|
103
|
+
- Passwords, credentials, authentication tokens
|
|
104
|
+
- Case-insensitive pattern matching for reliable detection
|
|
105
|
+
- Applied masking to both base and custom provider environment variables
|
|
106
|
+
- **Consistent Security Protection**: Unified secret masking across all environment variable displays
|
|
107
|
+
|
|
108
|
+
### Refactored
|
|
109
|
+
- **Provider Environment Variables**: Moved from inline switch statements to provider configuration objects
|
|
110
|
+
- **Stdin Management**: Complete migration to centralized StdinManager pattern across all modules
|
|
111
|
+
- **Launch Logic**: Restructured Claude Code launching with clear control handover phases
|
|
112
|
+
- **State Restoration**: Eliminated duplicate state restoration in StdinScope.release() for cleaner control flow
|
|
113
|
+
- **Test Organization**: Improved test file naming conventions and structure
|
|
114
|
+
|
|
115
|
+
### Documentation
|
|
116
|
+
- **README Updates**: Documented GLM API support in both English and Chinese versions
|
|
117
|
+
- **Provider Documentation**: Added comprehensive provider-specific feature descriptions
|
|
118
|
+
- **Configuration Guide**: Enhanced API configuration documentation with provider-specific details
|
|
119
|
+
|
|
8
120
|
## [2.0.0] - 2025-09-21
|
|
9
121
|
|
|
10
122
|
### Added
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Claude Launcher
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@kikkimo/claude-launcher) [](https://opensource.org/licenses/MIT) [](https://nodejs.org/) [](https://www.npmjs.com/package/@kikkimo/claude-launcher) [](https://deepwiki.com/kikkimo/claude-launcher)
|
|
4
|
+
|
|
3
5
|
An elegant interactive launcher for Claude Code with a beautiful Claude-style interface and comprehensive third-party API management. Launch Claude Code with various configurations through an intuitive multilingual command-line menu.
|
|
4
6
|
|
|
5
7
|
## 📖 Documentation
|
|
@@ -13,7 +15,7 @@ An elegant interactive launcher for Claude Code with a beautiful Claude-style in
|
|
|
13
15
|
- Claude-style interface with authentic orange/amber color scheme
|
|
14
16
|
- Arrow key navigation with smooth menu transitions
|
|
15
17
|
- Interactive tables for API selection and management
|
|
16
|
-
- Multi-language support (
|
|
18
|
+
- Multi-language support (English, Simplified Chinese, Traditional Chinese, German, French, Spanish, Italian, Portuguese, Japanese, Korean, Russian)
|
|
17
19
|
|
|
18
20
|
### 🔐 **Advanced Security**
|
|
19
21
|
- AES-256-CBC encryption for all sensitive data
|
|
@@ -23,7 +25,7 @@ An elegant interactive launcher for Claude Code with a beautiful Claude-style in
|
|
|
23
25
|
- Strong password requirements and validation
|
|
24
26
|
|
|
25
27
|
### 🚀 **Third-party API Management**
|
|
26
|
-
- Full support for multiple third-party API providers
|
|
28
|
+
- Full support for multiple third-party API providers (OpenAI, Anthropic, DeepSeek, Kimi, GLM (ZhiPu AI), and more)
|
|
27
29
|
- Interactive API configuration with validation
|
|
28
30
|
- API usage statistics and tracking
|
|
29
31
|
- Secure configuration backup and restore
|
|
@@ -50,7 +52,7 @@ An elegant interactive launcher for Claude Code with a beautiful Claude-style in
|
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
3. **First-time setup:** The launcher will guide you through:
|
|
53
|
-
- Language selection (
|
|
55
|
+
- Language selection (11 languages available)
|
|
54
56
|
- Security setup (password configuration for import/export)
|
|
55
57
|
- Third-party API configuration (if desired)
|
|
56
58
|
|
|
@@ -84,7 +86,7 @@ node claude-launcher
|
|
|
84
86
|
3. **Launch Claude Code with Third-party API** - Use configured third-party API
|
|
85
87
|
4. **Launch Claude Code with Third-party API (Skip Permissions)** - Combine third-party API with permission skipping
|
|
86
88
|
5. **Third-party API Management** - Configure, switch, remove APIs, view statistics
|
|
87
|
-
6. **Language Settings** - Switch between
|
|
89
|
+
6. **Language Settings** - Switch between 11 supported languages
|
|
88
90
|
7. **Version Update Check** - Check for launcher updates
|
|
89
91
|
8. **Exit** - Close the launcher
|
|
90
92
|
|
|
@@ -146,7 +148,7 @@ Claude Launcher 2.0 uses an advanced configuration system:
|
|
|
146
148
|
|
|
147
149
|
### First-time Setup Process
|
|
148
150
|
|
|
149
|
-
1. **Language Selection**: Choose from
|
|
151
|
+
1. **Language Selection**: Choose from 11 supported languages
|
|
150
152
|
2. **Security Setup**:
|
|
151
153
|
- Set up password protection for import/export (recommended)
|
|
152
154
|
- Or skip for basic usage (limited features)
|
|
@@ -156,10 +158,11 @@ Claude Launcher 2.0 uses an advanced configuration system:
|
|
|
156
158
|
|
|
157
159
|
Configure any third-party API provider through the interactive interface:
|
|
158
160
|
|
|
159
|
-
- **Supported Providers**: OpenAI, Anthropic,
|
|
161
|
+
- **Supported Providers**: OpenAI, Anthropic, DeepSeek, Kimi, GLM (ZhiPu AI), and custom APIs
|
|
160
162
|
- **Secure Storage**: All API tokens encrypted before storage
|
|
161
163
|
- **Validation**: Real-time validation of URLs, tokens, and models
|
|
162
164
|
- **Usage Tracking**: Monitor API usage statistics
|
|
165
|
+
- **Provider-specific Features**: Optimized configuration for each provider with helpful notes and recommendations
|
|
163
166
|
|
|
164
167
|
### Configuration Import/Export
|
|
165
168
|
|
package/claude-launcher
CHANGED
|
@@ -7,16 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Force complete stdin reset to prevent navigation issues
|
|
10
|
+
* Note: This function should only reset state, not remove listeners
|
|
11
|
+
* that might be used by other modules
|
|
10
12
|
*/
|
|
11
13
|
function forceStdinCleanup() {
|
|
12
14
|
try {
|
|
13
15
|
if (process.stdin.isTTY) {
|
|
16
|
+
// Only reset mode, don't remove listeners that might be in use
|
|
14
17
|
process.stdin.setRawMode(false);
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
// NOTE: Removed removeAllListeners to prevent conflicts
|
|
19
|
+
// Each module should manage its own listeners
|
|
20
|
+
// Only pause if not already paused (isPaused is a method, not a property)
|
|
21
|
+
if (!process.stdin.isPaused()) {
|
|
22
|
+
process.stdin.pause();
|
|
23
|
+
}
|
|
17
24
|
}
|
|
18
25
|
} catch (error) {
|
|
19
|
-
// Ignore cleanup errors
|
|
26
|
+
// Ignore cleanup errors but log for debugging
|
|
27
|
+
if (process.env.DEBUG_STDIN) {
|
|
28
|
+
console.error('[DEBUG] forceStdinCleanup error:', error.message);
|
|
29
|
+
}
|
|
20
30
|
}
|
|
21
31
|
}
|
|
22
32
|
|
|
@@ -1113,6 +1123,50 @@ process.on('SIGTERM', () => {
|
|
|
1113
1123
|
process.exit(0);
|
|
1114
1124
|
});
|
|
1115
1125
|
|
|
1126
|
+
// Global SIGINT handler (Ctrl+C) - fallback for non-raw mode Ctrl+C
|
|
1127
|
+
// In raw mode, Ctrl+C is handled by StdinManager directly
|
|
1128
|
+
// This handler catches Ctrl+C in line mode (e.g., during readline input)
|
|
1129
|
+
const stdinManager = require('./lib/utils/stdin-manager');
|
|
1130
|
+
|
|
1131
|
+
// Flag to prevent re-entrance of SIGINT handler
|
|
1132
|
+
let exiting = false;
|
|
1133
|
+
|
|
1134
|
+
process.on('SIGINT', () => {
|
|
1135
|
+
// During Claude run, ignore in launcher so child handles it
|
|
1136
|
+
// Check this BEFORE setting exiting flag to avoid breaking reentrancy protection
|
|
1137
|
+
if (stdinManager.isSuspended && stdinManager.isSuspended()) {
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// Prevent re-entrance - ensure cleanup runs only once
|
|
1142
|
+
if (exiting) {
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
exiting = true;
|
|
1146
|
+
|
|
1147
|
+
// Try to reset stdin state before handling
|
|
1148
|
+
try {
|
|
1149
|
+
if (process.stdin.isTTY) {
|
|
1150
|
+
process.stdin.setRawMode(false);
|
|
1151
|
+
process.stdin.pause();
|
|
1152
|
+
}
|
|
1153
|
+
} catch (_) {
|
|
1154
|
+
// Ignore errors during emergency cleanup
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
// Use unified Ctrl+C handler from StdinManager (synchronous)
|
|
1158
|
+
try {
|
|
1159
|
+
stdinManager.handleCtrlC();
|
|
1160
|
+
} catch (_) {
|
|
1161
|
+
// Ignore errors during Ctrl+C handling
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// Exit with standard SIGINT exit code (128 + 2 = 130)
|
|
1165
|
+
// Note: If handleCtrlC() calls process.exit(0) for second Ctrl+C,
|
|
1166
|
+
// this line won't be reached, which is expected behavior
|
|
1167
|
+
process.exit(130);
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1116
1170
|
// Initialize global menus and start the application
|
|
1117
1171
|
initializeGlobalMenus();
|
|
1118
1172
|
|
package/docs/README-zh.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Claude Launcher
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@kikkimo/claude-launcher) [](https://opensource.org/licenses/MIT) [](https://nodejs.org/) [](https://www.npmjs.com/package/@kikkimo/claude-launcher) [](https://deepwiki.com/kikkimo/claude-launcher)
|
|
4
|
+
|
|
3
5
|
一个优雅的 Claude Code 交互式启动器,具有美观的 Claude 风格界面和全面的第三方 API 管理功能。通过直观的多语言命令行菜单使用各种配置启动 Claude Code。
|
|
4
6
|
|
|
5
7
|
## 📖 文档
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
- Claude 风格界面,采用正宗的橙色/琥珀色配色方案
|
|
14
16
|
- 方向键导航,流畅的菜单切换
|
|
15
17
|
- API 选择和管理的交互式表格
|
|
16
|
-
-
|
|
18
|
+
- 多语言支持(简体中文、繁体中文、英文、德文、法文、西班牙文、意大利文、葡萄牙文、日文、韩文、俄文)
|
|
17
19
|
|
|
18
20
|
### 🔐 **高级安全**
|
|
19
21
|
- 所有敏感数据使用 AES-256-CBC 加密
|
|
@@ -23,7 +25,7 @@
|
|
|
23
25
|
- 强密码要求和验证
|
|
24
26
|
|
|
25
27
|
### 🚀 **第三方 API 管理**
|
|
26
|
-
- 全面支持多个第三方 API
|
|
28
|
+
- 全面支持多个第三方 API 提供商(OpenAI、Anthropic、DeepSeek、Kimi、GLM/智谱AI 和自定义 API)
|
|
27
29
|
- 带验证的交互式 API 配置
|
|
28
30
|
- API 使用统计和跟踪
|
|
29
31
|
- 安全的配置备份和恢复
|
|
@@ -50,7 +52,7 @@
|
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
3. **首次设置:** 启动器将引导您完成:
|
|
53
|
-
- 语言选择(提供
|
|
55
|
+
- 语言选择(提供11种语言)
|
|
54
56
|
- 安全设置(配置导入/导出的密码)
|
|
55
57
|
- 第三方 API 配置(如果需要)
|
|
56
58
|
|
|
@@ -84,7 +86,7 @@ node claude-launcher
|
|
|
84
86
|
3. **使用第三方 API 启动 Claude Code** - 使用配置的第三方 API
|
|
85
87
|
4. **使用第三方 API 启动 Claude Code(跳过权限)** - 结合第三方 API 和跳过权限
|
|
86
88
|
5. **第三方 API 管理** - 配置、切换、删除 API,查看统计信息
|
|
87
|
-
6. **语言设置** - 在
|
|
89
|
+
6. **语言设置** - 在11种支持的语言之间切换
|
|
88
90
|
7. **版本更新检查** - 检查启动器更新
|
|
89
91
|
8. **退出** - 关闭启动器
|
|
90
92
|
|
|
@@ -146,7 +148,7 @@ Claude Launcher 2.0 使用先进的配置系统:
|
|
|
146
148
|
|
|
147
149
|
### 首次设置流程
|
|
148
150
|
|
|
149
|
-
1. **语言选择**:从
|
|
151
|
+
1. **语言选择**:从11种支持的语言中选择
|
|
150
152
|
2. **安全设置**:
|
|
151
153
|
- 设置导入/导出的密码保护(推荐)
|
|
152
154
|
- 或跳过基本使用(功能有限)
|
|
@@ -156,10 +158,11 @@ Claude Launcher 2.0 使用先进的配置系统:
|
|
|
156
158
|
|
|
157
159
|
通过交互界面配置任何第三方 API 提供商:
|
|
158
160
|
|
|
159
|
-
- **支持的提供商**:OpenAI、Anthropic
|
|
161
|
+
- **支持的提供商**:OpenAI、Anthropic、DeepSeek、Kimi、GLM/智谱AI 和自定义 API
|
|
160
162
|
- **安全存储**:所有 API 令牌在存储前加密
|
|
161
163
|
- **验证**:URL、令牌和模型的实时验证
|
|
162
164
|
- **使用跟踪**:监控 API 使用统计
|
|
165
|
+
- **提供商特定功能**:为每个提供商优化配置,提供有用的注释和建议
|
|
163
166
|
|
|
164
167
|
### 配置导入/导出
|
|
165
168
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const readline = require('readline');
|
|
7
|
+
const stdinManager = require('../utils/stdin-manager');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Get password input with proper masking (no plaintext display)
|
|
@@ -12,105 +13,118 @@ const readline = require('readline');
|
|
|
12
13
|
*/
|
|
13
14
|
function getPasswordInput(prompt) {
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
15
|
-
// Save original stdin state
|
|
16
|
-
const originalRawMode = process.stdin.isRaw;
|
|
17
|
-
const originalPaused = process.stdin.isPaused();
|
|
18
|
-
|
|
19
16
|
let password = '';
|
|
17
|
+
let scope = null;
|
|
18
|
+
let cleanedUp = false;
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
process.stdout.write(prompt);
|
|
24
|
-
|
|
25
|
-
if (!process.stdin.isTTY) {
|
|
26
|
-
// Non-TTY environment fallback
|
|
27
|
-
const rl = readline.createInterface({
|
|
28
|
-
input: process.stdin,
|
|
29
|
-
output: process.stdout
|
|
30
|
-
});
|
|
20
|
+
// Display prompt - this is necessary for password input
|
|
21
|
+
process.stdout.write(prompt);
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
if (!process.stdin.isTTY) {
|
|
24
|
+
// Non-TTY environment fallback - use scope's createReadline
|
|
25
|
+
try {
|
|
26
|
+
scope = stdinManager.acquire('line', {
|
|
27
|
+
id: 'passwordInput_nonTTY',
|
|
28
|
+
allowNested: false
|
|
35
29
|
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
reject(new Error(`Failed to acquire stdin for password input: ${error.message}`));
|
|
36
32
|
return;
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (process.stdin.isTTY) {
|
|
48
|
-
process.stdin.setRawMode(originalRawMode);
|
|
49
|
-
if (originalPaused) {
|
|
50
|
-
process.stdin.pause();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
} catch (error) {
|
|
54
|
-
// Ignore cleanup errors
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const handleKeyPress = (data) => {
|
|
59
|
-
const key = data.toString();
|
|
60
|
-
|
|
61
|
-
// Handle different key combinations
|
|
62
|
-
switch (key) {
|
|
63
|
-
case '\u0003': // Ctrl+C
|
|
64
|
-
cleanup();
|
|
65
|
-
reject(new Error('Password input cancelled by user'));
|
|
66
|
-
return;
|
|
67
|
-
|
|
68
|
-
case '\r': // Enter (CR)
|
|
69
|
-
case '\n': // Line Feed (LF)
|
|
70
|
-
case '\r\n': // CRLF
|
|
71
|
-
process.stdout.write('\n');
|
|
72
|
-
cleanup();
|
|
73
|
-
resolve(password);
|
|
74
|
-
return;
|
|
75
|
-
|
|
76
|
-
case '\u007f': // Backspace (DEL)
|
|
77
|
-
case '\b': // Backspace (BS)
|
|
78
|
-
if (password.length > 0) {
|
|
79
|
-
password = password.slice(0, -1);
|
|
80
|
-
// Clear the last asterisk
|
|
81
|
-
process.stdout.write('\b \b');
|
|
82
|
-
}
|
|
83
|
-
return;
|
|
84
|
-
|
|
85
|
-
case '\u001b': // Escape
|
|
86
|
-
cleanup();
|
|
87
|
-
reject(new Error('Password input cancelled'));
|
|
88
|
-
return;
|
|
35
|
+
const rl = scope.createReadline();
|
|
36
|
+
rl.question('', (answer) => {
|
|
37
|
+
rl.close();
|
|
38
|
+
scope.release();
|
|
39
|
+
resolve(answer.trim());
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
89
43
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
44
|
+
// Use StdinManager to acquire raw mode scope
|
|
45
|
+
try {
|
|
46
|
+
scope = stdinManager.acquire('raw', {
|
|
47
|
+
id: 'passwordInput',
|
|
48
|
+
allowNested: false
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
reject(new Error(`Failed to acquire stdin for password input: ${error.message}`));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
99
54
|
|
|
100
|
-
|
|
55
|
+
const cleanup = () => {
|
|
56
|
+
if (cleanedUp) return;
|
|
57
|
+
cleanedUp = true;
|
|
101
58
|
|
|
102
|
-
} catch (error) {
|
|
103
|
-
// Restore stdin state on error
|
|
104
59
|
try {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
process.stdin.pause();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
} catch (cleanupError) {
|
|
60
|
+
scope.removeAllListeners('data');
|
|
61
|
+
scope.release();
|
|
62
|
+
} catch (error) {
|
|
112
63
|
// Ignore cleanup errors
|
|
113
64
|
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleKeyPress = (data) => {
|
|
68
|
+
const key = data.toString();
|
|
69
|
+
|
|
70
|
+
// Handle Ctrl+C - cancel password input immediately
|
|
71
|
+
if (key === '\u0003') {
|
|
72
|
+
cleanup();
|
|
73
|
+
reject(new Error('Password input cancelled by Ctrl+C'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// If waiting for second Ctrl+C, any other key cancels it
|
|
78
|
+
if (stdinManager.isCtrlCPending()) {
|
|
79
|
+
stdinManager.cancelCtrlC();
|
|
80
|
+
// Continue to process this key normally
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Handle different key combinations
|
|
84
|
+
switch (key) {
|
|
85
|
+
case '\r': // Enter (CR)
|
|
86
|
+
case '\n': // Line Feed (LF)
|
|
87
|
+
case '\r\n': // CRLF
|
|
88
|
+
process.stdout.write('\n');
|
|
89
|
+
cleanup();
|
|
90
|
+
resolve(password);
|
|
91
|
+
return;
|
|
92
|
+
|
|
93
|
+
case '\u007f': // Backspace (DEL)
|
|
94
|
+
case '\b': // Backspace (BS)
|
|
95
|
+
if (password.length > 0) {
|
|
96
|
+
password = password.slice(0, -1);
|
|
97
|
+
// Clear the last asterisk
|
|
98
|
+
process.stdout.write('\b \b');
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
|
|
102
|
+
case '\u001b': // Escape
|
|
103
|
+
cleanup();
|
|
104
|
+
reject(new Error('Password input cancelled'));
|
|
105
|
+
return;
|
|
106
|
+
|
|
107
|
+
default:
|
|
108
|
+
// Process each character individually to handle IME batch input
|
|
109
|
+
// When using Chinese IME, multiple chars may come in one event (e.g., "vis")
|
|
110
|
+
for (let i = 0; i < key.length; i++) {
|
|
111
|
+
const char = key[i];
|
|
112
|
+
const charCode = char.charCodeAt(0);
|
|
113
|
+
|
|
114
|
+
// Filter out control characters (only accept ASCII printable)
|
|
115
|
+
if (charCode >= 32 && charCode < 127) {
|
|
116
|
+
password += char;
|
|
117
|
+
process.stdout.write('*');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
scope.on('data', handleKeyPress);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
cleanup();
|
|
114
128
|
reject(error);
|
|
115
129
|
}
|
|
116
130
|
});
|
|
@@ -141,4 +155,4 @@ async function getPasswordWithConfirmation(prompt, confirmPrompt = 'Confirm Pass
|
|
|
141
155
|
module.exports = {
|
|
142
156
|
getPasswordInput,
|
|
143
157
|
getPasswordWithConfirmation
|
|
144
|
-
};
|
|
158
|
+
};
|
package/lib/i18n/locales/de.js
CHANGED
|
@@ -335,10 +335,25 @@ module.exports = {
|
|
|
335
335
|
press_key_return: "Drücken Sie eine beliebige Taste, um zum Hauptmenü zurückzukehren...",
|
|
336
336
|
environment_variables: "Umgebungsvariablen:",
|
|
337
337
|
using_third_party_api: "Verwende Drittanbieter-API-Konfiguration",
|
|
338
|
+
provider_optimizations_applied: "Anbieter-Optimierungen angewendet",
|
|
339
|
+
extended_timeout_format: "Erweitertes Timeout: {0}s ({1} Minuten)",
|
|
340
|
+
extended_timeout_format_singular: "Erweitertes Timeout: {0}s ({1} Minute)",
|
|
341
|
+
non_essential_traffic_disabled: "Nicht-essentieller Traffic deaktiviert",
|
|
342
|
+
custom_env_var: "{0}={1}",
|
|
343
|
+
// Deprecated - kept for backward compatibility
|
|
338
344
|
deepseek_optimizations: "DeepSeek-Optimierungen aktiviert:",
|
|
339
345
|
extended_timeout: "Erweitertes Timeout (600s)",
|
|
340
|
-
non_essential_disabled: "Nicht-essentieller Traffic deaktiviert"
|
|
341
|
-
|
|
346
|
+
non_essential_disabled: "Nicht-essentieller Traffic deaktiviert"
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
// Anbieter-Hinweise
|
|
350
|
+
provider: {
|
|
351
|
+
note_prefix: "Hinweis",
|
|
352
|
+
notes: {
|
|
353
|
+
deepseek: "Erfordert erweitertes Timeout für komplexe Denkaufgaben",
|
|
354
|
+
zhipu: "Erfordert erweitertes Timeout für große Antworten",
|
|
355
|
+
zai: "Erfordert erweitertes Timeout für große Antworten"
|
|
356
|
+
}
|
|
342
357
|
},
|
|
343
358
|
|
|
344
359
|
// Zusätzliche UI-Nachrichten
|
package/lib/i18n/locales/en.js
CHANGED
|
@@ -335,10 +335,25 @@ module.exports = {
|
|
|
335
335
|
press_key_return: "Press any key to return to main menu...",
|
|
336
336
|
environment_variables: "Environment variables:",
|
|
337
337
|
using_third_party_api: "Using Third-party API Configuration",
|
|
338
|
+
provider_optimizations_applied: "Provider Optimizations Applied",
|
|
339
|
+
extended_timeout_format: "Extended timeout: {0}s ({1} minutes)",
|
|
340
|
+
extended_timeout_format_singular: "Extended timeout: {0}s ({1} minute)",
|
|
341
|
+
non_essential_traffic_disabled: "Non-essential traffic disabled",
|
|
342
|
+
custom_env_var: "{0}={1}",
|
|
343
|
+
// Deprecated - kept for backward compatibility
|
|
338
344
|
deepseek_optimizations: "DeepSeek optimizations enabled:",
|
|
339
345
|
extended_timeout: "Extended timeout (600s)",
|
|
340
|
-
non_essential_disabled: "Non-essential traffic disabled"
|
|
341
|
-
|
|
346
|
+
non_essential_disabled: "Non-essential traffic disabled"
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
// Provider notes
|
|
350
|
+
provider: {
|
|
351
|
+
note_prefix: "Note",
|
|
352
|
+
notes: {
|
|
353
|
+
deepseek: "Requires extended timeout for complex reasoning tasks",
|
|
354
|
+
zhipu: "Requires extended timeout for large responses",
|
|
355
|
+
zai: "Requires extended timeout for large responses"
|
|
356
|
+
}
|
|
342
357
|
},
|
|
343
358
|
|
|
344
359
|
// Additional UI messages
|
package/lib/i18n/locales/es.js
CHANGED
|
@@ -335,10 +335,25 @@ module.exports = {
|
|
|
335
335
|
press_key_return: "Presione cualquier tecla para volver al menú principal...",
|
|
336
336
|
environment_variables: "Variables de entorno:",
|
|
337
337
|
using_third_party_api: "Usando configuración de API de terceros",
|
|
338
|
+
provider_optimizations_applied: "Optimizaciones del proveedor aplicadas",
|
|
339
|
+
extended_timeout_format: "Tiempo de espera extendido: {0}s ({1} minutos)",
|
|
340
|
+
extended_timeout_format_singular: "Tiempo de espera extendido: {0}s ({1} minuto)",
|
|
341
|
+
non_essential_traffic_disabled: "Tráfico no esencial deshabilitado",
|
|
342
|
+
custom_env_var: "{0}={1}",
|
|
343
|
+
// Deprecated - kept for backward compatibility
|
|
338
344
|
deepseek_optimizations: "Optimizaciones DeepSeek habilitadas:",
|
|
339
345
|
extended_timeout: "Tiempo de espera extendido (600s)",
|
|
340
|
-
non_essential_disabled: "Tráfico no esencial deshabilitado"
|
|
341
|
-
|
|
346
|
+
non_essential_disabled: "Tráfico no esencial deshabilitado"
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
// Notas del proveedor
|
|
350
|
+
provider: {
|
|
351
|
+
note_prefix: "Nota",
|
|
352
|
+
notes: {
|
|
353
|
+
deepseek: "Requiere tiempo de espera extendido para tareas de razonamiento complejas",
|
|
354
|
+
zhipu: "Requiere tiempo de espera extendido para respuestas grandes",
|
|
355
|
+
zai: "Requiere tiempo de espera extendido para respuestas grandes"
|
|
356
|
+
}
|
|
342
357
|
},
|
|
343
358
|
|
|
344
359
|
// Mensajes adicionales de interfaz de usuario
|
package/lib/i18n/locales/fr.js
CHANGED
|
@@ -335,10 +335,25 @@ module.exports = {
|
|
|
335
335
|
press_key_return: "Appuyez sur n'importe quelle touche pour retourner au menu principal...",
|
|
336
336
|
environment_variables: "Variables d'environnement :",
|
|
337
337
|
using_third_party_api: "Utilisation de la configuration d'API tierce",
|
|
338
|
+
provider_optimizations_applied: "Optimisations du fournisseur appliquées",
|
|
339
|
+
extended_timeout_format: "Délai d'expiration étendu : {0}\u00A0s ({1}\u00A0minutes)",
|
|
340
|
+
extended_timeout_format_singular: "Délai d'expiration étendu : {0}\u00A0s ({1}\u00A0minute)",
|
|
341
|
+
non_essential_traffic_disabled: "Trafic non essentiel désactivé",
|
|
342
|
+
custom_env_var: "{0}={1}",
|
|
343
|
+
// Deprecated - kept for backward compatibility
|
|
338
344
|
deepseek_optimizations: "Optimisations DeepSeek activées :",
|
|
339
|
-
extended_timeout: "Délai d'expiration étendu (
|
|
340
|
-
non_essential_disabled: "Trafic non essentiel désactivé"
|
|
341
|
-
|
|
345
|
+
extended_timeout: "Délai d'expiration étendu (600\u00A0s)",
|
|
346
|
+
non_essential_disabled: "Trafic non essentiel désactivé"
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
// Notes du fournisseur
|
|
350
|
+
provider: {
|
|
351
|
+
note_prefix: "Note",
|
|
352
|
+
notes: {
|
|
353
|
+
deepseek: "Nécessite un délai d'expiration étendu pour les tâches de raisonnement complexes",
|
|
354
|
+
zhipu: "Nécessite un délai d'expiration étendu pour les grandes réponses",
|
|
355
|
+
zai: "Nécessite un délai d'expiration étendu pour les grandes réponses"
|
|
356
|
+
}
|
|
342
357
|
},
|
|
343
358
|
|
|
344
359
|
// Messages d'interface utilisateur supplémentaires
|