@vibeapi/api-helper 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +25 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +18 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/auth.d.ts +1 -0
  6. package/dist/commands/auth.js +119 -0
  7. package/dist/commands/auth.js.map +1 -0
  8. package/dist/commands/config.d.ts +1 -0
  9. package/dist/commands/config.js +130 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +1 -0
  12. package/dist/commands/doctor.js +105 -0
  13. package/dist/commands/doctor.js.map +1 -0
  14. package/dist/commands/index.d.ts +4 -0
  15. package/dist/commands/index.js +5 -0
  16. package/dist/commands/index.js.map +1 -0
  17. package/dist/commands/lang.d.ts +1 -0
  18. package/dist/commands/lang.js +28 -0
  19. package/dist/commands/lang.js.map +1 -0
  20. package/dist/index.d.ts +12 -0
  21. package/dist/index.js +10 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/lib/api-validator.d.ts +12 -0
  24. package/dist/lib/api-validator.js +79 -0
  25. package/dist/lib/api-validator.js.map +1 -0
  26. package/dist/lib/claude-code-manager.d.ts +86 -0
  27. package/dist/lib/claude-code-manager.js +233 -0
  28. package/dist/lib/claude-code-manager.js.map +1 -0
  29. package/dist/lib/command.d.ts +10 -0
  30. package/dist/lib/command.js +168 -0
  31. package/dist/lib/command.js.map +1 -0
  32. package/dist/lib/config.d.ts +64 -0
  33. package/dist/lib/config.js +226 -0
  34. package/dist/lib/config.js.map +1 -0
  35. package/dist/lib/i18n.d.ts +20 -0
  36. package/dist/lib/i18n.js +149 -0
  37. package/dist/lib/i18n.js.map +1 -0
  38. package/dist/lib/opencode-manager.d.ts +55 -0
  39. package/dist/lib/opencode-manager.js +134 -0
  40. package/dist/lib/opencode-manager.js.map +1 -0
  41. package/dist/lib/tool-manager.d.ts +25 -0
  42. package/dist/lib/tool-manager.js +280 -0
  43. package/dist/lib/tool-manager.js.map +1 -0
  44. package/dist/lib/wizard.d.ts +23 -0
  45. package/dist/lib/wizard.js +360 -0
  46. package/dist/lib/wizard.js.map +1 -0
  47. package/dist/locales/en_US.json +146 -0
  48. package/dist/locales/zh_CN.json +146 -0
  49. package/dist/utils/logger.d.ts +55 -0
  50. package/dist/utils/logger.js +202 -0
  51. package/dist/utils/logger.js.map +1 -0
  52. package/dist/utils/string-width.d.ts +38 -0
  53. package/dist/utils/string-width.js +131 -0
  54. package/dist/utils/string-width.js.map +1 -0
  55. package/package.json +73 -0
