@meet-im/lxcli 0.0.11 → 0.0.13
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/commands/services/kb/handler.d.ts +4 -0
- package/dist/commands/services/kb/handler.js +16 -0
- package/dist/commands/services/kb/index.js +4 -0
- package/dist/commands/services/kb/params.js +7 -3
- package/dist/commands/services/kb/skill-metadata.js +1 -1
- package/dist/commands/users.js +12 -1
- package/dist/core/config.d.ts +1 -0
- package/dist/core/config.js +13 -0
- package/dist/core/error.d.ts +9 -0
- package/dist/core/error.js +1 -0
- package/package.json +1 -1
|
@@ -16,5 +16,9 @@ export interface KbCommandOptions {
|
|
|
16
16
|
gateway?: string;
|
|
17
17
|
file?: string;
|
|
18
18
|
out?: string;
|
|
19
|
+
with_subtasks?: string;
|
|
20
|
+
with_files?: string;
|
|
21
|
+
with_comments?: string;
|
|
22
|
+
with_links?: string;
|
|
19
23
|
}
|
|
20
24
|
export declare function createKbAction(method: Method): (options: KbCommandOptions) => Promise<void>;
|
|
@@ -86,6 +86,22 @@ export function createKbAction(method) {
|
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
88
|
params = { task_id: taskId };
|
|
89
|
+
const withParams = {
|
|
90
|
+
with_subtasks: options.with_subtasks,
|
|
91
|
+
with_files: options.with_files,
|
|
92
|
+
with_comments: options.with_comments,
|
|
93
|
+
with_links: options.with_links,
|
|
94
|
+
};
|
|
95
|
+
for (const [key, value] of Object.entries(withParams)) {
|
|
96
|
+
if (value !== undefined) {
|
|
97
|
+
const num = parseTaskId(value);
|
|
98
|
+
if (num === null) {
|
|
99
|
+
outputCliError('PARAM_INVALID', `--${key} must be a positive integer`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
params[key] = num;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
89
105
|
}
|
|
90
106
|
else if (method === 'createTask' && options.title && options.project_id) {
|
|
91
107
|
const projectId = parseTaskId(options.project_id);
|
|
@@ -35,6 +35,10 @@ const kbService = {
|
|
|
35
35
|
.description(METHOD_DESCRIPTIONS.getTask)
|
|
36
36
|
.option('--params <json>', 'JSON/JSON5 params; CLI fills jsonrpc/method/id')
|
|
37
37
|
.option('--task_id <id>', 'Task ID (shortcut for --params \'{"task_id": <id>}\')')
|
|
38
|
+
.option('--with_subtasks <page>', 'Include subtasks page (1-based, shortcut)')
|
|
39
|
+
.option('--with_files <page>', 'Include files page (1-based, shortcut)')
|
|
40
|
+
.option('--with_comments <page>', 'Include comments page (1-based, shortcut)')
|
|
41
|
+
.option('--with_links <page>', 'Include links page (1-based, shortcut)')
|
|
38
42
|
.option('--user <user>', 'Specify user')
|
|
39
43
|
.option('--gateway <url>', 'Override kanboard gateway')
|
|
40
44
|
.action(createKbAction('getTask'));
|
|
@@ -10,6 +10,10 @@ export const PARAM_DEFS = {
|
|
|
10
10
|
// 查询方法
|
|
11
11
|
getTask: [
|
|
12
12
|
{ name: 'task_id', type: 'integer', required: true, description: '需求/bug ID' },
|
|
13
|
+
{ name: 'with_subtasks', type: 'integer', required: false, description: '子任务页码。默认 0 不返回子任务;传入大于 0 的页码时,在响应中追加当前页 subtasks,每页最多 30 条。' },
|
|
14
|
+
{ name: 'with_files', type: 'integer', required: false, description: '需求附件页码。默认 0 不返回附件;传入大于 0 的页码时,在响应中追加当前页 files,每页最多 30 条。' },
|
|
15
|
+
{ name: 'with_comments', type: 'integer', required: false, description: '评论页码。默认 0 不返回评论;传入大于 0 的页码时,在响应中追加当前页 comments,每页最多 30 条。' },
|
|
16
|
+
{ name: 'with_links', type: 'integer', required: false, description: '关联需求/bug 页码。默认 0 不返回关联;传入大于 0 的页码时,在响应中追加当前页 links,每页最多 30 条。' },
|
|
13
17
|
],
|
|
14
18
|
queryUsers: [
|
|
15
19
|
{ name: 'user_ids', type: 'array<integer>', required: false, description: 'Kanboard 用户 ID 列表,例如 [18, 23]' },
|
|
@@ -45,7 +49,7 @@ export const PARAM_DEFS = {
|
|
|
45
49
|
{ name: 'iteration_id', type: 'integer', required: false, description: '迭代 ID;未传或为 0 时由服务端选择需求池或首个迭代。' },
|
|
46
50
|
{ name: 'date_due', type: 'string', required: false, description: '截止日期,建议使用 YYYY-MM-DD' },
|
|
47
51
|
{ name: 'date_started', type: 'string', required: false, description: '开始日期,建议使用 YYYY-MM-DD' },
|
|
48
|
-
{ name: 'priority', type: 'integer', required: false, description: '
|
|
52
|
+
{ name: 'priority', type: 'integer', required: false, description: '优先级:0 高、1 中、2 低,其他值为无关紧要' },
|
|
49
53
|
{ name: 'score', type: 'integer', required: false, description: '复杂度/分值' },
|
|
50
54
|
{ name: 'tags', type: 'array<string>', required: false, description: '标签列表,例如 ["Meet", "Sky", "Co"]' },
|
|
51
55
|
{ name: 'cc_id', type: 'array<string>', required: false, description: '抄送人列表。数组元素格式为 用户ID-用户名称,例如 ["22-Alice", "33-Bob"];未传时不设置抄送人。' },
|
|
@@ -70,9 +74,9 @@ export const PARAM_DEFS = {
|
|
|
70
74
|
{ name: 'iteration_id', type: 'integer', required: false, description: '迭代 ID。传入后修改需求/bug 所属迭代;未传时保持原迭代不变。' },
|
|
71
75
|
{ name: 'date_due', type: 'string', required: false, description: '截止日期,建议使用 YYYY-MM-DD' },
|
|
72
76
|
{ name: 'date_started', type: 'string', required: false, description: '开始日期,建议使用 YYYY-MM-DD' },
|
|
73
|
-
{ name: 'priority', type: 'integer', required: false, description: '
|
|
77
|
+
{ name: 'priority', type: 'integer', required: false, description: '优先级:0 高、1 中、2 低,其他值为无关紧要' },
|
|
74
78
|
{ name: 'score', type: 'integer', required: false, description: '复杂度/分值' },
|
|
75
|
-
{ name: 'color_id', type: 'string', required: false, description: '颜色 ID
|
|
79
|
+
{ name: 'color_id', type: 'string', required: false, description: '颜色 ID:yellow、blue、green、purple、red、orange、grey、greyhound、mint green、pinkteal、brown、deep orange、cyan、lime' },
|
|
76
80
|
{ name: 'reference', type: 'string', required: false, description: '外部引用编号' },
|
|
77
81
|
{ name: 'tags', type: 'array<string>', required: false, description: '标签列表,例如 ["Meet", "Sky", "Co"]' },
|
|
78
82
|
{ name: 'cc_id', type: 'array<string>', required: false, description: '抄送人列表。数组元素格式为 用户ID-用户名称,例如 ["22-Alice", "33-Bob"];传空数组 [] 表示清空抄送人,未传则保持不变。' },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const METHOD_SHORTCUT_PARAMS = {
|
|
2
|
-
getTask: ['task_id'],
|
|
2
|
+
getTask: ['task_id', 'with_subtasks', 'with_files', 'with_comments', 'with_links'],
|
|
3
3
|
createTask: ['title', 'project_id'],
|
|
4
4
|
searchTasks: ['project_id', 'query'],
|
|
5
5
|
searchSubtasks: ['project_id', 'iteration_id', 'user_id', 'page'],
|
package/dist/commands/users.js
CHANGED
|
@@ -138,6 +138,7 @@ export function registerUsersCommand(program) {
|
|
|
138
138
|
.description('Update user configuration (id: name or name@tenant)')
|
|
139
139
|
.option('--token <token>', 'Update authentication token')
|
|
140
140
|
.option('-e, --env <env>', `Update environment (${ENVIRONMENTS.join(', ')})`)
|
|
141
|
+
.option('--name <name>', 'Update user name (changes id to name@tenant)')
|
|
141
142
|
.action((id, options) => {
|
|
142
143
|
if (!id.includes('@')) {
|
|
143
144
|
const matches = findUsersByName(id);
|
|
@@ -164,13 +165,23 @@ export function registerUsersCommand(program) {
|
|
|
164
165
|
validEnvs: [...ENVIRONMENTS],
|
|
165
166
|
});
|
|
166
167
|
}
|
|
168
|
+
if (options.name !== undefined) {
|
|
169
|
+
if (!options.name.trim()) {
|
|
170
|
+
outputCliError('PARAM_INVALID', 'Name cannot be empty', { value: options.name });
|
|
171
|
+
}
|
|
172
|
+
if (options.name.includes('@')) {
|
|
173
|
+
outputCliError('PARAM_INVALID', 'Name cannot contain "@"', { value: options.name });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
167
176
|
const updates = {};
|
|
168
177
|
if (options.token !== undefined)
|
|
169
178
|
updates.token = options.token;
|
|
170
179
|
if (options.env !== undefined)
|
|
171
180
|
updates.env = options.env;
|
|
181
|
+
if (options.name !== undefined)
|
|
182
|
+
updates.name = options.name;
|
|
172
183
|
if (Object.keys(updates).length === 0) {
|
|
173
|
-
outputCliError('PARAM_MISSING', 'No update options provided. Use --token or --
|
|
184
|
+
outputCliError('PARAM_MISSING', 'No update options provided. Use --token, --env, or --name', {});
|
|
174
185
|
}
|
|
175
186
|
const updated = updateUser(user.id, updates);
|
|
176
187
|
outputJson({
|
package/dist/core/config.d.ts
CHANGED
package/dist/core/config.js
CHANGED
|
@@ -228,6 +228,19 @@ export function updateUser(id, updates) {
|
|
|
228
228
|
const user = config.users.find(u => u.id === id);
|
|
229
229
|
if (!user)
|
|
230
230
|
return null;
|
|
231
|
+
if (updates.name !== undefined) {
|
|
232
|
+
const newId = getUserId(updates.name, user.tenant);
|
|
233
|
+
const existing = config.users.find(u => u.id === newId);
|
|
234
|
+
if (existing) {
|
|
235
|
+
outputCliError('USER_ALREADY_EXISTS', `User "${newId}" already exists`, { id: newId });
|
|
236
|
+
}
|
|
237
|
+
const oldId = user.id;
|
|
238
|
+
user.name = updates.name;
|
|
239
|
+
user.id = newId;
|
|
240
|
+
if (config.currentUser === oldId) {
|
|
241
|
+
config.currentUser = newId;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
231
244
|
if (updates.token !== undefined) {
|
|
232
245
|
user.token = updates.token;
|
|
233
246
|
}
|
package/dist/core/error.d.ts
CHANGED
|
@@ -37,6 +37,11 @@ export declare const CLI_ERROR_CODES: {
|
|
|
37
37
|
readonly reason: "userDisabled";
|
|
38
38
|
readonly exitCode: 3;
|
|
39
39
|
};
|
|
40
|
+
readonly USER_ALREADY_EXISTS: {
|
|
41
|
+
readonly code: 20003;
|
|
42
|
+
readonly reason: "userAlreadyExists";
|
|
43
|
+
readonly exitCode: 2;
|
|
44
|
+
};
|
|
40
45
|
readonly TENANT_NOT_FOUND: {
|
|
41
46
|
readonly code: 30001;
|
|
42
47
|
readonly reason: "tenantNotFound";
|
|
@@ -94,6 +99,10 @@ export declare function getErrorMeta(key: CliErrorKey): {
|
|
|
94
99
|
readonly code: 20002;
|
|
95
100
|
readonly reason: "userDisabled";
|
|
96
101
|
readonly exitCode: 3;
|
|
102
|
+
} | {
|
|
103
|
+
readonly code: 20003;
|
|
104
|
+
readonly reason: "userAlreadyExists";
|
|
105
|
+
readonly exitCode: 2;
|
|
97
106
|
} | {
|
|
98
107
|
readonly code: 30001;
|
|
99
108
|
readonly reason: "tenantNotFound";
|
package/dist/core/error.js
CHANGED
|
@@ -18,6 +18,7 @@ export const CLI_ERROR_CODES = {
|
|
|
18
18
|
PARAM_INVALID: { code: 10002, reason: 'paramInvalid', exitCode: CLI_EXIT_CODES.PARAM },
|
|
19
19
|
USER_NOT_FOUND: { code: 20001, reason: 'userNotFound', exitCode: CLI_EXIT_CODES.NOT_FOUND },
|
|
20
20
|
USER_DISABLED: { code: 20002, reason: 'userDisabled', exitCode: CLI_EXIT_CODES.AUTH },
|
|
21
|
+
USER_ALREADY_EXISTS: { code: 20003, reason: 'userAlreadyExists', exitCode: CLI_EXIT_CODES.PARAM },
|
|
21
22
|
TENANT_NOT_FOUND: { code: 30001, reason: 'tenantNotFound', exitCode: CLI_EXIT_CODES.NOT_FOUND },
|
|
22
23
|
SERVICE_NOT_FOUND: { code: 30002, reason: 'serviceNotFound', exitCode: CLI_EXIT_CODES.NOT_FOUND },
|
|
23
24
|
CONFIG_READ_ERROR: { code: 40001, reason: 'configReadError', exitCode: CLI_EXIT_CODES.INTERNAL },
|