@hecom/codearts 0.2.2 → 0.2.3

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/dist/bin/cli.js CHANGED
@@ -41,6 +41,7 @@ const bug_command_1 = require("../commands/bug.command");
41
41
  const config_command_1 = require("../commands/config.command");
42
42
  const daily_command_1 = require("../commands/daily.command");
43
43
  const work_hour_command_1 = require("../commands/work-hour.command");
44
+ const constant_1 = require("../constant");
44
45
  const config_loader_1 = require("../utils/config-loader");
45
46
  const logger_1 = require("../utils/logger");
46
47
  // 读取 package.json 中的版本号
@@ -58,6 +59,7 @@ const configCmd = program
58
59
  .command('config')
59
60
  .description('交互式配置向导,引导用户创建或更新全局配置文件')
60
61
  .action(async () => {
62
+ (0, constant_1.showLogo)();
61
63
  await (0, config_command_1.configCommand)();
62
64
  });
63
65
  // config show 子命令 - 显示当前配置
@@ -65,6 +67,7 @@ configCmd
65
67
  .command('show')
66
68
  .description('显示当前配置信息')
67
69
  .action(async () => {
70
+ (0, constant_1.showLogo)();
68
71
  await (0, config_command_1.showConfigCommand)();
69
72
  });
70
73
  // 为每个项目配置项添加子命令
@@ -75,6 +78,7 @@ availableConfigs.forEach((configItem) => {
75
78
  .command(subCommandName)
76
79
  .description(`更新${configItem.label}`)
77
80
  .action(async () => {
81
+ (0, constant_1.showLogo)();
78
82
  await (0, config_command_1.updateProjectConfigCommand)(configItem.key);
79
83
  });
80
84
  });
