@meet-im/lxcli 0.1.2 → 0.1.4
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.
|
@@ -149,6 +149,28 @@ function renderParamsTable(params) {
|
|
|
149
149
|
lines.push('');
|
|
150
150
|
return lines.join('\n');
|
|
151
151
|
}
|
|
152
|
+
function renderExtraSections(metadata) {
|
|
153
|
+
const sections = metadata?.sections || [];
|
|
154
|
+
if (sections.length === 0)
|
|
155
|
+
return '';
|
|
156
|
+
const lines = [];
|
|
157
|
+
for (const section of sections) {
|
|
158
|
+
lines.push(`## ${section.title}`, '');
|
|
159
|
+
if (section.kind === 'bullets') {
|
|
160
|
+
for (const item of section.items) {
|
|
161
|
+
lines.push(`- ${item}`);
|
|
162
|
+
}
|
|
163
|
+
lines.push('');
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
lines.push(`| ${section.headers.join(' | ')} |`, `| ${section.headers.map(() => '---').join(' | ')} |`);
|
|
167
|
+
for (const row of section.rows) {
|
|
168
|
+
lines.push(`| ${row.join(' | ')} |`);
|
|
169
|
+
}
|
|
170
|
+
lines.push('');
|
|
171
|
+
}
|
|
172
|
+
return lines.join('\n');
|
|
173
|
+
}
|
|
152
174
|
async function readPackageVersion() {
|
|
153
175
|
const packageJson = JSON.parse(await fs.readFile(PACKAGE_JSON_PATH, 'utf-8'));
|
|
154
176
|
return packageJson.version || '1.0.0';
|
|
@@ -192,7 +214,7 @@ function renderSkillMd(method, version) {
|
|
|
192
214
|
}
|
|
193
215
|
return `--${param.name} <${param.type === 'integer' ? 'ID' : 'VALUE'}>`;
|
|
194
216
|
});
|
|
195
|
-
const shortcutUsage = shortcuts.length > 0 ? `lxcli kb ${method} ${shortcuts.join(' ')}` : '';
|
|
217
|
+
const shortcutUsage = metadata?.shortcutUsageExample || (shortcuts.length > 0 ? `lxcli kb ${method} ${shortcuts.join(' ')}` : '');
|
|
196
218
|
const paramsUsage = hasParams ? `lxcli kb ${method} --params '${JSON.stringify(metadata?.paramsExample || buildParamsExample(params))}'` : '';
|
|
197
219
|
// Usage 部分
|
|
198
220
|
const usageLines = ['## Usage', '', '```bash'];
|
|
@@ -240,6 +262,10 @@ metadata:
|
|
|
240
262
|
lines.push(renderParamsTable(params));
|
|
241
263
|
}
|
|
242
264
|
lines.push('## Examples', '', '```bash', shortcutUsage || paramsUsage || `lxcli kb ${method}`, '```', '');
|
|
265
|
+
const extraSections = renderExtraSections(metadata);
|
|
266
|
+
if (extraSections) {
|
|
267
|
+
lines.push(extraSections);
|
|
268
|
+
}
|
|
243
269
|
if (metadata?.notes?.length) {
|
|
244
270
|
lines.push('## Notes', '', ...metadata.notes.map((note) => `- ${note}`), '');
|
|
245
271
|
}
|
|
@@ -4,6 +4,7 @@ import { kbConfig } from './config.js';
|
|
|
4
4
|
import { METHODS, METHOD_DESCRIPTIONS } from './descriptions.js';
|
|
5
5
|
import { createKbAction } from './handler.js';
|
|
6
6
|
import { PARAM_DEFS } from './params.js';
|
|
7
|
+
import { METHOD_SKILL_METADATA } from './skill-metadata.js';
|
|
7
8
|
function getShortcutParamDescription(method, paramName) {
|
|
8
9
|
const param = PARAM_DEFS[method]?.find((item) => item.name === paramName);
|
|
9
10
|
if (!param) {
|
|
@@ -25,10 +26,32 @@ function renderParamsHelp(method) {
|
|
|
25
26
|
}
|
|
26
27
|
return lines.join('\n');
|
|
27
28
|
}
|
|
29
|
+
function renderMethodExtraHelp(method) {
|
|
30
|
+
const sections = METHOD_SKILL_METADATA[method]?.sections || [];
|
|
31
|
+
if (sections.length === 0) {
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
const lines = [];
|
|
35
|
+
for (const section of sections) {
|
|
36
|
+
lines.push(`${section.title}:`);
|
|
37
|
+
if (section.kind === 'bullets') {
|
|
38
|
+
for (const item of section.items) {
|
|
39
|
+
lines.push(` - ${item.replace(/`/g, '')}`);
|
|
40
|
+
}
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
for (const row of section.rows) {
|
|
44
|
+
const [label, description] = row;
|
|
45
|
+
lines.push(` - ${label.replace(/`/g, '')}: ${description}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return lines.join('\n');
|
|
49
|
+
}
|
|
28
50
|
function addParamsOption(command, method) {
|
|
29
51
|
const paramsHelp = renderParamsHelp(method);
|
|
52
|
+
const extraHelp = renderMethodExtraHelp(method);
|
|
30
53
|
const description = paramsHelp
|
|
31
|
-
? `JSON/JSON5 params; CLI fills jsonrpc/method/id\n${paramsHelp}`
|
|
54
|
+
? `JSON/JSON5 params; CLI fills jsonrpc/method/id\n${paramsHelp}${extraHelp ? `\n${extraHelp}` : ''}`
|
|
32
55
|
: 'JSON/JSON5 params; CLI fills jsonrpc/method/id';
|
|
33
56
|
return command.option('--params <json>', description);
|
|
34
57
|
}
|
|
@@ -21,7 +21,7 @@ export const PARAM_DEFS = {
|
|
|
21
21
|
],
|
|
22
22
|
searchTasks: [
|
|
23
23
|
{ name: 'project_id', type: 'integer', required: true, description: '项目 ID。接口按项目检查查看权限。' },
|
|
24
|
-
{ name: 'query', type: 'string', required: true, description: 'Kanboard
|
|
24
|
+
{ name: 'query', type: 'string', required: true, description: 'Kanboard 搜索表达式;多个条件以空格分隔,不同字段为 AND,同一字段重复为 OR。' },
|
|
25
25
|
],
|
|
26
26
|
searchSubtasks: [
|
|
27
27
|
{ name: 'project_id', type: 'integer', required: false, description: '项目 ID。传入后仅返回该项目下的子任务,并按项目检查查看权限;不传时仅在当前用户有权限查看的启用项目中查找。' },
|
|
@@ -49,7 +49,7 @@ export const PARAM_DEFS = {
|
|
|
49
49
|
{ name: 'owner_id', type: 'integer', required: false, description: '处理人 Kanboard 用户 ID。处理人必须可分配到该项目。' },
|
|
50
50
|
{ name: 'creator_id', type: 'integer', required: false, description: '创建人 Kanboard 用户 ID。登录态存在时创建人会使用当前用户。' },
|
|
51
51
|
{ name: 'category_id', type: 'integer', required: false, description: '分类 ID。服务端会根据分类和 bug 类型选择泳道。' },
|
|
52
|
-
{ name: 'iteration_id', type: 'integer', required: false, description: '迭代 ID;未传或为 0
|
|
52
|
+
{ name: 'iteration_id', type: 'integer', required: false, description: '迭代 ID;未传或为 0 时由服务端选择需求池或首个迭代。可用 getAllActiveIterations 查询启用迭代列表,根据 date_start/date_end(Unix 时间戳)确定目标迭代。' },
|
|
53
53
|
{ name: 'date_due', type: 'string', required: false, description: '截止日期,建议使用 YYYY-MM-DD' },
|
|
54
54
|
{ name: 'date_started', type: 'string', required: false, description: '开始日期,建议使用 YYYY-MM-DD' },
|
|
55
55
|
{ name: 'priority', type: 'integer', required: false, description: '优先级:0 高、1 中、2 低,其他值为无关紧要' },
|
|
@@ -74,7 +74,7 @@ export const PARAM_DEFS = {
|
|
|
74
74
|
{ name: 'description', type: 'string', required: false, description: '描述内容(Markdown)' },
|
|
75
75
|
{ name: 'owner_id', type: 'integer', required: false, description: '处理人用户 ID。目标用户必须可分配到该项目。' },
|
|
76
76
|
{ name: 'category_id', type: 'integer', required: false, description: '分类 ID' },
|
|
77
|
-
{ name: 'iteration_id', type: 'integer', required: false, description: '迭代 ID。传入后修改需求/bug
|
|
77
|
+
{ name: 'iteration_id', type: 'integer', required: false, description: '迭代 ID。传入后修改需求/bug 所属迭代;未传时保持原迭代不变。可用 getAllActiveIterations 查询启用迭代列表,根据 date_start/date_end(Unix 时间戳)确定目标迭代。' },
|
|
78
78
|
{ name: 'date_due', type: 'string', required: false, description: '截止日期,建议使用 YYYY-MM-DD' },
|
|
79
79
|
{ name: 'date_started', type: 'string', required: false, description: '开始日期,建议使用 YYYY-MM-DD' },
|
|
80
80
|
{ name: 'priority', type: 'integer', required: false, description: '优先级:0 高、1 中、2 低,其他值为无关紧要' },
|
|
@@ -4,6 +4,18 @@ export interface MethodSkillMetadata {
|
|
|
4
4
|
notes?: string[];
|
|
5
5
|
skillParams?: ParamDef[];
|
|
6
6
|
paramsExample?: Record<string, unknown>;
|
|
7
|
+
shortcutUsageExample?: string;
|
|
8
|
+
sections?: MethodSkillSection[];
|
|
7
9
|
}
|
|
10
|
+
export type MethodSkillSection = {
|
|
11
|
+
title: string;
|
|
12
|
+
kind: 'bullets';
|
|
13
|
+
items: string[];
|
|
14
|
+
} | {
|
|
15
|
+
title: string;
|
|
16
|
+
kind: 'table';
|
|
17
|
+
headers: string[];
|
|
18
|
+
rows: string[][];
|
|
19
|
+
};
|
|
8
20
|
export declare const METHOD_SHORTCUT_PARAMS: Partial<Record<Method, string[]>>;
|
|
9
21
|
export declare const METHOD_SKILL_METADATA: Partial<Record<Method, MethodSkillMetadata>>;
|
|
@@ -26,6 +26,78 @@ export const METHOD_SKILL_METADATA = {
|
|
|
26
26
|
'仅在确实需要时才传 `with_comments`、`with_files`、`with_links`、`with_subtasks`,避免把额外第三方内容带入代理上下文。',
|
|
27
27
|
],
|
|
28
28
|
},
|
|
29
|
+
getAllActiveIterations: {
|
|
30
|
+
paramsExample: {
|
|
31
|
+
project_id: 4,
|
|
32
|
+
},
|
|
33
|
+
sections: [
|
|
34
|
+
{
|
|
35
|
+
title: '返回值说明',
|
|
36
|
+
kind: 'bullets',
|
|
37
|
+
items: [
|
|
38
|
+
'返回数组中每个对象包含 `id`、`name`、`date_start`、`date_end`、`position`、`nb_open_tasks`、`nb_closed_tasks` 等字段。',
|
|
39
|
+
'`date_start` 和 `date_end` 是 **Unix 时间戳**(秒级整数),`0` 表示未设置。显示或比较前需转换为可读日期。',
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
title: '确定下个迭代',
|
|
44
|
+
kind: 'bullets',
|
|
45
|
+
items: [
|
|
46
|
+
'将当前时间转为 Unix 时间戳(秒),筛选 `date_start > 当前时间戳` 的迭代。',
|
|
47
|
+
'在筛选结果中取 `date_start` 最小的那个,即为"下个迭代"。',
|
|
48
|
+
'若所有迭代的 `date_start` 都 ≤ 当前时间,说明没有未来的迭代;可取 `date_end` 最大且仍 ≥ 当前时间的迭代作为"当前迭代"。',
|
|
49
|
+
'获得迭代后,将其 `id` 传入 `createTask --iteration_id` 或 `updateTask --iteration_id`。',
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
createTask: {
|
|
55
|
+
notes: [
|
|
56
|
+
'如需指定迭代,先调用 `getAllActiveIterations` 查询项目的启用迭代列表,根据 `date_start`/`date_end`(Unix 时间戳)确定目标迭代 ID,再传入 `iteration_id`。',
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
searchTasks: {
|
|
60
|
+
paramsExample: {
|
|
61
|
+
project_id: 4,
|
|
62
|
+
query: 'iteration:3 status:0 completedRange:"2026-07-01 00:00:00..2026-07-07 23:59:59"',
|
|
63
|
+
},
|
|
64
|
+
shortcutUsageExample: "lxcli kb searchTasks --project_id 4 --query 'iteration:3 status:0'",
|
|
65
|
+
sections: [
|
|
66
|
+
{
|
|
67
|
+
title: 'Query Syntax',
|
|
68
|
+
kind: 'bullets',
|
|
69
|
+
items: [
|
|
70
|
+
'`字段:值` 是基础条件,多个条件用空格分隔。',
|
|
71
|
+
'不同字段之间是 AND。',
|
|
72
|
+
'同一字段传多个值时为 OR,例如 `assignee:alice assignee:bob`。',
|
|
73
|
+
'值中包含空格、冒号或时间范围时,用双引号包裹。',
|
|
74
|
+
'日期字段支持比较符,例如 `completed:>=2026-07-01`。',
|
|
75
|
+
'范围字段支持 `start..end`,可省略一端。',
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
title: 'Common Query Conditions',
|
|
80
|
+
kind: 'table',
|
|
81
|
+
headers: ['表达式', '说明'],
|
|
82
|
+
rows: [
|
|
83
|
+
['`iteration:456` / `iteration:V1.0.0`', '按迭代 ID 或名称查询'],
|
|
84
|
+
['`status:1` / `status:0`', '按打开 / 关闭状态查询'],
|
|
85
|
+
['`completedRange:"2026-07-01 00:00:00..2026-07-07 23:59:59"`', '按完成时间范围查询'],
|
|
86
|
+
['`completed:>=2026-07-01`', '按完成时间做比较查询'],
|
|
87
|
+
['`assignee:alice` / `assignee:me`', '按处理人查询'],
|
|
88
|
+
['`category:Feature` / `column:Ready`', '按分类或状态列查询'],
|
|
89
|
+
['`title:"登录异常"` / `description:"回调失败"`', '按标题或描述查询'],
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
title: 'Warnings',
|
|
94
|
+
kind: 'bullets',
|
|
95
|
+
items: [
|
|
96
|
+
'`completedRange` 结束值只写日期时按当天 `00:00:00` 解析;需要覆盖整天时请写到 `23:59:59`。',
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
29
101
|
createProjectFile: {
|
|
30
102
|
skillParams: [
|
|
31
103
|
{ name: 'project_id', type: 'integer', required: true, description: '项目 ID' },
|