@zzp123/mcp-zentao 1.7.3 → 1.8.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,43 @@ 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.8.0] - 2025-11-06
9
+
10
+ ### Changed
11
+ - **重构需求变更接口命名**
12
+ - 将 `updateStory` 工具重命名为 `changeStory`,更准确地反映其功能
13
+ - 将 `UpdateStoryRequest` 类型重命名为 `ChangeStoryRequest`
14
+ - 将 `updateStory` API方法重命名为 `changeStory`
15
+ - 使用功能完整的"修改需求其他字段"接口替代功能有限的"变更需求"接口
16
+
17
+ ### Added
18
+ - 向后兼容的类型别名:`UpdateStoryRequest` 作为 `ChangeStoryRequest` 的别名
19
+
20
+ ### Technical
21
+ - 统一需求变更相关的命名规范
22
+ - 保持向后兼容性,旧的类型名称仍然可用
23
+ - 所有测试通过,确保重构不影响现有功能
24
+
25
+ ## [1.7.4] - 2025-11-06
26
+
27
+ ### Fixed
28
+ - **修复 createTask 和 updateStory 中的评审人相关错误**
29
+ - 修复 `createTask` 工具中 `assignedTo` 参数类型错误(从字符串改为数组)
30
+ - 修复 `createTask` 工具中必填参数缺失问题(execution, type, estStarted, deadline)
31
+ - 修复 `updateStory` 工具中"评审人不能为null"错误
32
+ - 为 `updateStory` 添加自动跳过评审机制(needNotReview=true)
33
+
34
+ ### Changed
35
+ - `CreateTaskRequest` 接口更新:将 assignedTo 从可选字符串改为必需数组
36
+ - `createTask` MCP 工具参数重新定义:必填参数前置,类型修正
37
+ - `updateStory` API 方法添加智能评审人处理逻辑
38
+ - API 请求表单数据处理:支持数组类型参数的正确格式化
39
+
40
+ ### Technical
41
+ - 更新测试文件以适配新的接口要求
42
+ - TypeScript 编译验证通过,确保类型安全
43
+ - 保持向后兼容性,同时修复API规范问题
44
+
8
45
  ## [1.7.3] - 2025-11-06
9
46
 
10
47
  ### Fixed
