@hecom/codearts 0.2.1 → 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/README.md +17 -5
- package/dist/bin/cli.js +40 -18
- package/dist/commands/bug.command.d.ts +0 -2
- package/dist/commands/bug.command.js +104 -60
- package/dist/commands/config.command.js +165 -191
- package/dist/commands/daily.command.d.ts +0 -5
- package/dist/commands/daily.command.js +277 -99
- package/dist/commands/work-hour.command.js +189 -131
- package/dist/constant/index.d.ts +1 -0
- package/dist/constant/index.js +29 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/utils/config-loader.d.ts +9 -6
- package/dist/utils/config-loader.js +19 -14
- package/dist/utils/csv-writer.d.ts +12 -0
- package/dist/utils/csv-writer.js +60 -0
- package/dist/utils/logger.d.ts +62 -0
- package/dist/utils/logger.js +103 -0
- package/package.json +5 -4
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -23
|
@@ -40,11 +40,13 @@ exports.configCommand = configCommand;
|
|
|
40
40
|
exports.updateProjectConfigCommand = updateProjectConfigCommand;
|
|
41
41
|
exports.getAvailableProjectConfigs = getAvailableProjectConfigs;
|
|
42
42
|
exports.showConfigCommand = showConfigCommand;
|
|
43
|
-
const
|
|
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");
|
|
47
48
|
const config_loader_1 = require("../utils/config-loader");
|
|
49
|
+
const logger_1 = require("../utils/logger");
|
|
48
50
|
/**
|
|
49
51
|
* 清除终端上指定行数的内容
|
|
50
52
|
* @param lines 要清除的行数
|
|
@@ -55,76 +57,71 @@ function clearLines(lines) {
|
|
|
55
57
|
readline.clearLine(process.stdout, 0); // 清除当前行
|
|
56
58
|
}
|
|
57
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
|
+
}
|
|
58
74
|
/**
|
|
59
75
|
* 配置角色 ID
|
|
60
76
|
*/
|
|
61
77
|
async function configureRoleIds(businessService, projectId, existingValue) {
|
|
78
|
+
let roles = [];
|
|
62
79
|
try {
|
|
63
|
-
|
|
64
|
-
if (roles.length === 0) {
|
|
65
|
-
// 如果没有获取到角色,使用手动输入
|
|
66
|
-
const { manualRoleId } = await inquirer_1.default.prompt([
|
|
67
|
-
{
|
|
68
|
-
type: 'input',
|
|
69
|
-
name: 'manualRoleId',
|
|
70
|
-
message: '角色 ID(支持逗号分隔,如: 1,2,3):',
|
|
71
|
-
default: existingValue || '',
|
|
72
|
-
validate: (input) => {
|
|
73
|
-
if (!input.trim()) {
|
|
74
|
-
return '角色 ID 不能为空';
|
|
75
|
-
}
|
|
76
|
-
const ids = input.split(',').map((id) => id.trim());
|
|
77
|
-
const allValid = ids.every((id) => /^\d+$/.test(id));
|
|
78
|
-
return allValid ? true : '角色 ID 必须是数字或逗号分隔的数字列表';
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
]);
|
|
82
|
-
return manualRoleId;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
// 使用多选框选择角色
|
|
86
|
-
const roleChoices = roles.map((role) => ({
|
|
87
|
-
name: `${role.role_name} (${role.role_id})`,
|
|
88
|
-
value: role.role_id.toString(),
|
|
89
|
-
checked: existingValue ? existingValue.split(',').includes(role.role_id.toString()) : false,
|
|
90
|
-
}));
|
|
91
|
-
const { selectedRoleIds } = await inquirer_1.default.prompt([
|
|
92
|
-
{
|
|
93
|
-
type: 'checkbox',
|
|
94
|
-
name: 'selectedRoleIds',
|
|
95
|
-
message: '请选择角色:',
|
|
96
|
-
choices: roleChoices,
|
|
97
|
-
validate: (input) => {
|
|
98
|
-
if (input.length === 0) {
|
|
99
|
-
return '至少选择一个角色';
|
|
100
|
-
}
|
|
101
|
-
return true;
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
]);
|
|
105
|
-
return selectedRoleIds.join(',');
|
|
106
|
-
}
|
|
80
|
+
roles = await businessService.getProjectRoles(projectId);
|
|
107
81
|
}
|
|
108
82
|
catch (error) {
|
|
109
|
-
|
|
83
|
+
logger_1.logger.error('❌ 获取角色列表失败:', error);
|
|
110
84
|
// 如果获取失败,使用手动输入
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
+
},
|
|
124
121
|
},
|
|
125
122
|
},
|
|
126
|
-
|
|
127
|
-
return
|
|
123
|
+
});
|
|
124
|
+
return selectedRoleIds.join(',');
|
|
128
125
|
}
|
|
129
126
|
}
|
|
130
127
|
/**
|
|
@@ -144,27 +141,30 @@ const PROJECT_CONFIG_ITEMS = [
|
|
|
144
141
|
// configure: configureCustomField,
|
|
145
142
|
// },
|
|
146
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
|
+
}
|
|
147
151
|
/**
|
|
148
152
|
* 交互式配置向导命令
|
|
149
153
|
* 引导用户创建或更新全局配置文件
|
|
150
154
|
*/
|
|
151
155
|
async function configCommand() {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const existingConfig = (0, config_loader_1.
|
|
157
|
-
if ((0, config_loader_1.
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
message: '检测到已存在全局配置,是否覆盖?',
|
|
163
|
-
default: false,
|
|
164
|
-
},
|
|
165
|
-
]);
|
|
156
|
+
logger_1.logger.info('欢迎使用 Hecom CodeArts 配置向导');
|
|
157
|
+
logger_1.logger.info('='.repeat(60));
|
|
158
|
+
logger_1.logger.info('此向导将帮助您配置华为云 CodeArts API 访问凭证以及项目相关设置');
|
|
159
|
+
logger_1.logger.info(`配置将保存到: ${(0, config_loader_1.getConfigPath)()}\n`);
|
|
160
|
+
const existingConfig = (0, config_loader_1.configExists)() ? (0, config_loader_1.readConfig)() : {};
|
|
161
|
+
if ((0, config_loader_1.configExists)()) {
|
|
162
|
+
const overwrite = await (0, prompts_1.confirm)({
|
|
163
|
+
message: '检测到已存在全局配置,是否覆盖?',
|
|
164
|
+
default: true,
|
|
165
|
+
});
|
|
166
166
|
if (!overwrite) {
|
|
167
|
-
|
|
167
|
+
logger_1.logger.info('\n已取消配置。');
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -180,53 +180,52 @@ async function configCommand() {
|
|
|
180
180
|
password: '',
|
|
181
181
|
};
|
|
182
182
|
while (!credentialsValid) {
|
|
183
|
-
iamAnswers =
|
|
184
|
-
{
|
|
185
|
-
type: 'input',
|
|
186
|
-
name: 'iamEndpoint',
|
|
183
|
+
iamAnswers = {
|
|
184
|
+
iamEndpoint: await (0, prompts_1.input)({
|
|
187
185
|
message: 'IAM 认证端点:',
|
|
188
186
|
default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT] ||
|
|
189
187
|
'https://iam.cn-north-4.myhuaweicloud.com',
|
|
190
|
-
validate: (
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
type: 'input',
|
|
194
|
-
name: 'region',
|
|
188
|
+
validate: (inputValue) => (inputValue.trim() ? true : 'IAM 认证端点不能为空'),
|
|
189
|
+
}),
|
|
190
|
+
region: await (0, prompts_1.input)({
|
|
195
191
|
message: '华为云区域:',
|
|
196
192
|
default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_REGION] || 'cn-north-4',
|
|
197
|
-
validate: (
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
type: 'input',
|
|
201
|
-
name: 'codeartsUrl',
|
|
193
|
+
validate: (inputValue) => (inputValue.trim() ? true : '华为云区域不能为空'),
|
|
194
|
+
}),
|
|
195
|
+
codeartsUrl: await (0, prompts_1.input)({
|
|
202
196
|
message: 'CodeArts API 地址:',
|
|
203
197
|
default: existingConfig[types_1.ConfigKey.CODEARTS_BASE_URL] ||
|
|
204
198
|
'https://projectman-ext.cn-north-4.myhuaweicloud.cn',
|
|
205
|
-
validate: (
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
type: 'input',
|
|
209
|
-
name: 'domain',
|
|
199
|
+
validate: (inputValue) => (inputValue.trim() ? true : 'CodeArts API 地址不能为空'),
|
|
200
|
+
}),
|
|
201
|
+
domain: await (0, prompts_1.input)({
|
|
210
202
|
message: '华为云账号名:',
|
|
211
203
|
default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_DOMAIN] || '',
|
|
212
|
-
validate: (
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
type: 'input',
|
|
216
|
-
name: 'username',
|
|
204
|
+
validate: (inputValue) => (inputValue.trim() ? true : '华为云账号名不能为空'),
|
|
205
|
+
}),
|
|
206
|
+
username: await (0, prompts_1.input)({
|
|
217
207
|
message: 'IAM 用户名:',
|
|
218
208
|
default: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_USERNAME] || '',
|
|
219
|
-
validate: (
|
|
220
|
-
},
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
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
|
+
}
|
|
230
229
|
// 创建 BusinessService 实例
|
|
231
230
|
businessService = new business_service_1.BusinessService({
|
|
232
231
|
iamEndpoint: iamAnswers.iamEndpoint,
|
|
@@ -244,17 +243,13 @@ async function configCommand() {
|
|
|
244
243
|
}
|
|
245
244
|
else {
|
|
246
245
|
const errorMessage = `❌ IAM 凭证验证失败: ${validationResult.error}\n`;
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
message: '是否重新配置 IAM 凭证?',
|
|
253
|
-
default: true,
|
|
254
|
-
},
|
|
255
|
-
]);
|
|
246
|
+
logger_1.logger.error(errorMessage);
|
|
247
|
+
const retry = await (0, prompts_1.confirm)({
|
|
248
|
+
message: '是否重新配置 IAM 凭证?',
|
|
249
|
+
default: true,
|
|
250
|
+
});
|
|
256
251
|
if (!retry) {
|
|
257
|
-
|
|
252
|
+
logger_1.logger.info('\n已取消配置。');
|
|
258
253
|
return;
|
|
259
254
|
}
|
|
260
255
|
// 计算需要清除的行数
|
|
@@ -266,51 +261,39 @@ async function configCommand() {
|
|
|
266
261
|
}
|
|
267
262
|
// 第二阶段:获取项目列表并选择项目
|
|
268
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
|
+
}
|
|
269
272
|
try {
|
|
270
|
-
|
|
271
|
-
if (projects.length === 0) {
|
|
272
|
-
const { manualProjectId } = await inquirer_1.default.prompt([
|
|
273
|
-
{
|
|
274
|
-
type: 'input',
|
|
275
|
-
name: 'manualProjectId',
|
|
276
|
-
message: '项目 ID:',
|
|
277
|
-
default: existingConfig[types_1.ConfigKey.PROJECT_ID] || '',
|
|
278
|
-
validate: (input) => (input.trim() ? true : '项目 ID 不能为空'),
|
|
279
|
-
},
|
|
280
|
-
]);
|
|
281
|
-
projectId = manualProjectId;
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
const projectChoices = projects.map((p) => ({
|
|
285
|
-
name: `${p.project_name} (${p.project_id})`,
|
|
286
|
-
value: p.project_id,
|
|
287
|
-
}));
|
|
288
|
-
const { selectedProjectId } = await inquirer_1.default.prompt([
|
|
289
|
-
{
|
|
290
|
-
type: 'list',
|
|
291
|
-
name: 'selectedProjectId',
|
|
292
|
-
message: '请选择项目:',
|
|
293
|
-
choices: projectChoices,
|
|
294
|
-
default: existingConfig[types_1.ConfigKey.PROJECT_ID] || projectChoices[0]?.value,
|
|
295
|
-
},
|
|
296
|
-
]);
|
|
297
|
-
projectId = selectedProjectId;
|
|
298
|
-
}
|
|
273
|
+
projects = await businessService.getProjects(100);
|
|
299
274
|
}
|
|
300
275
|
catch (error) {
|
|
301
|
-
|
|
302
|
-
console.error('❌ 获取项目列表失败:', errorMsg, '\n');
|
|
276
|
+
logger_1.logger.error(`❌ 获取项目列表失败: `, error);
|
|
303
277
|
// 获取失败,使用手动输入
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
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
|
+
});
|
|
314
297
|
}
|
|
315
298
|
// 第三阶段:配置项目相关配置
|
|
316
299
|
const projectConfigs = {};
|
|
@@ -330,13 +313,13 @@ async function configCommand() {
|
|
|
330
313
|
...projectConfigs,
|
|
331
314
|
};
|
|
332
315
|
try {
|
|
333
|
-
(0, config_loader_1.
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
316
|
+
(0, config_loader_1.writeConfig)(finalConfig);
|
|
317
|
+
logger_1.logger.success('\n✅ 全局配置已成功保存');
|
|
318
|
+
logger_1.logger.info(`配置文件位置: ${(0, config_loader_1.getConfigPath)()}`);
|
|
319
|
+
logger_1.logger.info('\n提示:配置文件包含敏感信息,请妥善保管。');
|
|
337
320
|
}
|
|
338
321
|
catch (error) {
|
|
339
|
-
|
|
322
|
+
logger_1.logger.error('\n❌ 保存配置文件失败:', error);
|
|
340
323
|
process.exit(1);
|
|
341
324
|
}
|
|
342
325
|
}
|
|
@@ -346,32 +329,22 @@ async function configCommand() {
|
|
|
346
329
|
*/
|
|
347
330
|
async function updateProjectConfigCommand(configKey) {
|
|
348
331
|
// 检查配置文件是否存在
|
|
349
|
-
if (!(0, config_loader_1.
|
|
350
|
-
|
|
332
|
+
if (!(0, config_loader_1.configExists)()) {
|
|
333
|
+
logger_1.logger.error('\n❌ 全局配置文件不存在,请先运行 `npx @hecom/codearts config` 创建配置。');
|
|
351
334
|
process.exit(1);
|
|
352
335
|
}
|
|
353
336
|
// 查找对应的配置项
|
|
354
337
|
const configItem = PROJECT_CONFIG_ITEMS.find((item) => item.key === configKey);
|
|
355
338
|
if (!configItem) {
|
|
356
|
-
|
|
357
|
-
|
|
339
|
+
logger_1.logger.error(`\n❌ 未知的配置项: ${configKey}`);
|
|
340
|
+
logger_1.logger.info(`\n可用的配置项:`);
|
|
358
341
|
PROJECT_CONFIG_ITEMS.forEach((item) => {
|
|
359
|
-
|
|
342
|
+
logger_1.logger.info(` - ${item.key}: ${item.label}`);
|
|
360
343
|
});
|
|
361
344
|
process.exit(1);
|
|
362
345
|
}
|
|
363
346
|
// 读取现有配置
|
|
364
|
-
const existingConfig = (0, config_loader_1.
|
|
365
|
-
// 检查必要的配置是否存在
|
|
366
|
-
if (!existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_USERNAME] ||
|
|
367
|
-
!existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD]) {
|
|
368
|
-
console.error('\n❌ 全局配置不完整,请先运行 `npx @hecom/codearts config` 完成配置。');
|
|
369
|
-
process.exit(1);
|
|
370
|
-
}
|
|
371
|
-
if (!existingConfig[types_1.ConfigKey.PROJECT_ID]) {
|
|
372
|
-
console.error('\n❌ 项目 ID 未配置,请先运行 `npx @hecom/codearts config` 完成配置。');
|
|
373
|
-
process.exit(1);
|
|
374
|
-
}
|
|
347
|
+
const existingConfig = (0, config_loader_1.readConfig)();
|
|
375
348
|
// 创建 BusinessService 实例
|
|
376
349
|
const businessService = new business_service_1.BusinessService({
|
|
377
350
|
iamEndpoint: existingConfig[types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT],
|
|
@@ -390,12 +363,12 @@ async function updateProjectConfigCommand(configKey) {
|
|
|
390
363
|
[configKey]: newValue,
|
|
391
364
|
};
|
|
392
365
|
try {
|
|
393
|
-
(0, config_loader_1.
|
|
394
|
-
|
|
395
|
-
|
|
366
|
+
(0, config_loader_1.writeConfig)(updatedConfig);
|
|
367
|
+
logger_1.logger.success(`\n✅ ${configItem.label}已成功更新`);
|
|
368
|
+
logger_1.logger.info(`配置文件位置: ${(0, config_loader_1.getConfigPath)()}`);
|
|
396
369
|
}
|
|
397
370
|
catch (error) {
|
|
398
|
-
|
|
371
|
+
logger_1.logger.error('\n❌ 保存配置文件失败:', error);
|
|
399
372
|
process.exit(1);
|
|
400
373
|
}
|
|
401
374
|
}
|
|
@@ -413,7 +386,7 @@ async function showConfigCommand() {
|
|
|
413
386
|
// 获取最终合并后的配置
|
|
414
387
|
const config = (0, config_loader_1.getConfig)();
|
|
415
388
|
// 按类别显示配置
|
|
416
|
-
|
|
389
|
+
logger_1.logger.info(picocolors_1.default.cyan('【华为云 IAM 凭证】'));
|
|
417
390
|
const iamKeys = [
|
|
418
391
|
types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT,
|
|
419
392
|
types_1.ConfigKey.HUAWEI_CLOUD_REGION,
|
|
@@ -424,9 +397,10 @@ async function showConfigCommand() {
|
|
|
424
397
|
for (const key of iamKeys) {
|
|
425
398
|
const value = config[key] || '(未配置)';
|
|
426
399
|
const displayValue = key.includes('PASSWORD') && value !== '(未配置)' ? '********' : value;
|
|
427
|
-
|
|
400
|
+
logger_1.logger.info(` ${formatKeyName(key)}: ${displayValue}`);
|
|
428
401
|
}
|
|
429
|
-
|
|
402
|
+
logger_1.logger.info();
|
|
403
|
+
logger_1.logger.info(picocolors_1.default.cyanBright('【CodeArts 配置】'));
|
|
430
404
|
const codeartsKeys = [
|
|
431
405
|
types_1.ConfigKey.CODEARTS_BASE_URL,
|
|
432
406
|
types_1.ConfigKey.PROJECT_ID,
|
|
@@ -434,7 +408,7 @@ async function showConfigCommand() {
|
|
|
434
408
|
];
|
|
435
409
|
for (const key of codeartsKeys) {
|
|
436
410
|
const value = config[key] || '(未配置)';
|
|
437
|
-
|
|
411
|
+
logger_1.logger.info(` ${formatKeyName(key)}: ${value}`);
|
|
438
412
|
}
|
|
439
413
|
}
|
|
440
414
|
/**
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { BusinessService } from '../services/business.service';
|
|
2
1
|
import { CliOptions } from '../utils/config-loader';
|
|
3
|
-
/**
|
|
4
|
-
* 生成单个角色的日报
|
|
5
|
-
*/
|
|
6
|
-
export declare function generateDailyReport(businessService: BusinessService, projectId: string, roleId: number, targetDate: string): Promise<void>;
|
|
7
2
|
/**
|
|
8
3
|
* daily 命令入口
|
|
9
4
|
*/
|