@zzp123/mcp-zentao 1.13.0 → 1.15.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 +57 -0
- package/dist/api/zentaoApi.d.ts +1 -0
- package/dist/api/zentaoApi.js +57 -0
- package/dist/index.js +216 -8
- package/dist/types/zentao.d.ts +12 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,63 @@ 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.15.0] - 2025-11-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **评论功能完整支持** 💬
|
|
12
|
+
- 新增 `addComment` 通用评论工具,支持9种对象类型
|
|
13
|
+
- 新增专用评论工具:
|
|
14
|
+
- `addStoryComment`: 为需求添加评论(自动识别story/requirement)
|
|
15
|
+
- `addTaskComment`: 为任务添加评论
|
|
16
|
+
- `addBugComment`: 为Bug添加评论
|
|
17
|
+
- 支持的对象类型:
|
|
18
|
+
- story(软件需求)
|
|
19
|
+
- requirement(用户需求)
|
|
20
|
+
- task(任务)
|
|
21
|
+
- bug(Bug)
|
|
22
|
+
- testcase(测试用例)
|
|
23
|
+
- testtask(测试单)
|
|
24
|
+
- todo(待办)
|
|
25
|
+
- doc(文档)
|
|
26
|
+
- doctemplate(文档模板)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **评论内容格式**
|
|
30
|
+
- 支持纯文本评论
|
|
31
|
+
- 支持HTML格式的富文本评论
|
|
32
|
+
- 自动处理评论提交的响应格式
|
|
33
|
+
|
|
34
|
+
### Technical
|
|
35
|
+
- 添加 `CommentObjectType` 类型定义
|
|
36
|
+
- 添加 `AddCommentRequest` 和 `CommentResponse` 接口
|
|
37
|
+
- 实现混合接口调用(使用HTML接口但保持REST API认证)
|
|
38
|
+
|
|
39
|
+
## [1.14.0] - 2025-11-07
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
- **完整的用户需求(Requirement)支持** 🎯
|
|
43
|
+
- 扩展 Story API,统一支持软件需求(story)和用户需求(requirement)
|
|
44
|
+
- 所有现有 story 工具现已支持两种需求类型,自动识别
|
|
45
|
+
- 新增4个专用的 requirement 工具:
|
|
46
|
+
- `createRequirement`: 创建用户需求
|
|
47
|
+
- `getRequirementDetail`: 获取用户需求详情
|
|
48
|
+
- `changeRequirement`: 修改用户需求
|
|
49
|
+
- `deleteRequirement`: 删除用户需求
|
|
50
|
+
- `createStory` 工具新增 `type` 参数,可选择创建 story 或 requirement
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
- **更新现有需求工具描述**
|
|
54
|
+
- `getStoryDetail`: 现支持 story 和 requirement 两种类型,自动识别
|
|
55
|
+
- `changeStory`: 现支持 story 和 requirement 两种类型,自动识别
|
|
56
|
+
- `deleteStory`: 现支持 story 和 requirement 两种类型,自动识别
|
|
57
|
+
- `getProductStories`: 返回的列表可能包含两种类型的需求
|
|
58
|
+
|
|
59
|
+
### Improved
|
|
60
|
+
- **更好的语义化**
|
|
61
|
+
- 专用的 requirement 工具提供更清晰的意图表达
|
|
62
|
+
- 统一接口底层实现,减少代码重复
|
|
63
|
+
- 符合禅道 API v2.0 的最新扩展
|
|
64
|
+
|
|
8
65
|
## [1.13.0] - 2025-11-07
|
|
9
66
|
|
|
10
67
|
### Added
|
package/dist/api/zentaoApi.d.ts
CHANGED
|
@@ -239,5 +239,6 @@ export declare class ZentaoAPI {
|
|
|
239
239
|
getModules(type: ModuleType, id: number, fields?: string): Promise<ModulesResponse>;
|
|
240
240
|
uploadFile(uploadRequest: UploadFileRequest): Promise<FileUploadResponse>;
|
|
241
241
|
downloadFile(fileId: number): Promise<Buffer>;
|
|
242
|
+
addComment(objectType: string, objectID: number, comment: string): Promise<any>;
|
|
242
243
|
getConfig(): ZentaoConfig;
|
|
243
244
|
}
|
package/dist/api/zentaoApi.js
CHANGED
|
@@ -1534,6 +1534,63 @@ export class ZentaoAPI {
|
|
|
1534
1534
|
throw error;
|
|
1535
1535
|
}
|
|
1536
1536
|
}
|
|
1537
|
+
// 评论模块 - 使用 HTML 接口
|
|
1538
|
+
async addComment(objectType, objectID, comment) {
|
|
1539
|
+
try {
|
|
1540
|
+
console.log(`正在为 ${objectType} ${objectID} 添加评论...`);
|
|
1541
|
+
const token = await this.getToken();
|
|
1542
|
+
const htmlUrl = `${this.config.url}/zentao/action-comment-${objectType}-${objectID}.html`;
|
|
1543
|
+
// 使用 form-urlencoded 格式发送数据
|
|
1544
|
+
const formData = new URLSearchParams();
|
|
1545
|
+
formData.append('actioncomment', comment);
|
|
1546
|
+
const response = await axios.post(htmlUrl, formData.toString(), {
|
|
1547
|
+
headers: {
|
|
1548
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
1549
|
+
'Token': token
|
|
1550
|
+
},
|
|
1551
|
+
timeout: 10000
|
|
1552
|
+
});
|
|
1553
|
+
console.log('添加评论响应:', response.data);
|
|
1554
|
+
// 返回统一格式
|
|
1555
|
+
if (response.data && typeof response.data === 'object') {
|
|
1556
|
+
// 如果是 JSON 响应(API 模式)
|
|
1557
|
+
if (response.data.status === 'success' || response.data.result === 'success') {
|
|
1558
|
+
return {
|
|
1559
|
+
status: 'success',
|
|
1560
|
+
actionID: response.data.data || response.data.actionID,
|
|
1561
|
+
message: '评论添加成功'
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
else if (response.data.result === 'fail' || response.data.status === 'fail') {
|
|
1565
|
+
throw new Error(response.data.message || '评论添加失败');
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
// 如果返回的是 HTML 或其他格式,认为成功
|
|
1569
|
+
return {
|
|
1570
|
+
status: 'success',
|
|
1571
|
+
message: '评论添加成功'
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
catch (error) {
|
|
1575
|
+
if (axios.isAxiosError(error)) {
|
|
1576
|
+
console.error('添加评论失败:', {
|
|
1577
|
+
status: error.response?.status,
|
|
1578
|
+
data: error.response?.data,
|
|
1579
|
+
message: error.message
|
|
1580
|
+
});
|
|
1581
|
+
// 尝试解析错误消息
|
|
1582
|
+
if (error.response?.data) {
|
|
1583
|
+
const errorData = error.response.data;
|
|
1584
|
+
if (typeof errorData === 'object' && errorData.message) {
|
|
1585
|
+
throw new Error(`添加评论失败: ${errorData.message}`);
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
throw new Error(`添加评论失败: ${error.message}`);
|
|
1589
|
+
}
|
|
1590
|
+
console.error('添加评论失败:', error);
|
|
1591
|
+
throw error;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1537
1594
|
// 获取配置信息(用于生成图片 URL)
|
|
1538
1595
|
getConfig() {
|
|
1539
1596
|
return this.config;
|
package/dist/index.js
CHANGED
|
@@ -335,10 +335,11 @@ server.tool("createTask", {
|
|
|
335
335
|
};
|
|
336
336
|
});
|
|
337
337
|
// Add createStory tool
|
|
338
|
-
server.tool("createStory", {
|
|
338
|
+
server.tool("createStory", "创建需求 - 支持创建软件需求(story)或用户需求(requirement)", {
|
|
339
339
|
title: z.string(),
|
|
340
340
|
product: z.number(),
|
|
341
341
|
pri: z.number(),
|
|
342
|
+
type: z.enum(['story', 'requirement']).optional().describe("需求类型:story=软件需求,requirement=用户需求,默认为story"),
|
|
342
343
|
category: z.string().optional(),
|
|
343
344
|
spec: z.string().optional(),
|
|
344
345
|
verify: z.string().optional(),
|
|
@@ -346,13 +347,14 @@ server.tool("createStory", {
|
|
|
346
347
|
sourceNote: z.string().optional(),
|
|
347
348
|
estimate: z.number().optional(),
|
|
348
349
|
keywords: z.string().optional()
|
|
349
|
-
}, async ({ title, product, pri, category, spec, verify, source, sourceNote, estimate, keywords }) => {
|
|
350
|
+
}, async ({ title, product, pri, type, category, spec, verify, source, sourceNote, estimate, keywords }) => {
|
|
350
351
|
if (!zentaoApi)
|
|
351
352
|
throw new Error("Please initialize Zentao API first");
|
|
352
353
|
const story = await zentaoApi.createStory({
|
|
353
354
|
title,
|
|
354
355
|
product,
|
|
355
356
|
pri,
|
|
357
|
+
type,
|
|
356
358
|
category,
|
|
357
359
|
spec,
|
|
358
360
|
verify,
|
|
@@ -465,8 +467,8 @@ server.tool("getProjectReleases", {
|
|
|
465
467
|
};
|
|
466
468
|
});
|
|
467
469
|
// Add getStoryDetail tool
|
|
468
|
-
server.tool("getStoryDetail", {
|
|
469
|
-
storyId: z.number(),
|
|
470
|
+
server.tool("getStoryDetail", "获取需求详情 - 支持软件需求(story)和用户需求(requirement),自动识别类型", {
|
|
471
|
+
storyId: z.number().describe("需求ID(可以是story或requirement类型)"),
|
|
470
472
|
fields: z.enum(['basic', 'detail', 'full']).optional().describe(`
|
|
471
473
|
字段级别:
|
|
472
474
|
- basic: 基本信息(id, title, status, stage, pri等核心字段)
|
|
@@ -585,8 +587,8 @@ server.tool("getProjects", {
|
|
|
585
587
|
};
|
|
586
588
|
});
|
|
587
589
|
// Add changeStory tool
|
|
588
|
-
server.tool("changeStory", "需求变更 -
|
|
589
|
-
storyId: z.number().describe("需求ID"),
|
|
590
|
+
server.tool("changeStory", "需求变更 - 支持软件需求(story)和用户需求(requirement),自动识别类型。支持对象或JSON字符串格式", {
|
|
591
|
+
storyId: z.number().describe("需求ID(可以是story或requirement类型)"),
|
|
590
592
|
update: z.union([
|
|
591
593
|
z.object({
|
|
592
594
|
// 基本信息
|
|
@@ -671,7 +673,7 @@ server.tool("deleteTask", {
|
|
|
671
673
|
};
|
|
672
674
|
});
|
|
673
675
|
// Add getProductStories tool
|
|
674
|
-
server.tool("getProductStories", "获取产品需求列表 -
|
|
676
|
+
server.tool("getProductStories", "获取产品需求列表 - 包含软件需求(story)和用户需求(requirement),默认只返回核心字段(id, 标题, 指派人, 创建人)", {
|
|
675
677
|
productId: z.number(),
|
|
676
678
|
page: z.number().optional().describe("页码,从1开始,默认为1"),
|
|
677
679
|
limit: z.number().optional().describe("每页数量,默认20,最大100"),
|
|
@@ -831,11 +833,128 @@ server.tool("deleteExecution", { executionId: z.number() }, async ({ executionId
|
|
|
831
833
|
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteExecution(executionId), null, 2) }] };
|
|
832
834
|
});
|
|
833
835
|
// Story tools
|
|
834
|
-
server.tool("deleteStory",
|
|
836
|
+
server.tool("deleteStory", "删除需求 - 支持软件需求(story)和用户需求(requirement),自动识别类型", {
|
|
837
|
+
storyId: z.number().describe("需求ID(可以是story或requirement类型)")
|
|
838
|
+
}, async ({ storyId }) => {
|
|
835
839
|
if (!zentaoApi)
|
|
836
840
|
throw new Error("Please initialize Zentao API first");
|
|
837
841
|
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteStory(storyId), null, 2) }] };
|
|
838
842
|
});
|
|
843
|
+
// Requirement tools (用户需求专用工具 - 提供更好的语义化)
|
|
844
|
+
server.tool("createRequirement", "创建用户需求(requirement) - 用户需求的专用接口,提供更好的语义化", {
|
|
845
|
+
title: z.string(),
|
|
846
|
+
product: z.number(),
|
|
847
|
+
pri: z.number(),
|
|
848
|
+
category: z.string().optional(),
|
|
849
|
+
spec: z.string().optional(),
|
|
850
|
+
verify: z.string().optional(),
|
|
851
|
+
source: z.string().optional(),
|
|
852
|
+
sourceNote: z.string().optional(),
|
|
853
|
+
estimate: z.number().optional(),
|
|
854
|
+
keywords: z.string().optional()
|
|
855
|
+
}, async ({ title, product, pri, category, spec, verify, source, sourceNote, estimate, keywords }) => {
|
|
856
|
+
if (!zentaoApi)
|
|
857
|
+
throw new Error("Please initialize Zentao API first");
|
|
858
|
+
// 调用 createStory 但强制设置 type='requirement'
|
|
859
|
+
const requirement = await zentaoApi.createStory({
|
|
860
|
+
title,
|
|
861
|
+
product,
|
|
862
|
+
pri,
|
|
863
|
+
type: 'requirement',
|
|
864
|
+
category,
|
|
865
|
+
spec,
|
|
866
|
+
verify,
|
|
867
|
+
source,
|
|
868
|
+
sourceNote,
|
|
869
|
+
estimate,
|
|
870
|
+
keywords
|
|
871
|
+
});
|
|
872
|
+
return {
|
|
873
|
+
content: [{ type: "text", text: JSON.stringify(requirement, null, 2) }]
|
|
874
|
+
};
|
|
875
|
+
});
|
|
876
|
+
server.tool("getRequirementDetail", "获取用户需求详情 - 用户需求的专用接口,提供更好的语义化", {
|
|
877
|
+
requirementId: z.number().describe("用户需求ID"),
|
|
878
|
+
fields: z.enum(['basic', 'detail', 'full']).optional().describe(`
|
|
879
|
+
字段级别:
|
|
880
|
+
- basic: 基本信息(id, title, status, stage, pri等核心字段)
|
|
881
|
+
- detail: 详细信息(包含spec和verify,但不包含executions/tasks/stages/children等关联数据)
|
|
882
|
+
- full: 完整信息(包含所有字段,默认值)
|
|
883
|
+
`.trim())
|
|
884
|
+
}, async ({ requirementId, fields }) => {
|
|
885
|
+
if (!zentaoApi)
|
|
886
|
+
throw new Error("Please initialize Zentao API first");
|
|
887
|
+
const requirement = await zentaoApi.getStoryDetail(requirementId, fields);
|
|
888
|
+
const result = {
|
|
889
|
+
fieldLevel: fields || 'full',
|
|
890
|
+
requirement: requirement
|
|
891
|
+
};
|
|
892
|
+
if (fields === 'basic') {
|
|
893
|
+
result.note = '仅显示基本信息,如需完整内容请使用 fields=detail 或 fields=full';
|
|
894
|
+
}
|
|
895
|
+
else if (fields === 'detail') {
|
|
896
|
+
result.note = '显示详细信息但不包含关联数据(executions/tasks/stages/children),如需完整内容请使用 fields=full';
|
|
897
|
+
}
|
|
898
|
+
return {
|
|
899
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
900
|
+
};
|
|
901
|
+
});
|
|
902
|
+
server.tool("changeRequirement", "用户需求变更 - 用户需求的专用接口,提供更好的语义化", {
|
|
903
|
+
requirementId: z.number().describe("用户需求ID"),
|
|
904
|
+
update: z.union([
|
|
905
|
+
z.object({
|
|
906
|
+
title: z.string().optional(),
|
|
907
|
+
product: z.number().optional(),
|
|
908
|
+
parent: z.number().optional(),
|
|
909
|
+
module: z.number().optional(),
|
|
910
|
+
pri: z.number().optional(),
|
|
911
|
+
category: z.string().optional(),
|
|
912
|
+
spec: z.string().optional(),
|
|
913
|
+
verify: z.string().optional(),
|
|
914
|
+
source: z.string().optional(),
|
|
915
|
+
sourceNote: z.string().optional(),
|
|
916
|
+
estimate: z.number().optional(),
|
|
917
|
+
keywords: z.string().optional(),
|
|
918
|
+
assignedTo: z.string().optional(),
|
|
919
|
+
reviewer: z.array(z.string()).optional(),
|
|
920
|
+
comment: z.string().optional()
|
|
921
|
+
}),
|
|
922
|
+
z.string().describe("JSON字符串格式的更新内容")
|
|
923
|
+
]).describe(`
|
|
924
|
+
更新用户需求(使用 PUT /stories/:id 接口)
|
|
925
|
+
|
|
926
|
+
此工具使用标准的"修改需求其他字段"接口(PUT /stories/:id),支持修改多个字段。
|
|
927
|
+
自动处理评审人问题,无需手动设置 needNotReview。
|
|
928
|
+
|
|
929
|
+
支持对象或JSON字符串格式。
|
|
930
|
+
`.trim())
|
|
931
|
+
}, async ({ requirementId, update }) => {
|
|
932
|
+
if (!zentaoApi)
|
|
933
|
+
throw new Error("Please initialize Zentao API first");
|
|
934
|
+
let updateData;
|
|
935
|
+
if (typeof update === 'string') {
|
|
936
|
+
try {
|
|
937
|
+
updateData = JSON.parse(update);
|
|
938
|
+
}
|
|
939
|
+
catch (e) {
|
|
940
|
+
throw new Error('Invalid JSON string for update parameter');
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
updateData = update;
|
|
945
|
+
}
|
|
946
|
+
const requirement = await zentaoApi.changeStory(requirementId, updateData);
|
|
947
|
+
return {
|
|
948
|
+
content: [{ type: "text", text: JSON.stringify(requirement, null, 2) }]
|
|
949
|
+
};
|
|
950
|
+
});
|
|
951
|
+
server.tool("deleteRequirement", "删除用户需求 - 用户需求的专用接口,提供更好的语义化", {
|
|
952
|
+
requirementId: z.number().describe("用户需求ID")
|
|
953
|
+
}, async ({ requirementId }) => {
|
|
954
|
+
if (!zentaoApi)
|
|
955
|
+
throw new Error("Please initialize Zentao API first");
|
|
956
|
+
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteStory(requirementId), null, 2) }] };
|
|
957
|
+
});
|
|
839
958
|
// Bug tools
|
|
840
959
|
server.tool("updateBug", {
|
|
841
960
|
bugId: z.number(),
|
|
@@ -1385,6 +1504,95 @@ server.tool("downloadFile", {
|
|
|
1385
1504
|
fs.writeFileSync(savePath, fileBuffer);
|
|
1386
1505
|
return { content: [{ type: "text", text: `文件已下载到: ${savePath}` }] };
|
|
1387
1506
|
});
|
|
1507
|
+
// Comment tools (评论工具)
|
|
1508
|
+
server.tool("addComment", "添加评论 - 为需求、任务、Bug等对象添加评论", {
|
|
1509
|
+
objectType: z.enum([
|
|
1510
|
+
'story', // 软件需求
|
|
1511
|
+
'requirement', // 用户需求
|
|
1512
|
+
'task', // 任务
|
|
1513
|
+
'bug', // Bug
|
|
1514
|
+
'testcase', // 测试用例
|
|
1515
|
+
'testtask', // 测试单
|
|
1516
|
+
'todo', // 待办
|
|
1517
|
+
'doc', // 文档
|
|
1518
|
+
'doctemplate' // 文档模板
|
|
1519
|
+
]).describe("对象类型"),
|
|
1520
|
+
objectID: z.number().describe("对象ID"),
|
|
1521
|
+
comment: z.string().describe("评论内容,支持HTML格式")
|
|
1522
|
+
}, async ({ objectType, objectID, comment }) => {
|
|
1523
|
+
if (!zentaoApi)
|
|
1524
|
+
throw new Error("Please initialize Zentao API first");
|
|
1525
|
+
const result = await zentaoApi.addComment(objectType, objectID, comment);
|
|
1526
|
+
return {
|
|
1527
|
+
content: [{
|
|
1528
|
+
type: "text",
|
|
1529
|
+
text: JSON.stringify({
|
|
1530
|
+
status: result.status,
|
|
1531
|
+
message: result.message,
|
|
1532
|
+
actionID: result.actionID,
|
|
1533
|
+
details: `已为 ${objectType} #${objectID} 添加评论`
|
|
1534
|
+
}, null, 2)
|
|
1535
|
+
}]
|
|
1536
|
+
};
|
|
1537
|
+
});
|
|
1538
|
+
server.tool("addStoryComment", "为需求添加评论 - 专用工具,支持软件需求(story)和用户需求(requirement)", {
|
|
1539
|
+
storyId: z.number().describe("需求ID"),
|
|
1540
|
+
comment: z.string().describe("评论内容,支持HTML格式")
|
|
1541
|
+
}, async ({ storyId, comment }) => {
|
|
1542
|
+
if (!zentaoApi)
|
|
1543
|
+
throw new Error("Please initialize Zentao API first");
|
|
1544
|
+
// 使用 'story' 类型,API会自动识别是 story 还是 requirement
|
|
1545
|
+
const result = await zentaoApi.addComment('story', storyId, comment);
|
|
1546
|
+
return {
|
|
1547
|
+
content: [{
|
|
1548
|
+
type: "text",
|
|
1549
|
+
text: JSON.stringify({
|
|
1550
|
+
status: result.status,
|
|
1551
|
+
message: result.message,
|
|
1552
|
+
actionID: result.actionID,
|
|
1553
|
+
details: `已为需求 #${storyId} 添加评论`
|
|
1554
|
+
}, null, 2)
|
|
1555
|
+
}]
|
|
1556
|
+
};
|
|
1557
|
+
});
|
|
1558
|
+
server.tool("addTaskComment", "为任务添加评论", {
|
|
1559
|
+
taskId: z.number().describe("任务ID"),
|
|
1560
|
+
comment: z.string().describe("评论内容,支持HTML格式")
|
|
1561
|
+
}, async ({ taskId, comment }) => {
|
|
1562
|
+
if (!zentaoApi)
|
|
1563
|
+
throw new Error("Please initialize Zentao API first");
|
|
1564
|
+
const result = await zentaoApi.addComment('task', taskId, comment);
|
|
1565
|
+
return {
|
|
1566
|
+
content: [{
|
|
1567
|
+
type: "text",
|
|
1568
|
+
text: JSON.stringify({
|
|
1569
|
+
status: result.status,
|
|
1570
|
+
message: result.message,
|
|
1571
|
+
actionID: result.actionID,
|
|
1572
|
+
details: `已为任务 #${taskId} 添加评论`
|
|
1573
|
+
}, null, 2)
|
|
1574
|
+
}]
|
|
1575
|
+
};
|
|
1576
|
+
});
|
|
1577
|
+
server.tool("addBugComment", "为Bug添加评论", {
|
|
1578
|
+
bugId: z.number().describe("Bug ID"),
|
|
1579
|
+
comment: z.string().describe("评论内容,支持HTML格式")
|
|
1580
|
+
}, async ({ bugId, comment }) => {
|
|
1581
|
+
if (!zentaoApi)
|
|
1582
|
+
throw new Error("Please initialize Zentao API first");
|
|
1583
|
+
const result = await zentaoApi.addComment('bug', bugId, comment);
|
|
1584
|
+
return {
|
|
1585
|
+
content: [{
|
|
1586
|
+
type: "text",
|
|
1587
|
+
text: JSON.stringify({
|
|
1588
|
+
status: result.status,
|
|
1589
|
+
message: result.message,
|
|
1590
|
+
actionID: result.actionID,
|
|
1591
|
+
details: `已为Bug #${bugId} 添加评论`
|
|
1592
|
+
}, null, 2)
|
|
1593
|
+
}]
|
|
1594
|
+
};
|
|
1595
|
+
});
|
|
1388
1596
|
// Start receiving messages on stdin and sending messages on stdout
|
|
1389
1597
|
const transport = new StdioServerTransport();
|
|
1390
1598
|
await server.connect(transport).catch(console.error);
|
package/dist/types/zentao.d.ts
CHANGED
|
@@ -180,6 +180,7 @@ export interface CreateStoryRequest {
|
|
|
180
180
|
title: string;
|
|
181
181
|
product: number;
|
|
182
182
|
pri: number;
|
|
183
|
+
type?: 'story' | 'requirement';
|
|
183
184
|
category?: string;
|
|
184
185
|
spec?: string;
|
|
185
186
|
verify?: string;
|
|
@@ -716,3 +717,14 @@ export interface UploadFileRequest {
|
|
|
716
717
|
filename: string;
|
|
717
718
|
uid?: string;
|
|
718
719
|
}
|
|
720
|
+
export type CommentObjectType = 'story' | 'requirement' | 'task' | 'bug' | 'testcase' | 'testtask' | 'todo' | 'doc' | 'doctemplate';
|
|
721
|
+
export interface AddCommentRequest {
|
|
722
|
+
objectType: CommentObjectType;
|
|
723
|
+
objectID: number;
|
|
724
|
+
comment: string;
|
|
725
|
+
}
|
|
726
|
+
export interface CommentResponse {
|
|
727
|
+
status: string;
|
|
728
|
+
data?: number;
|
|
729
|
+
message?: string;
|
|
730
|
+
}
|