@@ -0,0 +1,146 @@
1
+ {
2
+ "cli": {
3
+ "title": "Coding Tool Helper (chelper)",
4
+ "usage": "用法: chelper <命令> [选项]",
5
+ "commands": "命令:",
6
+ "examples": "示例:",
7
+ "error_unknown": "未知命令: {{command}}",
8
+ "error_general": "错误:"
9
+ },
10
+ "commands": {
11
+ "help": "显示帮助信息",
12
+ "version": "显示版本信息",
13
+ "init": "运行交互式初始化向导",
14
+ "lang": "语言管理",
15
+ "auth": "密钥管理",
16
+ "doctor": "健康检查",
17
+ "enter": "配置管理",
18
+ "tool": "工具管理"
19
+ },
20
+ "lang": {
21
+ "current": "当前语言",
22
+ "show_usage": "chelper lang show - 显示当前语言",
23
+ "set_usage": "chelper lang set <zh_CN|en_US> - 设置语言",
24
+ "changed": "语言已从 {{from}} 更改为 {{to}}",
25
+ "invalid": "不支持的语言: {{lang}}",
26
+ "available": "可用语言"
27
+ },
28
+ "auth": {
29
+ "set_usage": "chelper auth <token> - 设置API密钥",
30
+ "token_prompt": "请输入API密钥",
31
+ "token_required": "API密钥不能为空",
32
+ "saved": "API密钥已保存",
33
+ "revoke_confirm": "确认要删除已保存的API密钥吗?",
34
+ "revoked": "API密钥已删除",
35
+ "not_revoked": "取消删除操作",
36
+ "get_api_key_hint": "如需获取 API Key,请访问: {{url}}"
37
+ },
38
+ "wizard": {
39
+ "banner_subtitle": "统一管理您的 Claude Code 等编码工具",
40
+ "welcome": "欢迎使用编码工具助手!",
41
+ "privacy_note": "我们重视您的隐私,所有配置信息仅保存在本地.",
42
+ "select_language": "请选择界面语言",
43
+ "input_api_key": "输入 API Key",
44
+ "input_your_api_key": "请在这里输入您的 API key, 回车键确认:",
45
+ "update_api_key": "更新 API Key",
46
+ "api_key_required": "API密钥不能为空",
47
+ "select_tool": "请选择要配置的编码工具",
48
+ "tool_not_installed": "{{tool}} 尚未安装",
49
+ "install_tool_confirm": "是否现在安装?",
50
+ "installing_tool": "正在安装工具...",
51
+ "tool_installed": "工具安装成功",
52
+ "install_failed": "安装失败",
53
+ "install_skipped": "已跳过安装,您可以稍后手动安装",
54
+ "menu_title": "管理菜单",
55
+ "select_action": "请选择操作",
56
+ "action_load_config": "配置装载 - (将您配置的 API 应用到 {{tool}})",
57
+ "action_unload_config": "配置卸载 - (移除 {{tool}} 的 API 配置)",
58
+ "action_view_config": "当前配置",
59
+ "action_back": "返回",
60
+ "action_exit": "退出",
61
+ "goodbye": "再见!",
62
+ "loading_config": "正在装载配置...",
63
+ "config_loaded": "配置已成功装载,您现在可以使用 {{tool}} 进行编码了。",
64
+ "config_failed": "配置装载失败",
65
+ "confirm_unload_config": "确认要从 {{tool}} 中卸载配置吗?",
66
+ "unloading_config": "正在卸载配置...",
67
+ "config_unloaded": "配置已成功卸载",
68
+ "config_unload_failed": "配置卸载失败",
69
+ "tool_not_supported": "该工具不支持此操作",
70
+ "missing_config": "缺少必要配置(API密钥)",
71
+ "current_config": "当前配置",
72
+ "config_language": "界面语言",
73
+ "config_api_key": "API Key",
74
+ "config_models": "模型配置",
75
+ "config_title": "配置",
76
+ "not_set": "未设置",
77
+ "press_enter": "按回车继续",
78
+ "main_menu_title": "主菜单",
79
+ "current_config_status": "当前配置状态:",
80
+ "api_key_set": "已设置",
81
+ "api_key_get_hint": "如需获取 API Key,请访问: {{url}}",
82
+ "menu_config_language": "界面语言",
83
+ "menu_config_api_key": "API Key",
84
+ "menu_config_models": "模型配置",
85
+ "menu_config_tool": "编码工具",
86
+ "menu_exit": "退出",
87
+ "select_operation": "请选择操作:",
88
+ "goodbye_message": "再见!",
89
+ "nav_return": "返回",
90
+ "nav_exit": "退出",
91
+ "current_active": "当前",
92
+ "operation_hint": "操作提示",
93
+ "hint_navigate": "↑↓ 选择",
94
+ "hint_confirm": "Enter 确认",
95
+ "detected_config_title": "Claude Code 当前配置",
96
+ "chelper_config_title": "Chelper 配置",
97
+ "claude_code_config_title": "Claude Code 当前全局配置",
98
+ "config_synced": "配置已同步",
99
+ "config_out_of_sync": "配置不一致,建议刷新",
100
+ "config_not_loaded": "{{tool}} 尚未装载配置",
101
+ "action_refresh_config": "配置刷新 - (更新 {{tool}} 的配置)",
102
+ "global_config_warning": "⚠️ 注意:您正在修改 {{tool}} 全局配置,更改将影响所有工作区",
103
+ "global_label": "全局",
104
+ "set_success": "设置成功",
105
+ "start_tool": "启动 {{tool}} - (建议在您的工作空间新开终端,执行 {{shell}} 启动)",
106
+ "starting_tool": "启动中...",
107
+ "validating_api_key": "正在验证 API Key...",
108
+ "api_key_valid": "API Key 验证通过",
109
+ "api_key_invalid": "API Key 无效或已过期",
110
+ "api_key_network_error": "网络错误,请检查网络连接",
111
+ "select_model_config": "请选择模型配置方式",
112
+ "use_default_models": "使用默认模型",
113
+ "use_custom_models": "自定义模型",
114
+ "model_haiku": "Haiku 模型 (快速)",
115
+ "model_sonnet": "Sonnet 模型 (平衡)",
116
+ "model_opus": "Opus 模型 (强大)",
117
+ "model_reasoning": "Reasoning 模型 (推理)",
118
+ "input_model_name": "请输入模型名称",
119
+ "models_saved": "模型配置已保存"
120
+ },
121
+ "doctor": {
122
+ "checking": "正在进行健康检查...",
123
+ "check_path": "检查PATH环境变量",
124
+ "check_api_key_network": "检查 API Key 和网络连接",
125
+ "check_api_key": "检查API密钥",
126
+ "check_tools": "检查已安装的工具",
127
+ "all_good": "所有检查通过!",
128
+ "tool_installed": "已安装",
129
+ "tool_not_found": "工具未找到: {{tool}}",
130
+ "network_error": "网络连接失败",
131
+ "api_key_invalid": "API Key 无效或已过期",
132
+ "api_key_network_ok": "API Key 和网络验证通过",
133
+ "api_key_missing": "API密钥未配置",
134
+ "claude_code_installed": "Claude Code 已安装",
135
+ "claude_code_not_installed": "Claude Code 未安装。请从 https://claude.ai/download 下载安装",
136
+ "suggestions": "建议",
137
+ "check_git_env": "检查 Git 环境",
138
+ "git_not_installed": "Git 未安装。请从 https://git-scm.com/downloads 下载安装"
139
+ },
140
+ "messages": {
141
+ "initializing": "正在初始化...",
142
+ "args": "参数:",
143
+ "first_run": "检测到首次运行,启动初始化向导...",
144
+ "config_saved": "配置已保存"
145
+ }
146
+ }
@@ -0,0 +1,55 @@
1
+ export declare enum LogLevel {
2
+ DEBUG = 0,
3
+ INFO = 1,
4
+ WARN = 2,
5
+ ERROR = 3
6
+ }
7
+ export declare class Logger {
8
+ private static instance;
9
+ private logLevel;
10
+ private fileLogLevel;
11
+ private logDir;
12
+ private fileLoggingEnabled;
13
+ private constructor();
14
+ static getInstance(): Logger;
15
+ /**
16
+ * Ensure the log directory exists
17
+ */
18
+ private ensureLogDir;
19
+ /**
20
+ * Get the current log file path based on today's date
21
+ */
22
+ private getLogFilePath;
23
+ /**
24
+ * Sanitize a value to mask sensitive information
25
+ */
26
+ private sanitizeValue;
27
+ /**
28
+ * Sanitize message and args to remove sensitive information
29
+ */
30
+ private sanitize;
31
+ /**
32
+ * Format args to string for file logging
33
+ */
34
+ private formatArgs;
35
+ /**
36
+ * Write log entry to file
37
+ */
38
+ private writeToFile;
39
+ setLogLevel(level: LogLevel): void;
40
+ setFileLogLevel(level: LogLevel): void;
41
+ setFileLoggingEnabled(enabled: boolean): void;
42
+ debug(message: string, ...args: any[]): void;
43
+ info(message: string, ...args: any[]): void;
44
+ warn(message: string, ...args: any[]): void;
45
+ error(message: string, ...args: any[]): void;
46
+ /**
47
+ * Log an error with stack trace (always writes to file)
48
+ */
49
+ logError(context: string, error: unknown): void;
50
+ /**
51
+ * Get the log directory path
52
+ */
53
+ getLogDir(): string;
54
+ }
55
+ export declare const logger: Logger;
@@ -0,0 +1,202 @@
1
+ import { existsSync, mkdirSync, appendFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ export var LogLevel;
5
+ (function (LogLevel) {
6
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
7
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
8
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
9
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
10
+ })(LogLevel || (LogLevel = {}));
11
+ // Sensitive keys that should be masked in logs
12
+ const SENSITIVE_KEYS = [
13
+ 'token',
14
+ 'apikey',
15
+ 'api_key',
16
+ 'api-key',
17
+ 'auth_token',
18
+ 'auth-token',
19
+ 'authorization',
20
+ 'password',
21
+ 'secret',
22
+ 'credential',
23
+ 'anthropic_auth_token',
24
+ 'anthropic_api_key',
25
+ 'z_ai_api_key'
26
+ ];
27
+ // Regex patterns for detecting sensitive values
28
+ const SENSITIVE_PATTERNS = [
29
+ // JWT-like tokens
30
+ /eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
31
+ // API key patterns (common formats)
32
+ /\b[a-zA-Z0-9]{32,}\b/g,
33
+ // Bearer token in headers
34
+ /Bearer\s+[A-Za-z0-9._-]+/gi
35
+ ];
36
+ export class Logger {
37
+ static instance;
38
+ logLevel = LogLevel.INFO;
39
+ fileLogLevel = LogLevel.WARN;
40
+ logDir;
41
+ fileLoggingEnabled = true;
42
+ constructor() {
43
+ this.logDir = join(homedir(), '.chelper');
44
+ this.ensureLogDir();
45
+ }
46
+ static getInstance() {
47
+ if (!Logger.instance) {
48
+ Logger.instance = new Logger();
49
+ }
50
+ return Logger.instance;
51
+ }
52
+ /**
53
+ * Ensure the log directory exists
54
+ */
55
+ ensureLogDir() {
56
+ try {
57
+ if (!existsSync(this.logDir)) {
58
+ mkdirSync(this.logDir, { recursive: true });
59
+ }
60
+ }
61
+ catch (error) {
62
+ this.fileLoggingEnabled = false;
63
+ }
64
+ }
65
+ /**
66
+ * Get the current log file path based on today's date
67
+ */
68
+ getLogFilePath() {
69
+ const now = new Date();
70
+ const dateStr = now.toISOString().split('T')[0]; // yyyy-mm-dd
71
+ return join(this.logDir, `${dateStr}.log`);
72
+ }
73
+ /**
74
+ * Sanitize a value to mask sensitive information
75
+ */
76
+ sanitizeValue(value) {
77
+ if (value === null || value === undefined) {
78
+ return value;
79
+ }
80
+ if (typeof value === 'string') {
81
+ let sanitized = value;
82
+ // Apply regex patterns to mask sensitive values
83
+ for (const pattern of SENSITIVE_PATTERNS) {
84
+ sanitized = sanitized.replace(pattern, '[REDACTED]');
85
+ }
86
+ return sanitized;
87
+ }
88
+ if (Array.isArray(value)) {
89
+ return value.map(item => this.sanitizeValue(item));
90
+ }
91
+ if (typeof value === 'object') {
92
+ const sanitized = {};
93
+ for (const [key, val] of Object.entries(value)) {
94
+ const keyLower = key.toLowerCase();
95
+ const isSensitive = SENSITIVE_KEYS.some(sk => keyLower.includes(sk));
96
+ sanitized[key] = isSensitive ? '[REDACTED]' : this.sanitizeValue(val);
97
+ }
98
+ return sanitized;
99
+ }
100
+ return value;
101
+ }
102
+ /**
103
+ * Sanitize message and args to remove sensitive information
104
+ */
105
+ sanitize(message, args) {
106
+ const sanitizedMessage = this.sanitizeValue(message);
107
+ const sanitizedArgs = args.map(arg => this.sanitizeValue(arg));
108
+ return { message: sanitizedMessage, args: sanitizedArgs };
109
+ }
110
+ /**
111
+ * Format args to string for file logging
112
+ */
113
+ formatArgs(args) {
114
+ if (args.length === 0)
115
+ return '';
116
+ return ' ' + args.map(arg => {
117
+ if (typeof arg === 'object') {
118
+ try {
119
+ return JSON.stringify(arg);
120
+ }
121
+ catch {
122
+ return String(arg);
123
+ }
124
+ }
125
+ return String(arg);
126
+ }).join(' ');
127
+ }
128
+ /**
129
+ * Write log entry to file
130
+ */
131
+ writeToFile(level, message, args) {
132
+ if (!this.fileLoggingEnabled)
133
+ return;
134
+ try {
135
+ const { message: sanitizedMsg, args: sanitizedArgs } = this.sanitize(message, args);
136
+ const timestamp = new Date().toISOString();
137
+ const logEntry = `${timestamp} [${level}] ${sanitizedMsg}${this.formatArgs(sanitizedArgs)}\n`;
138
+ appendFileSync(this.getLogFilePath(), logEntry, 'utf-8');
139
+ }
140
+ catch {
141
+ // Silently fail if file writing fails
142
+ }
143
+ }
144
+ setLogLevel(level) {
145
+ this.logLevel = level;
146
+ }
147
+ setFileLogLevel(level) {
148
+ this.fileLogLevel = level;
149
+ }
150
+ setFileLoggingEnabled(enabled) {
151
+ this.fileLoggingEnabled = enabled;
152
+ }
153
+ debug(message, ...args) {
154
+ if (this.logLevel <= LogLevel.DEBUG) {
155
+ console.debug(`[DEBUG] ${message}`, ...args);
156
+ }
157
+ if (this.fileLoggingEnabled && this.fileLogLevel <= LogLevel.DEBUG) {
158
+ this.writeToFile('DEBUG', message, args);
159
+ }
160
+ }
161
+ info(message, ...args) {
162
+ if (this.logLevel <= LogLevel.INFO) {
163
+ console.info(`[INFO] ${message}`, ...args);
164
+ }
165
+ if (this.fileLoggingEnabled && this.fileLogLevel <= LogLevel.INFO) {
166
+ this.writeToFile('INFO', message, args);
167
+ }
168
+ }
169
+ warn(message, ...args) {
170
+ if (this.logLevel <= LogLevel.WARN) {
171
+ console.warn(`[WARN] ${message}`, ...args);
172
+ }
173
+ if (this.fileLoggingEnabled && this.fileLogLevel <= LogLevel.WARN) {
174
+ this.writeToFile('WARN', message, args);
175
+ }
176
+ }
177
+ error(message, ...args) {
178
+ if (this.logLevel <= LogLevel.ERROR) {
179
+ console.error(`[ERROR] ${message}`, ...args);
180
+ }
181
+ if (this.fileLoggingEnabled && this.fileLogLevel <= LogLevel.ERROR) {
182
+ this.writeToFile('ERROR', message, args);
183
+ }
184
+ }
185
+ /**
186
+ * Log an error with stack trace (always writes to file)
187
+ */
188
+ logError(context, error) {
189
+ const errorMessage = error instanceof Error ? error.message : String(error);
190
+ const stack = error instanceof Error ? error.stack : undefined;
191
+ // Write to file with sanitized info
192
+ this.writeToFile('ERROR', `[${context}] ${errorMessage}`, stack ? [{ stack }] : []);
193
+ }
194
+ /**
195
+ * Get the log directory path
196
+ */
197
+ getLogDir() {
198
+ return this.logDir;
199
+ }
200
+ }
201
+ export const logger = Logger.getInstance();
202
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Calculate the visual display width of a string
3
+ * Handles emoji, CJK characters, and ANSI escape codes
4
+ */
5
+ /**
6
+ * Strip ANSI escape codes from a string
7
+ */
8
+ export declare function stripAnsi(str: string): string;
9
+ /**
10
+ * Calculate the visual display width of a string
11
+ * Strips ANSI codes and counts visual width of each character
12
+ */
13
+ export declare function stringWidth(str: string): number;
14
+ /**
15
+ * Pad a string to a specific visual width
16
+ * @param str - The string to pad
17
+ * @param targetWidth - The target visual width
18
+ * @param char - The character to use for padding (default: space)
19
+ * @param align - Alignment: 'left', 'right', or 'center' (default: 'left')
20
+ */
21
+ export declare function padString(str: string, targetWidth: number, char?: string, align?: 'left' | 'right' | 'center'): string;
22
+ /**
23
+ * Create a box border line
24
+ * @param leftChar - Left border character
25
+ * @param rightChar - Right border character
26
+ * @param fillChar - Fill character
27
+ * @param width - Total width including borders
28
+ */
29
+ export declare function createBorderLine(leftChar: string, rightChar: string, fillChar: string, width: number): string;
30
+ /**
31
+ * Create a box content line with borders
32
+ * @param content - The content to display
33
+ * @param leftChar - Left border character
34
+ * @param rightChar - Right border character
35
+ * @param width - Total width including borders
36
+ * @param align - Content alignment
37
+ */
38
+ export declare function createContentLine(content: string, leftChar: string, rightChar: string, width: number, align?: 'left' | 'right' | 'center'): string;
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Calculate the visual display width of a string
3
+ * Handles emoji, CJK characters, and ANSI escape codes
4
+ */
5
+ /**
6
+ * Strip ANSI escape codes from a string
7
+ */
8
+ export function stripAnsi(str) {
9
+ // eslint-disable-next-line no-control-regex
10
+ return str.replace(/\u001b\[[0-9;]*m/g, '');
11
+ }
12
+ /**
13
+ * Calculate the visual width of a character
14
+ * - Emoji and wide characters (CJK): 2
15
+ * - Regular ASCII: 1
16
+ * - Zero-width characters: 0
17
+ */
18
+ function charWidth(char) {
19
+ const code = char.codePointAt(0);
20
+ if (!code)
21
+ return 0;
22
+ // Zero-width characters
23
+ if (code === 0x200b || // Zero-width space
24
+ code === 0x200c || // Zero-width non-joiner
25
+ code === 0x200d || // Zero-width joiner
26
+ code === 0xfeff || // Zero-width no-break space
27
+ (code >= 0xfe00 && code <= 0xfe0f) // Variation Selectors (emoji style selectors)
28
+ ) {
29
+ return 0;
30
+ }
31
+ // Emoji and symbols (rough approximation)
32
+ // Most emoji are in these ranges and display as 2 characters wide
33
+ if ((code >= 0x1f300 && code <= 0x1f9ff) || // Misc Symbols and Pictographs, Emoticons, etc.
34
+ (code >= 0x2600 && code <= 0x26ff) || // Misc symbols
35
+ (code >= 0x2700 && code <= 0x27bf) || // Dingbats
36
+ (code >= 0x1f000 && code <= 0x1f02f) || // Mahjong Tiles, Domino Tiles
37
+ (code >= 0x1f0a0 && code <= 0x1f0ff) // Playing Cards
38
+ ) {
39
+ return 2;
40
+ }
41
+ // CJK characters (Chinese, Japanese, Korean)
42
+ // These are typically displayed as 2 characters wide
43
+ if ((code >= 0x4e00 && code <= 0x9fff) || // CJK Unified Ideographs
44
+ (code >= 0x3400 && code <= 0x4dbf) || // CJK Unified Ideographs Extension A
45
+ (code >= 0x20000 && code <= 0x2a6df) || // CJK Unified Ideographs Extension B
46
+ (code >= 0x2a700 && code <= 0x2b73f) || // CJK Unified Ideographs Extension C
47
+ (code >= 0x2b740 && code <= 0x2b81f) || // CJK Unified Ideographs Extension D
48
+ (code >= 0x2b820 && code <= 0x2ceaf) || // CJK Unified Ideographs Extension E
49
+ (code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility Ideographs
50
+ (code >= 0x2f800 && code <= 0x2fa1f) || // CJK Compatibility Ideographs Supplement
51
+ (code >= 0x3040 && code <= 0x309f) || // Hiragana
52
+ (code >= 0x30a0 && code <= 0x30ff) || // Katakana
53
+ (code >= 0xac00 && code <= 0xd7af) || // Hangul Syllables
54
+ (code >= 0x1100 && code <= 0x11ff) || // Hangul Jamo
55
+ (code >= 0x3130 && code <= 0x318f) || // Hangul Compatibility Jamo
56
+ (code >= 0xa960 && code <= 0xa97f) || // Hangul Jamo Extended-A
57
+ (code >= 0xd7b0 && code <= 0xd7ff) // Hangul Jamo Extended-B
58
+ ) {
59
+ return 2;
60
+ }
61
+ // Fullwidth characters
62
+ if (code >= 0xff00 && code <= 0xffef) {
63
+ return 2;
64
+ }
65
+ // Default to 1 for regular ASCII and other characters
66
+ return 1;
67
+ }
68
+ /**
69
+ * Calculate the visual display width of a string
70
+ * Strips ANSI codes and counts visual width of each character
71
+ */
72
+ export function stringWidth(str) {
73
+ const cleaned = stripAnsi(str);
74
+ let width = 0;
75
+ // Use Array.from to properly handle surrogate pairs
76
+ for (const char of Array.from(cleaned)) {
77
+ width += charWidth(char);
78
+ }
79
+ return width;
80
+ }
81
+ /**
82
+ * Pad a string to a specific visual width
83
+ * @param str - The string to pad
84
+ * @param targetWidth - The target visual width
85
+ * @param char - The character to use for padding (default: space)
86
+ * @param align - Alignment: 'left', 'right', or 'center' (default: 'left')
87
+ */
88
+ export function padString(str, targetWidth, char = ' ', align = 'left') {
89
+ const currentWidth = stringWidth(str);
90
+ const padWidth = Math.max(0, targetWidth - currentWidth);
91
+ if (padWidth === 0)
92
+ return str;
93
+ const padding = char.repeat(padWidth);
94
+ if (align === 'right') {
95
+ return padding + str;
96
+ }
97
+ else if (align === 'center') {
98
+ const leftPad = Math.floor(padWidth / 2);
99
+ const rightPad = padWidth - leftPad;
100
+ return char.repeat(leftPad) + str + char.repeat(rightPad);
101
+ }
102
+ else {
103
+ return str + padding;
104
+ }
105
+ }
106
+ /**
107
+ * Create a box border line
108
+ * @param leftChar - Left border character
109
+ * @param rightChar - Right border character
110
+ * @param fillChar - Fill character
111
+ * @param width - Total width including borders
112
+ */
113
+ export function createBorderLine(leftChar, rightChar, fillChar, width) {
114
+ const innerWidth = width - stringWidth(leftChar) - stringWidth(rightChar);
115
+ return leftChar + fillChar.repeat(Math.max(0, innerWidth)) + rightChar;
116
+ }
117
+ /**
118
+ * Create a box content line with borders
119
+ * @param content - The content to display
120
+ * @param leftChar - Left border character
121
+ * @param rightChar - Right border character
122
+ * @param width - Total width including borders
123
+ * @param align - Content alignment
124
+ */
125
+ export function createContentLine(content, leftChar, rightChar, width, align = 'left') {
126
+ const borderWidth = stringWidth(leftChar) + stringWidth(rightChar);
127
+ const innerWidth = width - borderWidth;
128
+ const paddedContent = padString(content, innerWidth, ' ', align);
129
+ return leftChar + paddedContent + rightChar;
130
+ }
131
+ //# sourceMappingURL=string-width.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-width.js","sourceRoot":"","sources":["../../src/utils/string-width.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@vibeapi/api-helper",
3
+ "version": "2.0.0",
4
+ "description": "CLI tool for managing AI coding assistants (Claude Code, OpenCode) with Anthropic API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "api-helper": "dist/cli.js",
9
+ "chelper": "dist/cli.js"
10
+ },
11
+ "homepage": "https://www.vibeapi.cn/",
12
+ "bugs": {
13
+ "url": "https://www.vibeapi.cn/support"
14
+ },
15
+ "type": "module",
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc && cp -r src/locales dist/",
29
+ "dev": "tsx watch src/cli.ts",
30
+ "start": "node dist/cli.js",
31
+ "clean": "rm -rf dist",
32
+ "prepublishOnly": "pnpm run clean && pnpm run build",
33
+ "test": "echo \"Error: no test specified\" && exit 1",
34
+ "lint": "eslint .",
35
+ "lint:fix": "eslint . --fix"
36
+ },
37
+ "keywords": [
38
+ "cli",
39
+ "coding",
40
+ "helper",
41
+ "tools",
42
+ "anthropic",
43
+ "claude",
44
+ "ai",
45
+ "assistant",
46
+ "claude-code",
47
+ "opencode"
48
+ ],
49
+ "author": "VibeAPI",
50
+ "license": "UNLICENSED",
51
+ "private": false,
52
+ "packageManager": "pnpm@10.15.0",
53
+ "dependencies": {
54
+ "chalk": "^5.3.0",
55
+ "commander": "^12.1.0",
56
+ "inquirer": "^9.2.12",
57
+ "js-yaml": "^4.1.0",
58
+ "ora": "^8.0.1",
59
+ "terminal-link": "^5.0.0"
60
+ },
61
+ "devDependencies": {
62
+ "@eslint/js": "^9.39.1",
63
+ "@types/inquirer": "^9.0.7",
64
+ "@types/js-yaml": "^4.0.9",
65
+ "@types/node": "^24.10.1",
66
+ "eslint": "^9.39.1",
67
+ "globals": "^16.5.0",
68
+ "nodemon": "^3.1.11",
69
+ "tsx": "^4.20.6",
70
+ "typescript": "^5.9.3",
71
+ "typescript-eslint": "^8.46.4"
72
+ }
73
+ }