@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.
- package/LICENSE +25 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.js +119 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/config.d.ts +1 -0
- package/dist/commands/config.js +130 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +105 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/index.js +5 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/lang.d.ts +1 -0
- package/dist/commands/lang.js +28 -0
- package/dist/commands/lang.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-validator.d.ts +12 -0
- package/dist/lib/api-validator.js +79 -0
- package/dist/lib/api-validator.js.map +1 -0
- package/dist/lib/claude-code-manager.d.ts +86 -0
- package/dist/lib/claude-code-manager.js +233 -0
- package/dist/lib/claude-code-manager.js.map +1 -0
- package/dist/lib/command.d.ts +10 -0
- package/dist/lib/command.js +168 -0
- package/dist/lib/command.js.map +1 -0
- package/dist/lib/config.d.ts +64 -0
- package/dist/lib/config.js +226 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/i18n.d.ts +20 -0
- package/dist/lib/i18n.js +149 -0
- package/dist/lib/i18n.js.map +1 -0
- package/dist/lib/opencode-manager.d.ts +55 -0
- package/dist/lib/opencode-manager.js +134 -0
- package/dist/lib/opencode-manager.js.map +1 -0
- package/dist/lib/tool-manager.d.ts +25 -0
- package/dist/lib/tool-manager.js +280 -0
- package/dist/lib/tool-manager.js.map +1 -0
- package/dist/lib/wizard.d.ts +23 -0
- package/dist/lib/wizard.js +360 -0
- package/dist/lib/wizard.js.map +1 -0
- package/dist/locales/en_US.json +146 -0
- package/dist/locales/zh_CN.json +146 -0
- package/dist/utils/logger.d.ts +55 -0
- package/dist/utils/logger.js +202 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/string-width.d.ts +38 -0
- package/dist/utils/string-width.js +131 -0
- package/dist/utils/string-width.js.map +1 -0
- 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":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACjC,4CAA4C;IAC5C,OAAO,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAY;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IAEpB,wBAAwB;IACxB,IACI,IAAI,KAAK,MAAM,IAAI,mBAAmB;QACtC,IAAI,KAAK,MAAM,IAAI,wBAAwB;QAC3C,IAAI,KAAK,MAAM,IAAI,oBAAoB;QACvC,IAAI,KAAK,MAAM,IAAI,4BAA4B;QAC/C,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,8CAA8C;MACnF,CAAC;QACC,OAAO,CAAC,CAAC;IACb,CAAC;IAED,0CAA0C;IAC1C,kEAAkE;IAClE,IACI,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,gDAAgD;QACxF,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,eAAe;QACvD,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,WAAW;QACnD,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,8BAA8B;QACtE,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,CAAI,gBAAgB;MAC1D,CAAC;QACC,OAAO,CAAC,CAAC;IACb,CAAC;IAED,6CAA6C;IAC7C,qDAAqD;IACrD,IACI,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,yBAAyB;QACjE,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,qCAAqC;QAC7E,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,qCAAqC;QAC7E,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,qCAAqC;QAC7E,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,qCAAqC;QAC7E,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,qCAAqC;QAC7E,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,+BAA+B;QACvE,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,0CAA0C;QAClF,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,WAAW;QACnD,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,WAAW;QACnD,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,mBAAmB;QAC3D,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,cAAc;QACtD,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,4BAA4B;QACpE,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAM,yBAAyB;QACjE,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,CAAM,yBAAyB;MACnE,CAAC;QACC,OAAO,CAAC,CAAC;IACb,CAAC;IAED,uBAAuB;IACvB,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;QACnC,OAAO,CAAC,CAAC;IACb,CAAC;IAED,sDAAsD;IACtD,OAAO,CAAC,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACnC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,oDAAoD;IACpD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,KAAK,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACrB,GAAW,EACX,WAAmB,EACnB,OAAe,GAAG,EAClB,QAAqC,MAAM;IAE3C,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,YAAY,CAAC,CAAC;IACzD,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEtC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,OAAO,GAAG,GAAG,CAAC;IACzB,CAAC;SAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACJ,OAAO,GAAG,GAAG,OAAO,CAAC;IACzB,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC5B,QAAgB,EAChB,SAAiB,EACjB,QAAgB,EAChB,KAAa;IAEb,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IAC1E,OAAO,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;AAC3E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC7B,OAAe,EACf,QAAgB,EAChB,SAAiB,EACjB,KAAa,EACb,QAAqC,MAAM;IAE3C,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC;IACvC,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACjE,OAAO,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AAChD,CAAC"}
|
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
|
+
}
|