@zzp123/mcp-zentao 1.14.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 CHANGED
@@ -5,6 +5,37 @@ 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
+
8
39
  ## [1.14.0] - 2025-11-07
9
40
 
10
41
  ### Added
@@ -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
  }
@@ -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
@@ -1504,6 +1504,95 @@ server.tool("downloadFile", {
1504
1504
  fs.writeFileSync(savePath, fileBuffer);
1505
1505
  return { content: [{ type: "text", text: `文件已下载到: ${savePath}` }] };
1506
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
+ });
1507
1596
  // Start receiving messages on stdin and sending messages on stdout
1508
1597
  const transport = new StdioServerTransport();
1509
1598
  await server.connect(transport).catch(console.error);
@@ -717,3 +717,14 @@ export interface UploadFileRequest {
717
717
  filename: string;
718
718
  uid?: string;
719
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzp123/mcp-zentao",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "禅道项目管理系统的高级API集成包,提供任务管理、Bug跟踪等功能的完整封装,专为Cursor IDE设计的MCP扩展",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",