@@ -111,6 +115,7 @@ async function checkConfigAndRun() {
111
115
  const args = process.argv.slice(2);
112
116
  // 如果没有参数(直接执行 codearts),检测配置
113
117
  if (args.length === 0) {
118
+ (0, constant_1.showLogo)();
114
119
  // 检查是否有全局配置
115
120
  const hasConfig = (0, config_loader_1.configExists)();
116
121
  if (!hasConfig) {
@@ -125,6 +130,16 @@ async function checkConfigAndRun() {
125
130
  // 有参数,正常解析命令
126
131
  program.parse();
127
132
  }
133
+ process.on('uncaughtException', (error) => {
134
+ if (error instanceof Error && error.name === 'ExitPromptError') {
135
+ console.log('👋 操作取消!');
136
+ process.exit(0);
137
+ }
138
+ else {
139
+ // 重新抛出未知错误
140
+ throw error;
141
+ }
142
+ });
128
143
  checkConfigAndRun().catch((error) => {
129
144
  logger_1.logger.error('执行失败: ', error);
130
145
  process.exit(1);
@@ -40,7 +40,8 @@ exports.configCommand = configCommand;
40
40
  exports.updateProjectConfigCommand = updateProjectConfigCommand;
41
41
  exports.getAvailableProjectConfigs = getAvailableProjectConfigs;
42
42
  exports.showConfigCommand = showConfigCommand;
43
- const inquirer_1 = __importDefault(require("inquirer"));
43
+ const prompts_1 = require("@inquirer/prompts");
44
+ const picocolors_1 = __importDefault(require("picocolors"));
44
45
  const readline = __importStar(require("readline"));
45
46
  const business_service_1 = require("../services/business.service");
46
47
  const types_1 = require("../types");
@@ -56,76 +57,71 @@ function clearLines(lines) {
56
57
  readline.clearLine(process.stdout, 0); // 清除当前行
57
58
  }
58
59
  }
60
+ async function inputRoleIds(existingValue) {
61
+ return await (0, prompts_1.input)({
62
+ message: '角色 ID(支持逗号分隔,如: 1,2,3):',
63
+ default: existingValue || '',
64
+ validate: (inputValue) => {
65
+ if (!inputValue.trim()) {
66
+ return '角色 ID 不能为空';
67
+ }
68
+ const ids = inputValue.split(',').map((id) => id.trim());
69
+ const allValid = ids.every((id) => /^\d+$/.test(id));
70
+ return allValid ? true : '角色 ID 必须是数字或逗号分隔的数字列表';
71
+ },
72
+ });
73
+ }
59
74
  /**
60
75
  * 配置角色 ID
61
76
  */
62
77
  async function configureRoleIds(businessService, projectId, existingValue) {
78
+ let roles = [];
63
79
  try {
64
- const roles = await businessService.getProjectRoles(projectId);
65
- if (roles.length === 0) {
66
- // 如果没有获取到角色,使用手动输入
67
- const { manualRoleId } = await inquirer_1.default.prompt([
68
- {
69
- type: 'input',
70
- name: 'manualRoleId',
71
- message: '角色 ID(支持逗号分隔,如: 1,2,3):',
72
- default: existingValue || '',
73
- validate: (input) => {
74
- if (!input.trim()) {
75
- return '角色 ID 不能为空';
76
- }
77
- const ids = input.split(',').map((id) => id.trim());
78
- const allValid = ids.every((id) => /^\d+$/.test(id));
79
- return allValid ? true : '角色 ID 必须是数字或逗号分隔的数字列表';
80
- },
81
- },
82
- ]);
83
- return manualRoleId;
84
- }
85
- else {
86
- // 使用多选框选择角色
87
- const roleChoices = roles.map((role) => ({
88
- name: `${role.role_name} (${role.role_id})`,
89
- value: role.role_id.toString(),
90
- checked: existingValue ? existingValue.split(',').includes(role.role_id.toString()) : false,
91
- }));
92
- const { selectedRoleIds } = await inquirer_1.default.prompt([
93
- {
94
- type: 'checkbox',
95
- name: 'selectedRoleIds',
96
- message: '请选择角色:',
97
- choices: roleChoices,
98
- validate: (input) => {
99
- if (input.length === 0) {
100
- return '至少选择一个角色';
101
- }
102
- return true;
103
- },
104
- },
105
- ]);
106
- return selectedRoleIds.join(',');
107
- }
80
+ roles = await businessService.getProjectRoles(projectId);
108
81
  }
109
82
  catch (error) {
110
83
  logger_1.logger.error('❌ 获取角色列表失败:', error);
111
84
  // 如果获取失败,使用手动输入
112
- const { manualRoleId } = await inquirer_1.default.prompt([
113
- {
114
- type: 'input',
115
- name: 'manualRoleId',
116
- message: '角色 ID(支持逗号分隔,如: 1,2,3):',
117
- default: existingValue || '',
118
- validate: (input) => {
119
- if (!input.trim()) {
120
- return '角色 ID 不能为空';
121
- }
122
- const ids = input.split(',').map((id) => id.trim());
123
- const allValid = ids.every((id) => /^\d+$/.test(id));
124
- return allValid ? true : '角色 ID 必须是数字或逗号分隔的数字列表';
85
+ return await inputRoleIds(existingValue);
86
+ }
87
+ if (roles.length === 0) {
88
+ // 如果没有获取到角色,使用手动输入
89
+ return await inputRoleIds(existingValue);
90
+ }
91
+ else {
92
+ // 使用多选框选择角色
93
+ const roleChoices = roles.map((role) => ({
94
+ name: `${role.role_name} (${role.role_id})`,
95
+ value: role.role_id.toString(),
96
+ checked: existingValue ? existingValue.split(',').includes(role.role_id.toString()) : false,
97
+ }));
98
+ const selectedRoleIds = await (0, prompts_1.checkbox)({
99
+ message: '请选择角色:',
100
+ choices: roleChoices,
101
+ validate: (answer) => {
102
+ if (answer.length === 0) {
103
+ return '至少需要选择一个角色';
104
+ }
105
+ return true;
106
+ },
107
+ theme: {
108
+ style: {
109
+ help: (text) => `\x1b[90m${123}\x1b[0m`, // 灰色
110
+ keysHelpTip: (keys) => {
111
+ const actionMap = {
112
+ navigate: '上下移动',
113
+ select: '选择/取消',
114
+ all: '全选',
115
+ invert: '反选',
116
+ submit: '提交',
117
+ };
118
+ const tips = keys.map(([key, action]) => `${key} \x1b[90m${actionMap[action] || action}\x1b[0m`);
119
+ return tips.join(' • ');
120
+ },
125
121
  },
126
122
  },
127
- ]);
128
- return manualRoleId;
123
+ });
124
+ return selectedRoleIds.join(',');
129
125
  }
130
126
  }
131
127
  /**
@@ -145,25 +141,28 @@ const PROJECT_CONFIG_ITEMS = [
145
141
  // configure: configureCustomField,
146
142
  // },
147
143
  ];
144
+ async function inputPassword() {
145
+ return await (0, prompts_1.password)({
146
+ message: 'IAM 密码:',
147
+ mask: '*',
148
+ validate: (inputValue) => (inputValue.trim() ? true : 'IAM 密码不能为空'),
149
+ });
150
+ }
148
151
  /**
149
152
  * 交互式配置向导命令
150
153
  * 引导用户创建或更新全局配置文件
151
154
  */
152
155
  async function configCommand() {
153
- logger_1.logger.info('\n欢迎使用 Hecom CodeArts 配置向导');
156
+ logger_1.logger.info('欢迎使用 Hecom CodeArts 配置向导');
154
157
  logger_1.logger.info('='.repeat(60));
155
- logger_1.logger.info('此向导将帮助您配置华为云 CodeArts API 访问凭证。');
158
+ logger_1.logger.info('此向导将帮助您配置华为云 CodeArts API 访问凭证以及项目相关设置');
156
159
  logger_1.logger.info(`配置将保存到: ${(0, config_loader_1.getConfigPath)()}\n`);
157
160
  const existingConfig = (0, config_loader_1.configExists)() ? (0, config_loader_1.readConfig)() : {};
158
161
  if ((0, config_loader_1.configExists)()) {
159
- const { overwrite } = await inquirer_1.default.prompt([
160
- {
161
- type: 'confirm',
162
- name: 'overwrite',
163
- message: '检测到已存在全局配置,是否覆盖?',
164
- default: false,
165
- },
166
- ]);
162
+ const overwrite = await (0, prompts_1.confirm)({
163
+ message: '检测到已存在全局配置,是否覆盖?',
164
+ default: true,
165
+ });
167
166
  if (!overwrite) {
168
167
  logger_1.logger.info('\n已取消配置。');
169
168
  return;
@@ -181,53 +180,52 @@ async function configCommand() {
181
180
  password: '',
182
181
  };
183
182
  while (!credentialsValid) {
184
- iamAnswers = await inquirer_1.default.prompt([
185
- {
186
- type: 'input',
187
- name: 'iamEndpoint',
183
+ iamAnswers = {
184
+ iamEndpoint: await (0, prompts_1.input)({
188
185
  message: 'IAM 认证端点:',
189
186
  default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT] ||
190
187
  'https://iam.cn-north-4.myhuaweicloud.com',
191
- validate: (input) => (input.trim() ? true : 'IAM 认证端点不能为空'),
192
- },
193
- {
194
- type: 'input',
195
- name: 'region',
188
+ validate: (inputValue) => (inputValue.trim() ? true : 'IAM 认证端点不能为空'),
189
+ }),
190
+ region: await (0, prompts_1.input)({
196
191
  message: '华为云区域:',
197
192
  default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_REGION] || 'cn-north-4',
198
- validate: (input) => (input.trim() ? true : '华为云区域不能为空'),
199
- },
200
- {
201
- type: 'input',
202
- name: 'codeartsUrl',
193
+ validate: (inputValue) => (inputValue.trim() ? true : '华为云区域不能为空'),
194
+ }),
195
+ codeartsUrl: await (0, prompts_1.input)({
203
196
  message: 'CodeArts API 地址:',
204
197
  default: existingConfig[types_1.ConfigKey.CODEARTS_BASE_URL] ||
205
198
  'https://projectman-ext.cn-north-4.myhuaweicloud.cn',
206
- validate: (input) => (input.trim() ? true : 'CodeArts API 地址不能为空'),
207
- },
208
- {
209
- type: 'input',
210
- name: 'domain',
199
+ validate: (inputValue) => (inputValue.trim() ? true : 'CodeArts API 地址不能为空'),
200
+ }),
201
+ domain: await (0, prompts_1.input)({
211
202
  message: '华为云账号名:',
212
203
  default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_DOMAIN] || '',
213
- validate: (input) => (input.trim() ? true : '华为云账号名不能为空'),
214
- },
215
- {
216
- type: 'input',
217
- name: 'username',
204
+ validate: (inputValue) => (inputValue.trim() ? true : '华为云账号名不能为空'),
205
+ }),
206
+ username: await (0, prompts_1.input)({
218
207
  message: 'IAM 用户名:',
219
208
  default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_USERNAME] || '',
220
- validate: (input) => (input.trim() ? true : 'IAM 用户名不能为空'),
221
- },
222
- {
223
- type: 'password',
224
- name: 'password',
225
- message: 'IAM 密码:',
226
- mask: '*',
227
- default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD] || '',
228
- validate: (input) => (input.trim() ? true : 'IAM 密码不能为空'),
229
- },
230
- ]);
209
+ validate: (inputValue) => (inputValue.trim() ? true : 'IAM 用户名不能为空'),
210
+ }),
211
+ password: '',
212
+ };
213
+ // 处理密码:如果存在旧密码,询问是否重用
214
+ if (existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD]) {
215
+ const useExistingPassword = await (0, prompts_1.confirm)({
216
+ message: 'IAM 密码: 是否使用已保存的密码?',
217
+ default: true,
218
+ });
219
+ if (useExistingPassword) {
220
+ iamAnswers.password = existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD];
221
+ }
222
+ else {
223
+ iamAnswers.password = await inputPassword();
224
+ }
225
+ }
226
+ else {
227
+ iamAnswers.password = await inputPassword();
228
+ }
231
229
  // 创建 BusinessService 实例
232
230
  businessService = new business_service_1.BusinessService({
233
231
  iamEndpoint: iamAnswers.iamEndpoint,
@@ -246,14 +244,10 @@ async function configCommand() {
246
244
  else {
247
245
  const errorMessage = `❌ IAM 凭证验证失败: ${validationResult.error}\n`;
248
246
  logger_1.logger.error(errorMessage);
249
- const { retry } = await inquirer_1.default.prompt([
250
- {
251
- type: 'confirm',
252
- name: 'retry',
253
- message: '是否重新配置 IAM 凭证?',
254
- default: true,
255
- },
256
- ]);
247
+ const retry = await (0, prompts_1.confirm)({
248
+ message: '是否重新配置 IAM 凭证?',
249
+ default: true,
250
+ });
257
251
  if (!retry) {
258
252
  logger_1.logger.info('\n已取消配置。');
259
253
  return;
@@ -267,51 +261,39 @@ async function configCommand() {
267
261
  }
268
262
  // 第二阶段:获取项目列表并选择项目
269
263
  let projectId;
264
+ let projects = [];
265
+ async function inputProjectId() {
266
+ return await (0, prompts_1.input)({
267
+ message: '项目 ID:',
268
+ default: existingConfig[types_1.ConfigKey.PROJECT_ID] || '',
269
+ validate: (inputValue) => (inputValue.trim() ? true : '项目 ID 不能为空'),
270
+ });
271
+ }
270
272
  try {
271
- const projects = await businessService.getProjects(100);
272
- if (projects.length === 0) {
273
- const { manualProjectId } = await inquirer_1.default.prompt([
274
- {
275
- type: 'input',
276
- name: 'manualProjectId',
277
- message: '项目 ID:',
278
- default: existingConfig[types_1.ConfigKey.PROJECT_ID] || '',
279
- validate: (input) => (input.trim() ? true : '项目 ID 不能为空'),
280
- },
281
- ]);
282
- projectId = manualProjectId;
283
- }
284
- else {
285
- const projectChoices = projects.map((p) => ({
286
- name: `${p.project_name} (${p.project_id})`,
287
- value: p.project_id,
288
- }));
289
- const { selectedProjectId } = await inquirer_1.default.prompt([
290
- {
291
- type: 'list',
292
- name: 'selectedProjectId',
293
- message: '请选择项目:',
294
- choices: projectChoices,
295
- default: existingConfig[types_1.ConfigKey.PROJECT_ID] || projectChoices[0]?.value,
296
- },
297
- ]);
298
- projectId = selectedProjectId;
299
- }
273
+ projects = await businessService.getProjects(100);
300
274
  }
301
275
  catch (error) {
302
- const errorMsg = error instanceof Error ? error.message : String(error);
303
276
  logger_1.logger.error(`❌ 获取项目列表失败: `, error);
304
277
  // 获取失败,使用手动输入
305
- const { manualProjectId } = await inquirer_1.default.prompt([
306
- {
307
- type: 'input',
308
- name: 'manualProjectId',
309
- message: '项目 ID:',
310
- default: existingConfig[types_1.ConfigKey.PROJECT_ID] || '',
311
- validate: (input) => (input.trim() ? true : '项目 ID 不能为空'),
312
- },
313
- ]);
314
- projectId = manualProjectId;
278
+ projectId = await inputProjectId();
279
+ }
280
+ if (projects.length === 0) {
281
+ projectId = await inputProjectId();
282
+ }
283
+ else {
284
+ const projectChoices = projects.map((p) => ({
285
+ name: `${p.project_name} (${p.project_id})`,
286
+ value: p.project_id,
287
+ }));
288
+ // 确定默认项目 ID
289
+ const existingProjectId = existingConfig[types_1.ConfigKey.PROJECT_ID];
290
+ const isExistingProjectValid = existingProjectId && projects.some((p) => p.project_id === existingProjectId);
291
+ const defaultProjectId = isExistingProjectValid ? existingProjectId : projectChoices[0]?.value;
292
+ projectId = await (0, prompts_1.select)({
293
+ message: '请选择项目:',
294
+ choices: projectChoices,
295
+ default: defaultProjectId,
296
+ });
315
297
  }
316
298
  // 第三阶段:配置项目相关配置
317
299
  const projectConfigs = {};
@@ -363,16 +345,6 @@ async function updateProjectConfigCommand(configKey) {
363
345
  }
364
346
  // 读取现有配置
365
347
  const existingConfig = (0, config_loader_1.readConfig)();
366
- // 检查必要的配置是否存在
367
- if (!existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_USERNAME] ||
368
- !existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD]) {
369
- logger_1.logger.error('\n❌ 全局配置不完整,请先运行 `npx @hecom/codearts config` 完成配置。');
370
- process.exit(1);
371
- }
372
- if (!existingConfig[types_1.ConfigKey.PROJECT_ID]) {
373
- logger_1.logger.error('\n❌ 项目 ID 未配置,请先运行 `npx @hecom/codearts config` 完成配置。');
374
- process.exit(1);
375
- }
376
348
  // 创建 BusinessService 实例
377
349
  const businessService = new business_service_1.BusinessService({
378
350
  iamEndpoint: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT],
@@ -414,7 +386,7 @@ async function showConfigCommand() {
414
386
  // 获取最终合并后的配置
415
387
  const config = (0, config_loader_1.getConfig)();
416
388
  // 按类别显示配置
417
- logger_1.logger.info('\n【华为云 IAM 凭证】');
389
+ logger_1.logger.info(picocolors_1.default.cyan('【华为云 IAM 凭证】'));
418
390
  const iamKeys = [
419
391
  types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT,
420
392
  types_1.ConfigKey.HUAWEI_CLOUD_REGION,
@@ -427,7 +399,8 @@ async function showConfigCommand() {
427
399
  const displayValue = key.includes('PASSWORD') && value !== '(未配置)' ? '********' : value;
428
400
  logger_1.logger.info(` ${formatKeyName(key)}: ${displayValue}`);
429
401
  }
430
- logger_1.logger.info('\n【CodeArts 配置】');
402
+ logger_1.logger.info();
403
+ logger_1.logger.info(picocolors_1.default.cyanBright('【CodeArts 配置】'));
431
404
  const codeartsKeys = [
432
405
  types_1.ConfigKey.CODEARTS_BASE_URL,
433
406
  types_1.ConfigKey.PROJECT_ID,
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.dailyCommand = dailyCommand;
7
+ const picocolors_1 = __importDefault(require("picocolors"));
4
8
  const business_service_1 = require("../services/business.service");
5
9
  const config_loader_1 = require("../utils/config-loader");
6
10
  const csv_writer_1 = require("../utils/csv-writer");
@@ -165,6 +169,13 @@ async function queryDailyReportData(businessService, projectId, roleId, targetDa
165
169
  totalHours: dailyStats.totalHours,
166
170
  };
167
171
  }
172
+ function issueTypeColor(type) {
173
+ const issueTypeColorMap = {
174
+ 任务: picocolors_1.default.bgCyan,
175
+ 缺陷: picocolors_1.default.bgRed,
176
+ };
177
+ return issueTypeColorMap[type] ? issueTypeColorMap[type](type) : picocolors_1.default.bgGreen(type);
178
+ }
168
179
  /**
169
180
  * 控制台输出日报(多角色统一汇总)
170
181
  */
@@ -195,17 +206,18 @@ function outputConsole(allReports, showReport = false) {
195
206
  // 平铺所有用户的工时明细
196
207
  allReports.forEach((report) => {
197
208
  report.userStats.forEach((userStat) => {
198
- logger_1.logger.info(`\n\x1b[31m${userStat.userName} ${userStat.totalHours}小时\x1b[0m`);
209
+ logger_1.logger.info();
210
+ logger_1.logger.info(picocolors_1.default.red(`${userStat.userName} ${userStat.totalHours}小时`));
199
211
  userStat.workHours
200
212
  .sort((a, b) => a.issueType.localeCompare(b.issueType))
201
213
  .forEach((workHour) => {
202
214
  const summaryPart = workHour.summary && workHour.summary.trim() !== ''
203
- ? ` \x1b[36m${workHour.summary}\x1b[0m`
215
+ ? picocolors_1.default.cyan(` ${workHour.summary}`)
204
216
  : '';
205
217
  const workHoursTypePart = workHour.workHoursTypeName
206
218
  ? ` (${workHour.workHoursTypeName})`
207
219
  : '';
208
- logger_1.logger.info(` [${workHour.issueType}]${workHour.subject}${summaryPart} ${workHoursTypePart} ${workHour.workHoursNum}小时`);
220
+ logger_1.logger.info(` ${issueTypeColor(workHour.issueType)} ${workHour.subject}${summaryPart} ${workHoursTypePart} ${workHour.workHoursNum}小时`);
209
221
  });
210
222
  });
211
223
  });
@@ -0,0 +1 @@
1
+ export declare function showLogo(): void;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.showLogo = showLogo;
4
+ const logger_1 = require("../utils/logger");
5
+ const LOGO_LINES = [
6
+ '██╗ ██╗███████╗ ██████╗ ██████╗ ███╗ ███╗',
7
+ '██║ ██║██╔════╝██╔════╝██╔═══██╗████╗ ████║',
8
+ '███████║█████╗ ██║ ██║ ██║██╔████╔██║',
9
+ '██╔══██║██╔══╝ ██║ ██║ ██║██║╚██╔╝██║',
10
+ '██║ ██║███████╗╚██████╗╚██████╔╝██║ ╚═╝ ██║',
11
+ '╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝',
12
+ ];
13
+ const RESET = '\x1b[0m';
14
+ // 256-color middle grays - visible on both light and dark backgrounds
15
+ const GRAYS = [
16
+ '\x1b[38;5;250m', // lighter gray
17
+ '\x1b[38;5;248m',
18
+ '\x1b[38;5;245m', // mid gray
19
+ '\x1b[38;5;243m',
20
+ '\x1b[38;5;240m',
21
+ '\x1b[38;5;238m', // darker gray
22
+ ];
23
+ function showLogo() {
24
+ logger_1.logger.info();
25
+ LOGO_LINES.forEach((line, i) => {
26
+ logger_1.logger.info(`${GRAYS[i]}${line}${RESET}`);
27
+ });
28
+ logger_1.logger.info();
29
+ }
@@ -22,7 +22,7 @@ export declare class Logger {
22
22
  * 信息日志(输出到 stdout)
23
23
  * json 模式下会被静默
24
24
  */
25
- info(message: string, ...optionalParams: any[]): void;
25
+ info(message?: string, ...optionalParams: any[]): void;
26
26
  /**
27
27
  * 警告日志(输出到 stdout)
28
28
  * json 模式下会被静默
@@ -33,7 +33,12 @@ class Logger {
33
33
  */
34
34
  info(message, ...optionalParams) {
35
35
  if (!this.silent) {
36
- console.log(message, ...optionalParams);
36
+ if (message) {
37
+ console.log(message, ...optionalParams);
38
+ }
39
+ else {
40
+ console.log();
41
+ }
37
42
  }
38
43
  }
39
44
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hecom/codearts",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "华为云 CodeArts 统计分析工具",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -45,14 +45,15 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "axios": "^1.5.0",
48
- "commander": "^12.1.0",
49
- "inquirer": "^9.3.8"
48
+ "commander": "^14.0.3",
49
+ "inquirer": "^13.2.2",
50
+ "picocolors": "^1.1.1"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/commander": "^2.12.0",
53
54
  "@types/inquirer": "^9.0.9",
54
55
  "@types/jest": "^29.5.5",
55
- "@types/node": "^20.6.3",
56
+ "@types/node": "^20.19.33",
56
57
  "@typescript-eslint/eslint-plugin": "^6.7.2",
57
58
  "@typescript-eslint/parser": "^6.7.2",
58
59
  "eslint": "^8.49.0",
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export { ApiService } from './services/api.service';
2
- export { BusinessService } from './services/business.service';
3
- export * from './types';
package/dist/index.js DELETED
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.BusinessService = exports.ApiService = void 0;
18
- // 导出API服务和类型定义
19
- var api_service_1 = require("./services/api.service");
20
- Object.defineProperty(exports, "ApiService", { enumerable: true, get: function () { return api_service_1.ApiService; } });
21
- var business_service_1 = require("./services/business.service");
22
- Object.defineProperty(exports, "BusinessService", { enumerable: true, get: function () { return business_service_1.BusinessService; } });
23
- __exportStar(require("./types"), exports);