@@ -1,4 +1,4 @@
1
- import { AssignFeedbackRequest, Bug, BugStatus, Build, CloseFeedbackRequest, CreateBuildRequest, CreateBugRequest, CreateExecutionRequest, CreateFeedbackRequest, CreatePlanRequest, CreateProductRequest, CreateProgramRequest, CreateProjectRequest, CreateStoryRequest, CreateTaskRequest, CreateTestCaseRequest, CreateTicketRequest, CreateUserRequest, Execution, Feedback, FileUploadResponse, ModulesResponse, ModuleType, Plan, Product, Program, Project, Release, ResolveBugRequest, Story, Task, TaskStatus, TaskUpdate, TestCase, Ticket, UpdateBuildRequest, UpdateBugRequest, UpdateExecutionRequest, UpdateFeedbackRequest, UpdatePlanRequest, UpdateProductRequest, UpdateProgramRequest, UpdateProjectRequest, UpdateStoryRequest, UpdateTestCaseRequest, UpdateTicketRequest, UpdateUserRequest, UploadFileRequest, UserDetail, ZentaoConfig } from '../types/zentao';
1
+ import { AssignFeedbackRequest, Bug, BugStatus, Build, CloseFeedbackRequest, CreateBuildRequest, CreateBugRequest, CreateExecutionRequest, CreateFeedbackRequest, CreatePlanRequest, CreateProductRequest, CreateProgramRequest, CreateProjectRequest, CreateStoryRequest, CreateTaskRequest, CreateTestCaseRequest, CreateTicketRequest, CreateUserRequest, Execution, Feedback, FileUploadResponse, ModulesResponse, ModuleType, Plan, Product, Program, Project, Release, ResolveBugRequest, Story, Task, TaskStatus, TaskUpdate, TestCase, Ticket, UpdateBuildRequest, UpdateBugRequest, UpdateExecutionRequest, UpdateFeedbackRequest, UpdatePlanRequest, UpdateProductRequest, UpdateProgramRequest, UpdateProjectRequest, ChangeStoryRequest, UpdateTestCaseRequest, UpdateTicketRequest, UpdateUserRequest, UploadFileRequest, UserDetail, ZentaoConfig } from '../types/zentao';
2
2
  export declare class ZentaoAPI {
3
3
  private config;
4
4
  private client;
@@ -33,7 +33,7 @@ export declare class ZentaoAPI {
33
33
  getProjectExecutions(projectId: number): Promise<Execution[]>;
34
34
  createPlan(productId: number, plan: CreatePlanRequest): Promise<Plan>;
35
35
  getProjects(page?: number, limit?: number): Promise<Project[]>;
36
- updateStory(storyId: number, update: UpdateStoryRequest): Promise<Story>;
36
+ changeStory(storyId: number, update: ChangeStoryRequest): Promise<Story>;
37
37
  deleteTask(taskId: number): Promise<{
38
38
  message: string;
39
39
  }>;
@@ -217,7 +217,15 @@ export class ZentaoAPI {
217
217
  const formData = new URLSearchParams();
218
218
  Object.entries(task).forEach(([key, value]) => {
219
219
  if (value !== undefined && value !== null) {
220
- formData.append(key, value.toString());
220
+ if (key === 'assignedTo' && Array.isArray(value)) {
221
+ // 对于assignedTo数组,需要特殊处理
222
+ value.forEach((item, index) => {
223
+ formData.append(`${key}[${index}]`, item.toString());
224
+ });
225
+ }
226
+ else {
227
+ formData.append(key, value.toString());
228
+ }
221
229
  }
222
230
  });
223
231
  // 在URL中添加执行ID
@@ -487,15 +495,22 @@ export class ZentaoAPI {
487
495
  throw error;
488
496
  }
489
497
  }
490
- async updateStory(storyId, update) {
498
+ async changeStory(storyId, update) {
491
499
  try {
492
- console.log(`正在更新需求 ${storyId}...`);
493
- const response = await this.request('PUT', `/stories/${storyId}`, undefined, update);
494
- console.log('更新需求响应:', response);
500
+ console.log(`正在变更需求 ${storyId}...`);
501
+ // 自动处理评审人问题
502
+ const updateData = { ...update };
503
+ // 如果用户没有设置评审人,也没有指定无需评审,则自动跳过评审
504
+ if (!updateData.reviewer && updateData.needNotReview !== true) {
505
+ updateData.needNotReview = true;
506
+ console.log('自动设置needNotReview=true以跳过评审要求');
507
+ }
508
+ const response = await this.request('PUT', `/stories/${storyId}`, undefined, updateData);
509
+ console.log('变更需求响应:', response);
495
510
  return response;
496
511
  }
497
512
  catch (error) {
498
- console.error('更新需求失败:', error);
513
+ console.error('变更需求失败:', error);
499
514
  throw error;
500
515
  }
501
516
  }
package/dist/index.js CHANGED
@@ -197,32 +197,32 @@ server.tool("getProductPlans", {
197
197
  server.tool("createTask", {
198
198
  name: z.string(),
199
199
  execution: z.number(),
200
+ type: z.string(),
201
+ assignedTo: z.array(z.string()),
202
+ estStarted: z.string(),
203
+ deadline: z.string(),
200
204
  desc: z.string().optional(),
201
205
  pri: z.number().min(1).max(4).optional(),
202
206
  estimate: z.number().optional(),
203
207
  project: z.number().optional(),
204
208
  module: z.number().optional(),
205
- story: z.number().optional(),
206
- type: z.string().optional(),
207
- assignedTo: z.string().optional(),
208
- estStarted: z.string().optional(),
209
- deadline: z.string().optional()
209
+ story: z.number().optional()
210
210
  }, async ({ name, execution, desc, pri, estimate, project, module, story, type, assignedTo, estStarted, deadline }) => {
211
211
  if (!zentaoApi)
212
212
  throw new Error("Please initialize Zentao API first");
213
213
  const task = await zentaoApi.createTask({
214
214
  name,
215
215
  execution,
216
+ type,
217
+ assignedTo,
218
+ estStarted,
219
+ deadline,
216
220
  desc,
217
221
  pri,
218
222
  estimate,
219
223
  project,
220
224
  module,
221
- story,
222
- type,
223
- assignedTo,
224
- estStarted,
225
- deadline
225
+ story
226
226
  });
227
227
  return {
228
228
  content: [{ type: "text", text: JSON.stringify(task, null, 2) }]
@@ -460,8 +460,8 @@ server.tool("getProjects", {
460
460
  content: [{ type: "text", text: JSON.stringify(projects, null, 2) }]
461
461
  };
462
462
  });
463
- // Add updateStory tool
464
- server.tool("updateStory", {
463
+ // Add changeStory tool
464
+ server.tool("changeStory", {
465
465
  storyId: z.number(),
466
466
  update: z.union([
467
467
  z.object({
@@ -507,7 +507,7 @@ server.tool("updateStory", {
507
507
  comment: z.string().optional()
508
508
  }),
509
509
  z.string()
510
- ]).describe("需求更新字段 - 支持对象或JSON字符串格式")
510
+ ]).describe("需求变更字段 - 支持对象或JSON字符串格式")
511
511
  }, async ({ storyId, update }) => {
512
512
  if (!zentaoApi)
513
513
  throw new Error("Please initialize Zentao API first");
@@ -524,7 +524,7 @@ server.tool("updateStory", {
524
524
  else {
525
525
  updateData = update;
526
526
  }
527
- const story = await zentaoApi.updateStory(storyId, updateData);
527
+ const story = await zentaoApi.changeStory(storyId, updateData);
528
528
  return {
529
529
  content: [{ type: "text", text: JSON.stringify(story, null, 2) }]
530
530
  };
@@ -10,13 +10,13 @@ export interface CreateTaskRequest {
10
10
  pri?: number;
11
11
  estimate?: number;
12
12
  project?: number;
13
- execution?: number;
13
+ execution: number;
14
14
  module?: number;
15
15
  story?: number;
16
- type?: string;
17
- assignedTo?: string;
18
- estStarted?: string;
19
- deadline?: string;
16
+ type: string;
17
+ assignedTo: string[];
18
+ estStarted: string;
19
+ deadline: string;
20
20
  }
21
21
  export interface Task {
22
22
  id: number;
@@ -256,7 +256,7 @@ export interface Project {
256
256
  PM: string | User;
257
257
  progress: number;
258
258
  }
259
- export interface UpdateStoryRequest {
259
+ export interface ChangeStoryRequest {
260
260
  title?: string;
261
261
  product?: number;
262
262
  parent?: number;
@@ -287,6 +287,7 @@ export interface UpdateStoryRequest {
287
287
  verify?: string;
288
288
  comment?: string;
289
289
  }
290
+ export type UpdateStoryRequest = ChangeStoryRequest;
290
291
  export interface CreateProgramRequest {
291
292
  name?: string;
292
293
  parent?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzp123/mcp-zentao",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "禅道项目管理系统的高级API集成包,提供任务管理、Bug跟踪等功能的完整封装,专为Cursor IDE设计的MCP扩展",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",