@zzp123/mcp-zentao 1.10.0 → 1.11.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/CHANGELOG.md +35 -0
- package/dist/api/zentaoApi.d.ts +24 -2
- package/dist/api/zentaoApi.js +37 -18
- package/dist/index.js +58 -15
- package/dist/types/zentao.d.ts +28 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.11.0] - 2025-11-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **完整的 Bug 状态筛选支持** ✨
|
|
12
|
+
- 扩展 `BugStatus` 类型,新增 16 种状态筛选类型
|
|
13
|
+
- 支持所有禅道官方 API 的状态筛选:assigntome、openedbyme、resolvedbyme、assignedbyme、assigntonull、unconfirmed、unclosed、unresolved、toclosed、postponedbugs、longlifebugs、overduebugs、review、feedback、needconfirm、bysearch
|
|
14
|
+
- MCP 工具现在提供完整的 20 种状态选项供选择
|
|
15
|
+
|
|
16
|
+
- **分支筛选功能** 🌿
|
|
17
|
+
- 为 `getMyBugs` 和 `getProductBugs` 添加 `branch` 参数
|
|
18
|
+
- 支持 'all'(所有分支)、'0'(主干分支)、分支ID
|
|
19
|
+
- 默认值为 'all',符合禅道官方 API 规范
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- **重构 Bug 列表 API 参数** 🔄
|
|
23
|
+
- 移除 `onlyAssignedToMe` 参数,改用更灵活的 `status='assigntome'`
|
|
24
|
+
- 调整参数顺序:`status, productId, page, limit, branch, order`
|
|
25
|
+
- 优化参数构建逻辑,确保与禅道官方 API 完全一致
|
|
26
|
+
|
|
27
|
+
### Improved
|
|
28
|
+
- **API 文档完善**
|
|
29
|
+
- 为 `getMyBugs` 和 `getProductBugs` 添加详细的 JSDoc 注释
|
|
30
|
+
- 更新工具描述,明确说明支持的状态筛选类型
|
|
31
|
+
- 参数说明更加清晰,包含默认值和示例
|
|
32
|
+
|
|
33
|
+
- **更好的用户体验**
|
|
34
|
+
- MCP 工具提供完整的状态枚举,IDE 可以自动补全
|
|
35
|
+
- 所有状态选项都有中文注释说明
|
|
36
|
+
- 更符合禅道用户的使用习惯
|
|
37
|
+
|
|
38
|
+
### Technical
|
|
39
|
+
- 完全符合禅道官方 Bug 列表 API 文档规范
|
|
40
|
+
- 支持所有官方 API 参数:branch、status、order、limit、page
|
|
41
|
+
- 默认值与官方 API 保持一致
|
|
42
|
+
|
|
8
43
|
## [1.10.0] - 2025-11-07
|
|
9
44
|
|
|
10
45
|
### Fixed
|
package/dist/api/zentaoApi.d.ts
CHANGED
|
@@ -9,13 +9,35 @@ export declare class ZentaoAPI {
|
|
|
9
9
|
getMyTasks(status?: TaskStatus): Promise<Task[]>;
|
|
10
10
|
getTaskDetail(taskId: number): Promise<Task>;
|
|
11
11
|
getProducts(): Promise<Product[]>;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* 获取 Bug 列表
|
|
14
|
+
*
|
|
15
|
+
* @param status Bug状态筛选(支持多种状态,详见BugStatus类型)
|
|
16
|
+
* @param productId 产品ID(可选,默认使用第二个产品)
|
|
17
|
+
* @param page 页码(从1开始,默认1)
|
|
18
|
+
* @param limit 每页数量(默认20,最大100)
|
|
19
|
+
* @param branch 分支筛选('all'所有分支/'0'主干/分支ID,默认'all')
|
|
20
|
+
* @param order 排序字段(如:'id_desc'、'pri_desc'等,默认'id_desc')
|
|
21
|
+
* @returns Promise<Bug列表及分页信息>
|
|
22
|
+
*/
|
|
23
|
+
getMyBugs(status?: BugStatus, productId?: number, page?: number, limit?: number, branch?: string, order?: string): Promise<{
|
|
13
24
|
page: number;
|
|
14
25
|
total: number;
|
|
15
26
|
limit: number;
|
|
16
27
|
bugs: Bug[];
|
|
17
28
|
}>;
|
|
18
|
-
|
|
29
|
+
/**
|
|
30
|
+
* 获取产品 Bug 列表
|
|
31
|
+
*
|
|
32
|
+
* @param productId 产品ID(必填)
|
|
33
|
+
* @param page 页码(从1开始,默认1)
|
|
34
|
+
* @param limit 每页数量(默认20,最大100)
|
|
35
|
+
* @param status Bug状态筛选(支持多种状态,详见BugStatus类型)
|
|
36
|
+
* @param branch 分支筛选('all'所有分支/'0'主干/分支ID,默认'all')
|
|
37
|
+
* @param order 排序字段(如:'id_desc'、'pri_desc'等,默认'id_desc')
|
|
38
|
+
* @returns Promise<Bug列表及分页信息>
|
|
39
|
+
*/
|
|
40
|
+
getProductBugs(productId: number, page?: number, limit?: number, status?: BugStatus, branch?: string, order?: string): Promise<{
|
|
19
41
|
page: number;
|
|
20
42
|
total: number;
|
|
21
43
|
limit: number;
|
package/dist/api/zentaoApi.js
CHANGED
|
@@ -111,7 +111,18 @@ export class ZentaoAPI {
|
|
|
111
111
|
throw error;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
/**
|
|
115
|
+
* 获取 Bug 列表
|
|
116
|
+
*
|
|
117
|
+
* @param status Bug状态筛选(支持多种状态,详见BugStatus类型)
|
|
118
|
+
* @param productId 产品ID(可选,默认使用第二个产品)
|
|
119
|
+
* @param page 页码(从1开始,默认1)
|
|
120
|
+
* @param limit 每页数量(默认20,最大100)
|
|
121
|
+
* @param branch 分支筛选('all'所有分支/'0'主干/分支ID,默认'all')
|
|
122
|
+
* @param order 排序字段(如:'id_desc'、'pri_desc'等,默认'id_desc')
|
|
123
|
+
* @returns Promise<Bug列表及分页信息>
|
|
124
|
+
*/
|
|
125
|
+
async getMyBugs(status, productId, page, limit, branch, order) {
|
|
115
126
|
if (!productId) {
|
|
116
127
|
// 如果没有提供产品ID,获取第二个可用的产品(索引为1)
|
|
117
128
|
const products = await this.getProducts();
|
|
@@ -125,22 +136,20 @@ export class ZentaoAPI {
|
|
|
125
136
|
// 默认每页20条,最多100条
|
|
126
137
|
const finalLimit = limit ? Math.min(limit, 100) : 20;
|
|
127
138
|
const finalPage = page || 1;
|
|
139
|
+
const finalBranch = branch || 'all';
|
|
140
|
+
const finalOrder = order || 'id_desc';
|
|
128
141
|
// 构建查询参数
|
|
129
142
|
const queryParams = new URLSearchParams();
|
|
130
|
-
|
|
131
|
-
if (onlyAssignedToMe) {
|
|
132
|
-
queryParams.append('status', 'assigntome');
|
|
133
|
-
}
|
|
134
|
-
else if (status && status !== 'all') {
|
|
135
|
-
queryParams.append('status', status);
|
|
136
|
-
}
|
|
143
|
+
queryParams.append('branch', finalBranch);
|
|
137
144
|
queryParams.append('page', finalPage.toString());
|
|
138
145
|
queryParams.append('limit', finalLimit.toString());
|
|
139
|
-
// 添加排序参数,默认按ID降序
|
|
140
|
-
const finalOrder = order || 'id_desc';
|
|
141
146
|
queryParams.append('order', finalOrder);
|
|
147
|
+
// 添加状态筛选
|
|
148
|
+
if (status && status !== 'all') {
|
|
149
|
+
queryParams.append('status', status);
|
|
150
|
+
}
|
|
142
151
|
try {
|
|
143
|
-
console.log(`正在获取产品 ${productId} 的Bug列表,参数: status=${
|
|
152
|
+
console.log(`正在获取产品 ${productId} 的Bug列表,参数: status=${status || 'all'}, branch=${finalBranch}, page=${finalPage}, limit=${finalLimit}, order=${finalOrder}`);
|
|
144
153
|
const response = await this.request('GET', `/products/${productId}/bugs?${queryParams.toString()}`);
|
|
145
154
|
console.log(`Bug列表响应: 获取到 ${response.bugs?.length || 0} 条数据`);
|
|
146
155
|
if (Array.isArray(response)) {
|
|
@@ -169,23 +178,33 @@ export class ZentaoAPI {
|
|
|
169
178
|
throw error;
|
|
170
179
|
}
|
|
171
180
|
}
|
|
172
|
-
|
|
181
|
+
/**
|
|
182
|
+
* 获取产品 Bug 列表
|
|
183
|
+
*
|
|
184
|
+
* @param productId 产品ID(必填)
|
|
185
|
+
* @param page 页码(从1开始,默认1)
|
|
186
|
+
* @param limit 每页数量(默认20,最大100)
|
|
187
|
+
* @param status Bug状态筛选(支持多种状态,详见BugStatus类型)
|
|
188
|
+
* @param branch 分支筛选('all'所有分支/'0'主干/分支ID,默认'all')
|
|
189
|
+
* @param order 排序字段(如:'id_desc'、'pri_desc'等,默认'id_desc')
|
|
190
|
+
* @returns Promise<Bug列表及分页信息>
|
|
191
|
+
*/
|
|
192
|
+
async getProductBugs(productId, page, limit, status, branch, order) {
|
|
173
193
|
try {
|
|
174
194
|
// 默认每页20条,最多100条
|
|
175
195
|
const finalLimit = limit ? Math.min(limit, 100) : 20;
|
|
176
196
|
const finalPage = page || 1;
|
|
197
|
+
const finalBranch = branch || 'all';
|
|
177
198
|
const finalOrder = order || 'id_desc';
|
|
178
|
-
console.log(`正在获取产品 ${productId} 的Bug列表 (page=${finalPage}, limit=${finalLimit}, order=${finalOrder})...`);
|
|
199
|
+
console.log(`正在获取产品 ${productId} 的Bug列表 (status=${status || 'all'}, branch=${finalBranch}, page=${finalPage}, limit=${finalLimit}, order=${finalOrder})...`);
|
|
179
200
|
// 构建查询参数
|
|
180
201
|
const queryParams = new URLSearchParams();
|
|
202
|
+
queryParams.append('branch', finalBranch);
|
|
181
203
|
queryParams.append('page', finalPage.toString());
|
|
182
204
|
queryParams.append('limit', finalLimit.toString());
|
|
183
205
|
queryParams.append('order', finalOrder);
|
|
184
|
-
//
|
|
185
|
-
if (status
|
|
186
|
-
queryParams.append('status', 'assigntome');
|
|
187
|
-
}
|
|
188
|
-
else if (status && status !== 'all') {
|
|
206
|
+
// 添加状态筛选
|
|
207
|
+
if (status && status !== 'all') {
|
|
189
208
|
queryParams.append('status', status);
|
|
190
209
|
}
|
|
191
210
|
const response = await this.request('GET', `/products/${productId}/bugs?${queryParams.toString()}`);
|
package/dist/index.js
CHANGED
|
@@ -87,17 +87,38 @@ server.tool("getProducts", {}, async () => {
|
|
|
87
87
|
};
|
|
88
88
|
});
|
|
89
89
|
// Add getMyBugs tool
|
|
90
|
-
server.tool("getMyBugs", "获取Bug列表 -
|
|
91
|
-
status: z.enum([
|
|
92
|
-
|
|
90
|
+
server.tool("getMyBugs", "获取Bug列表 - 支持多种状态筛选(指派给我、由我创建、未关闭等)和分支筛选", {
|
|
91
|
+
status: z.enum([
|
|
92
|
+
'active', // 激活状态
|
|
93
|
+
'resolved', // 已解决
|
|
94
|
+
'closed', // 已关闭
|
|
95
|
+
'all', // 所有状态
|
|
96
|
+
'assigntome', // 指派给我的
|
|
97
|
+
'openedbyme', // 由我创建
|
|
98
|
+
'resolvedbyme', // 由我解决
|
|
99
|
+
'assignedbyme', // 由我指派
|
|
100
|
+
'assigntonull', // 未指派
|
|
101
|
+
'unconfirmed', // 未确认
|
|
102
|
+
'unclosed', // 未关闭
|
|
103
|
+
'unresolved', // 未解决(激活状态)
|
|
104
|
+
'toclosed', // 待关闭(已解决)
|
|
105
|
+
'postponedbugs', // 延期的Bug
|
|
106
|
+
'longlifebugs', // 长期未处理的Bug
|
|
107
|
+
'overduebugs', // 已过期的Bug
|
|
108
|
+
'review', // 待我审核
|
|
109
|
+
'feedback', // 用户反馈
|
|
110
|
+
'needconfirm', // 需求变更需确认
|
|
111
|
+
'bysearch' // 自定义搜索
|
|
112
|
+
]).optional().describe("Bug状态筛选,默认返回所有状态"),
|
|
113
|
+
productId: z.number().optional().describe("产品ID,默认使用第二个产品"),
|
|
93
114
|
page: z.number().optional().describe("页码,从1开始,默认为1"),
|
|
94
115
|
limit: z.number().optional().describe("每页数量,默认20,最大100"),
|
|
95
|
-
|
|
96
|
-
order: z.string().optional().describe("排序方式,如 id_desc(ID降序),
|
|
97
|
-
}, async ({ status, productId, page, limit,
|
|
116
|
+
branch: z.string().optional().describe("分支筛选:'all'(所有分支,默认)、'0'(主干分支)、分支ID"),
|
|
117
|
+
order: z.string().optional().describe("排序方式,如 id_desc(ID降序), pri_desc(优先级降序), openedDate_desc(创建时间降序)等,默认id_desc")
|
|
118
|
+
}, async ({ status, productId, page, limit, branch, order }) => {
|
|
98
119
|
if (!zentaoApi)
|
|
99
120
|
throw new Error("Please initialize Zentao API first");
|
|
100
|
-
const result = await zentaoApi.getMyBugs(status, productId, page, limit,
|
|
121
|
+
const result = await zentaoApi.getMyBugs(status, productId, page, limit, branch, order);
|
|
101
122
|
// 返回分页信息和数据
|
|
102
123
|
const summary = {
|
|
103
124
|
summary: `当前第 ${result.page} 页,共 ${result.total} 个Bug,本页显示 ${result.bugs.length} 个`,
|
|
@@ -114,16 +135,38 @@ server.tool("getMyBugs", "获取Bug列表 - 默认获取所有Bug,可选择只
|
|
|
114
135
|
};
|
|
115
136
|
});
|
|
116
137
|
// Add getProductBugs tool
|
|
117
|
-
server.tool("getProductBugs", {
|
|
118
|
-
productId: z.number(),
|
|
138
|
+
server.tool("getProductBugs", "获取指定产品的Bug列表 - 支持多种状态筛选和分支筛选", {
|
|
139
|
+
productId: z.number().describe("产品ID(必填)"),
|
|
119
140
|
page: z.number().optional().describe("页码,从1开始,默认为1"),
|
|
120
141
|
limit: z.number().optional().describe("每页数量,默认20,最大100"),
|
|
121
|
-
status: z.enum([
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
142
|
+
status: z.enum([
|
|
143
|
+
'active', // 激活状态
|
|
144
|
+
'resolved', // 已解决
|
|
145
|
+
'closed', // 已关闭
|
|
146
|
+
'all', // 所有状态
|
|
147
|
+
'assigntome', // 指派给我的
|
|
148
|
+
'openedbyme', // 由我创建
|
|
149
|
+
'resolvedbyme', // 由我解决
|
|
150
|
+
'assignedbyme', // 由我指派
|
|
151
|
+
'assigntonull', // 未指派
|
|
152
|
+
'unconfirmed', // 未确认
|
|
153
|
+
'unclosed', // 未关闭
|
|
154
|
+
'unresolved', // 未解决(激活状态)
|
|
155
|
+
'toclosed', // 待关闭(已解决)
|
|
156
|
+
'postponedbugs', // 延期的Bug
|
|
157
|
+
'longlifebugs', // 长期未处理的Bug
|
|
158
|
+
'overduebugs', // 已过期的Bug
|
|
159
|
+
'review', // 待我审核
|
|
160
|
+
'feedback', // 用户反馈
|
|
161
|
+
'needconfirm', // 需求变更需确认
|
|
162
|
+
'bysearch' // 自定义搜索
|
|
163
|
+
]).optional().describe("Bug状态筛选,默认返回所有状态"),
|
|
164
|
+
branch: z.string().optional().describe("分支筛选:'all'(所有分支,默认)、'0'(主干分支)、分支ID"),
|
|
165
|
+
order: z.string().optional().describe("排序方式,如 id_desc(ID降序), pri_desc(优先级降序), openedDate_desc(创建时间降序)等,默认id_desc")
|
|
166
|
+
}, async ({ productId, page, limit, status, branch, order }) => {
|
|
167
|
+
if (!zentaoApi)
|
|
168
|
+
throw new Error("Please initialize Zentao API first");
|
|
169
|
+
const result = await zentaoApi.getProductBugs(productId, page, limit, status, branch, order);
|
|
127
170
|
// 返回分页信息和数据
|
|
128
171
|
const summary = {
|
|
129
172
|
summary: `当前第 ${result.page} 页,共 ${result.total} 个Bug,本页显示 ${result.bugs.length} 个`,
|
package/dist/types/zentao.d.ts
CHANGED
|
@@ -56,7 +56,34 @@ export interface TaskUpdate {
|
|
|
56
56
|
comment?: string;
|
|
57
57
|
}
|
|
58
58
|
export type TaskStatus = 'wait' | 'doing' | 'done' | 'all';
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Bug 状态筛选类型
|
|
61
|
+
*
|
|
62
|
+
* 基础状态:
|
|
63
|
+
* - active: 激活状态
|
|
64
|
+
* - resolved: 已解决
|
|
65
|
+
* - closed: 已关闭
|
|
66
|
+
* - all: 所有状态
|
|
67
|
+
*
|
|
68
|
+
* 筛选条件:
|
|
69
|
+
* - assigntome: 指派给我的
|
|
70
|
+
* - openedbyme: 由我创建
|
|
71
|
+
* - resolvedbyme: 由我解决
|
|
72
|
+
* - assignedbyme: 由我指派
|
|
73
|
+
* - assigntonull: 未指派
|
|
74
|
+
* - unconfirmed: 未确认
|
|
75
|
+
* - unclosed: 未关闭
|
|
76
|
+
* - unresolved: 未解决(激活状态)
|
|
77
|
+
* - toclosed: 待关闭(已解决)
|
|
78
|
+
* - postponedbugs: 延期的Bug
|
|
79
|
+
* - longlifebugs: 长期未处理的Bug
|
|
80
|
+
* - overduebugs: 已过期的Bug
|
|
81
|
+
* - review: 待我审核
|
|
82
|
+
* - feedback: 用户反馈
|
|
83
|
+
* - needconfirm: 需求变更需确认
|
|
84
|
+
* - bysearch: 自定义搜索(需配合queryID使用)
|
|
85
|
+
*/
|
|
86
|
+
export type BugStatus = 'active' | 'resolved' | 'closed' | 'all' | 'assigntome' | 'openedbyme' | 'resolvedbyme' | 'assignedbyme' | 'assigntonull' | 'unconfirmed' | 'unclosed' | 'unresolved' | 'toclosed' | 'postponedbugs' | 'longlifebugs' | 'overduebugs' | 'review' | 'feedback' | 'needconfirm' | 'bysearch';
|
|
60
87
|
export type ResolutionType = 'fixed' | 'bydesign' | 'duplicate' | 'external' | 'notrepro' | 'postponed' | 'willnotfix';
|
|
61
88
|
export interface ResolveBugRequest {
|
|
62
89
|
resolution: ResolutionType;
|