@xurenxiang1219/pingcode-mcp 0.3.1

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.
Files changed (268) hide show
  1. package/.env.example +115 -0
  2. package/.env.stdio.local.example +13 -0
  3. package/README.md +222 -0
  4. package/dist/approve-write.d.ts +3 -0
  5. package/dist/approve-write.d.ts.map +1 -0
  6. package/dist/approve-write.js +81 -0
  7. package/dist/approve-write.js.map +1 -0
  8. package/dist/auth/cimd-client-resolver.d.ts +35 -0
  9. package/dist/auth/cimd-client-resolver.d.ts.map +1 -0
  10. package/dist/auth/cimd-client-resolver.js +293 -0
  11. package/dist/auth/cimd-client-resolver.js.map +1 -0
  12. package/dist/auth/memory-store.d.ts +15 -0
  13. package/dist/auth/memory-store.d.ts.map +1 -0
  14. package/dist/auth/memory-store.js +46 -0
  15. package/dist/auth/memory-store.js.map +1 -0
  16. package/dist/auth/pingcode-oauth-client.d.ts +23 -0
  17. package/dist/auth/pingcode-oauth-client.d.ts.map +1 -0
  18. package/dist/auth/pingcode-oauth-client.js +103 -0
  19. package/dist/auth/pingcode-oauth-client.js.map +1 -0
  20. package/dist/auth/pingcode-oauth-provider.d.ts +70 -0
  21. package/dist/auth/pingcode-oauth-provider.d.ts.map +1 -0
  22. package/dist/auth/pingcode-oauth-provider.js +414 -0
  23. package/dist/auth/pingcode-oauth-provider.js.map +1 -0
  24. package/dist/auth/redis-store.d.ts +16 -0
  25. package/dist/auth/redis-store.d.ts.map +1 -0
  26. package/dist/auth/redis-store.js +54 -0
  27. package/dist/auth/redis-store.js.map +1 -0
  28. package/dist/auth/runtime.d.ts +10 -0
  29. package/dist/auth/runtime.d.ts.map +1 -0
  30. package/dist/auth/runtime.js +57 -0
  31. package/dist/auth/runtime.js.map +1 -0
  32. package/dist/auth/store.d.ts +35 -0
  33. package/dist/auth/store.d.ts.map +1 -0
  34. package/dist/auth/store.js +55 -0
  35. package/dist/auth/store.js.map +1 -0
  36. package/dist/auth/token-cipher.d.ts +7 -0
  37. package/dist/auth/token-cipher.d.ts.map +1 -0
  38. package/dist/auth/token-cipher.js +36 -0
  39. package/dist/auth/token-cipher.js.map +1 -0
  40. package/dist/config.d.ts +54 -0
  41. package/dist/config.d.ts.map +1 -0
  42. package/dist/config.js +270 -0
  43. package/dist/config.js.map +1 -0
  44. package/dist/domain/content-hash.d.ts +5 -0
  45. package/dist/domain/content-hash.d.ts.map +1 -0
  46. package/dist/domain/content-hash.js +17 -0
  47. package/dist/domain/content-hash.js.map +1 -0
  48. package/dist/domain/requirement-context.d.ts +29 -0
  49. package/dist/domain/requirement-context.d.ts.map +1 -0
  50. package/dist/domain/requirement-context.js +2 -0
  51. package/dist/domain/requirement-context.js.map +1 -0
  52. package/dist/domain/test-case-context.d.ts +56 -0
  53. package/dist/domain/test-case-context.d.ts.map +1 -0
  54. package/dist/domain/test-case-context.js +2 -0
  55. package/dist/domain/test-case-context.js.map +1 -0
  56. package/dist/domain/work-item-context.d.ts +47 -0
  57. package/dist/domain/work-item-context.d.ts.map +1 -0
  58. package/dist/domain/work-item-context.js +2 -0
  59. package/dist/domain/work-item-context.js.map +1 -0
  60. package/dist/environment.d.ts +2 -0
  61. package/dist/environment.d.ts.map +1 -0
  62. package/dist/environment.js +21 -0
  63. package/dist/environment.js.map +1 -0
  64. package/dist/index.d.ts +3 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +52 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/inspect-wiki.d.ts +3 -0
  69. package/dist/inspect-wiki.d.ts.map +1 -0
  70. package/dist/inspect-wiki.js +49 -0
  71. package/dist/inspect-wiki.js.map +1 -0
  72. package/dist/logger.d.ts +9 -0
  73. package/dist/logger.d.ts.map +1 -0
  74. package/dist/logger.js +40 -0
  75. package/dist/logger.js.map +1 -0
  76. package/dist/mcp/create-server.d.ts +10 -0
  77. package/dist/mcp/create-server.d.ts.map +1 -0
  78. package/dist/mcp/create-server.js +40 -0
  79. package/dist/mcp/create-server.js.map +1 -0
  80. package/dist/mcp/pagination-guidance.d.ts +19 -0
  81. package/dist/mcp/pagination-guidance.d.ts.map +1 -0
  82. package/dist/mcp/pagination-guidance.js +36 -0
  83. package/dist/mcp/pagination-guidance.js.map +1 -0
  84. package/dist/mcp/reference-resolution.d.ts +19 -0
  85. package/dist/mcp/reference-resolution.d.ts.map +1 -0
  86. package/dist/mcp/reference-resolution.js +160 -0
  87. package/dist/mcp/reference-resolution.js.map +1 -0
  88. package/dist/mcp/tool-registry.d.ts +2 -0
  89. package/dist/mcp/tool-registry.d.ts.map +1 -0
  90. package/dist/mcp/tool-registry.js +55 -0
  91. package/dist/mcp/tool-registry.js.map +1 -0
  92. package/dist/mcp/tool-runtime.d.ts +22 -0
  93. package/dist/mcp/tool-runtime.d.ts.map +1 -0
  94. package/dist/mcp/tool-runtime.js +214 -0
  95. package/dist/mcp/tool-runtime.js.map +1 -0
  96. package/dist/mcp/tools/member-role.d.ts +8 -0
  97. package/dist/mcp/tools/member-role.d.ts.map +1 -0
  98. package/dist/mcp/tools/member-role.js +451 -0
  99. package/dist/mcp/tools/member-role.js.map +1 -0
  100. package/dist/mcp/tools/metadata.d.ts +5 -0
  101. package/dist/mcp/tools/metadata.d.ts.map +1 -0
  102. package/dist/mcp/tools/metadata.js +606 -0
  103. package/dist/mcp/tools/metadata.js.map +1 -0
  104. package/dist/mcp/tools/project-context.d.ts +4 -0
  105. package/dist/mcp/tools/project-context.d.ts.map +1 -0
  106. package/dist/mcp/tools/project-context.js +111 -0
  107. package/dist/mcp/tools/project-context.js.map +1 -0
  108. package/dist/mcp/tools/project.d.ts +7 -0
  109. package/dist/mcp/tools/project.d.ts.map +1 -0
  110. package/dist/mcp/tools/project.js +370 -0
  111. package/dist/mcp/tools/project.js.map +1 -0
  112. package/dist/mcp/tools/relation.d.ts +7 -0
  113. package/dist/mcp/tools/relation.d.ts.map +1 -0
  114. package/dist/mcp/tools/relation.js +592 -0
  115. package/dist/mcp/tools/relation.js.map +1 -0
  116. package/dist/mcp/tools/runtime-info.d.ts +4 -0
  117. package/dist/mcp/tools/runtime-info.d.ts.map +1 -0
  118. package/dist/mcp/tools/runtime-info.js +49 -0
  119. package/dist/mcp/tools/runtime-info.js.map +1 -0
  120. package/dist/mcp/tools/ship-suite.d.ts +7 -0
  121. package/dist/mcp/tools/ship-suite.d.ts.map +1 -0
  122. package/dist/mcp/tools/ship-suite.js +636 -0
  123. package/dist/mcp/tools/ship-suite.js.map +1 -0
  124. package/dist/mcp/tools/ship.d.ts +7 -0
  125. package/dist/mcp/tools/ship.d.ts.map +1 -0
  126. package/dist/mcp/tools/ship.js +617 -0
  127. package/dist/mcp/tools/ship.js.map +1 -0
  128. package/dist/mcp/tools/sync.d.ts +10 -0
  129. package/dist/mcp/tools/sync.d.ts.map +1 -0
  130. package/dist/mcp/tools/sync.js +1110 -0
  131. package/dist/mcp/tools/sync.js.map +1 -0
  132. package/dist/mcp/tools/task.d.ts +5 -0
  133. package/dist/mcp/tools/task.d.ts.map +1 -0
  134. package/dist/mcp/tools/task.js +236 -0
  135. package/dist/mcp/tools/task.js.map +1 -0
  136. package/dist/mcp/tools/test-case-bulk.d.ts +7 -0
  137. package/dist/mcp/tools/test-case-bulk.d.ts.map +1 -0
  138. package/dist/mcp/tools/test-case-bulk.js +297 -0
  139. package/dist/mcp/tools/test-case-bulk.js.map +1 -0
  140. package/dist/mcp/tools/test-case-delete.d.ts +7 -0
  141. package/dist/mcp/tools/test-case-delete.d.ts.map +1 -0
  142. package/dist/mcp/tools/test-case-delete.js +247 -0
  143. package/dist/mcp/tools/test-case-delete.js.map +1 -0
  144. package/dist/mcp/tools/test-case.d.ts +5 -0
  145. package/dist/mcp/tools/test-case.d.ts.map +1 -0
  146. package/dist/mcp/tools/test-case.js +155 -0
  147. package/dist/mcp/tools/test-case.js.map +1 -0
  148. package/dist/mcp/tools/test-library.d.ts +7 -0
  149. package/dist/mcp/tools/test-library.d.ts.map +1 -0
  150. package/dist/mcp/tools/test-library.js +302 -0
  151. package/dist/mcp/tools/test-library.js.map +1 -0
  152. package/dist/mcp/tools/wiki.d.ts +5 -0
  153. package/dist/mcp/tools/wiki.d.ts.map +1 -0
  154. package/dist/mcp/tools/wiki.js +266 -0
  155. package/dist/mcp/tools/wiki.js.map +1 -0
  156. package/dist/mcp/write-approval.d.ts +48 -0
  157. package/dist/mcp/write-approval.d.ts.map +1 -0
  158. package/dist/mcp/write-approval.js +321 -0
  159. package/dist/mcp/write-approval.js.map +1 -0
  160. package/dist/observability/metrics.d.ts +46 -0
  161. package/dist/observability/metrics.d.ts.map +1 -0
  162. package/dist/observability/metrics.js +79 -0
  163. package/dist/observability/metrics.js.map +1 -0
  164. package/dist/pingcode/access-token-provider.d.ts +5 -0
  165. package/dist/pingcode/access-token-provider.d.ts.map +1 -0
  166. package/dist/pingcode/access-token-provider.js +2 -0
  167. package/dist/pingcode/access-token-provider.js.map +1 -0
  168. package/dist/pingcode/client.d.ts +43 -0
  169. package/dist/pingcode/client.d.ts.map +1 -0
  170. package/dist/pingcode/client.js +300 -0
  171. package/dist/pingcode/client.js.map +1 -0
  172. package/dist/pingcode/errors.d.ts +20 -0
  173. package/dist/pingcode/errors.d.ts.map +1 -0
  174. package/dist/pingcode/errors.js +14 -0
  175. package/dist/pingcode/errors.js.map +1 -0
  176. package/dist/pingcode/schemas.d.ts +465 -0
  177. package/dist/pingcode/schemas.d.ts.map +1 -0
  178. package/dist/pingcode/schemas.js +450 -0
  179. package/dist/pingcode/schemas.js.map +1 -0
  180. package/dist/pingcode/token-provider.d.ts +20 -0
  181. package/dist/pingcode/token-provider.d.ts.map +1 -0
  182. package/dist/pingcode/token-provider.js +97 -0
  183. package/dist/pingcode/token-provider.js.map +1 -0
  184. package/dist/pingcode/write-response.d.ts +9 -0
  185. package/dist/pingcode/write-response.d.ts.map +1 -0
  186. package/dist/pingcode/write-response.js +39 -0
  187. package/dist/pingcode/write-response.js.map +1 -0
  188. package/dist/services.d.ts +22 -0
  189. package/dist/services.d.ts.map +1 -0
  190. package/dist/services.js +84 -0
  191. package/dist/services.js.map +1 -0
  192. package/dist/sources/metadata-source.d.ts +445 -0
  193. package/dist/sources/metadata-source.d.ts.map +1 -0
  194. package/dist/sources/metadata-source.js +167 -0
  195. package/dist/sources/metadata-source.js.map +1 -0
  196. package/dist/sources/project-context-source.d.ts +61 -0
  197. package/dist/sources/project-context-source.d.ts.map +1 -0
  198. package/dist/sources/project-context-source.js +224 -0
  199. package/dist/sources/project-context-source.js.map +1 -0
  200. package/dist/sources/relation-source.d.ts +83 -0
  201. package/dist/sources/relation-source.d.ts.map +1 -0
  202. package/dist/sources/relation-source.js +129 -0
  203. package/dist/sources/relation-source.js.map +1 -0
  204. package/dist/sources/requirement-source.d.ts +5 -0
  205. package/dist/sources/requirement-source.d.ts.map +1 -0
  206. package/dist/sources/requirement-source.js +2 -0
  207. package/dist/sources/requirement-source.js.map +1 -0
  208. package/dist/sources/ship-source.d.ts +67 -0
  209. package/dist/sources/ship-source.d.ts.map +1 -0
  210. package/dist/sources/ship-source.js +135 -0
  211. package/dist/sources/ship-source.js.map +1 -0
  212. package/dist/sources/test-case-source.d.ts +30 -0
  213. package/dist/sources/test-case-source.d.ts.map +1 -0
  214. package/dist/sources/test-case-source.js +206 -0
  215. package/dist/sources/test-case-source.js.map +1 -0
  216. package/dist/sources/wiki-source.d.ts +34 -0
  217. package/dist/sources/wiki-source.d.ts.map +1 -0
  218. package/dist/sources/wiki-source.js +136 -0
  219. package/dist/sources/wiki-source.js.map +1 -0
  220. package/dist/sources/work-item-source.d.ts +33 -0
  221. package/dist/sources/work-item-source.d.ts.map +1 -0
  222. package/dist/sources/work-item-source.js +159 -0
  223. package/dist/sources/work-item-source.js.map +1 -0
  224. package/dist/sources/write-source.d.ts +461 -0
  225. package/dist/sources/write-source.d.ts.map +1 -0
  226. package/dist/sources/write-source.js +174 -0
  227. package/dist/sources/write-source.js.map +1 -0
  228. package/dist/transports/bearer-auth.d.ts +20 -0
  229. package/dist/transports/bearer-auth.d.ts.map +1 -0
  230. package/dist/transports/bearer-auth.js +79 -0
  231. package/dist/transports/bearer-auth.js.map +1 -0
  232. package/dist/transports/http.d.ts +11 -0
  233. package/dist/transports/http.d.ts.map +1 -0
  234. package/dist/transports/http.js +203 -0
  235. package/dist/transports/http.js.map +1 -0
  236. package/dist/transports/metrics-auth.d.ts +3 -0
  237. package/dist/transports/metrics-auth.d.ts.map +1 -0
  238. package/dist/transports/metrics-auth.js +22 -0
  239. package/dist/transports/metrics-auth.js.map +1 -0
  240. package/dist/transports/stdio.d.ts +5 -0
  241. package/dist/transports/stdio.d.ts.map +1 -0
  242. package/dist/transports/stdio.js +11 -0
  243. package/dist/transports/stdio.js.map +1 -0
  244. package/dist/uat/run-label.d.ts +2 -0
  245. package/dist/uat/run-label.d.ts.map +1 -0
  246. package/dist/uat/run-label.js +12 -0
  247. package/dist/uat/run-label.js.map +1 -0
  248. package/dist/verify.d.ts +3 -0
  249. package/dist/verify.d.ts.map +1 -0
  250. package/dist/verify.js +59 -0
  251. package/dist/verify.js.map +1 -0
  252. package/dist/write/approval.d.ts +35 -0
  253. package/dist/write/approval.d.ts.map +1 -0
  254. package/dist/write/approval.js +66 -0
  255. package/dist/write/approval.js.map +1 -0
  256. package/dist/write/plan.d.ts +2 -0
  257. package/dist/write/plan.d.ts.map +1 -0
  258. package/dist/write/plan.js +17 -0
  259. package/dist/write/plan.js.map +1 -0
  260. package/dist/write/runtime.d.ts +90 -0
  261. package/dist/write/runtime.d.ts.map +1 -0
  262. package/dist/write/runtime.js +244 -0
  263. package/dist/write/runtime.js.map +1 -0
  264. package/dist/write/store.d.ts +101 -0
  265. package/dist/write/store.d.ts.map +1 -0
  266. package/dist/write/store.js +201 -0
  267. package/dist/write/store.js.map +1 -0
  268. package/package.json +58 -0
@@ -0,0 +1,297 @@
1
+ import * as z from "zod/v4";
2
+ import { PingCodeError } from "../../pingcode/errors.js";
3
+ import { contentHashSchema } from "../../domain/content-hash.js";
4
+ import { verifyCreatedTestCase } from "./sync.js";
5
+ import { requestHash as calculateRequestHash } from "../../write/plan.js";
6
+ import { executeTool, requestIdForLog } from "../tool-runtime.js";
7
+ import { resolveCandidate, resolveUserReference } from "../reference-resolution.js";
8
+ import { approvalTokenSchema, commitWithApproval, formatPreviewToolResult, formatWriteConfirmationMessage, formatWriteToolResult, requestClientWriteConfirmation, resolveCommitVerification, } from "../write-approval.js";
9
+ const identifier = z.string().trim().min(1).max(200);
10
+ const contentHash = contentHashSchema;
11
+ const agentSessionId = z.string().trim().min(8).max(200).optional();
12
+ const approvalContextId = z.string().uuid();
13
+ const sourceReferenceSchema = z.object({
14
+ type: z.enum(["wiki", "task", "test_case", "spec", "plan", "code", "project", "test_library"]),
15
+ id: identifier,
16
+ url: z.url().optional(),
17
+ content_hash: contentHash.optional(),
18
+ }).strict();
19
+ const bulkStepSchema = z.object({
20
+ description: z.string().trim().min(1).max(5_000),
21
+ expected_value: z.string().max(5_000).optional(),
22
+ }).strict();
23
+ const bulkPropertiesSchema = z
24
+ .record(z.string().trim().min(1).max(100), z.unknown())
25
+ .refine((value) => Object.keys(value).length <= 50, "properties 最多包含 50 个字段")
26
+ .refine((value) => Buffer.byteLength(JSON.stringify(value), "utf8") <= 32 * 1024, "properties 不得超过 32 KiB");
27
+ const bulkFieldsSchema = z.object({
28
+ test_library_id: identifier.optional().describe("兼容字段;由 Tool 从测试库列表验证"),
29
+ test_library_name: identifier.optional().describe("测试库名称或标识;Tool 会从测试库列表解析 ID"),
30
+ title: z.string().trim().min(1).max(500).describe("测试用例标题"),
31
+ important_level: z.enum(["P0", "P1", "P2", "P3", "P4"]).optional().describe("重要程度名称"),
32
+ maintenance_id: identifier.optional().describe("兼容字段;由 Tool 从用户目录验证"),
33
+ maintenance_name: identifier.optional().describe("维护人姓名;Tool 会通过用户目录解析 ID"),
34
+ participant_ids: z.array(identifier).max(50).optional().describe("兼容字段;每个成员由 Tool 从用户目录验证"),
35
+ participant_names: z.array(identifier).max(50).optional().describe("关注人姓名列表;Tool 会通过用户目录解析 ID"),
36
+ properties: bulkPropertiesSchema.optional().describe("官方批量接口支持的属性"),
37
+ description: z.string().max(50_000).optional().describe("测试用例说明"),
38
+ precondition: z.string().max(50_000).optional().describe("测试前置条件"),
39
+ steps: z.array(bulkStepSchema).max(100).optional().describe("测试步骤,最多 100 条"),
40
+ }).strict()
41
+ .refine((value) => value.test_library_id !== undefined || value.test_library_name !== undefined, "test_library_id 或 test_library_name 至少提供一个")
42
+ .refine((value) => value.test_library_id === undefined || value.test_library_name === undefined, "test_library_id 与 test_library_name 不得同时提供")
43
+ .refine((value) => value.maintenance_id === undefined || value.maintenance_name === undefined, "maintenance_id 与 maintenance_name 不得同时提供")
44
+ .refine((value) => value.participant_ids === undefined || value.participant_names === undefined, "participant_ids 与 participant_names 不得同时提供");
45
+ const operationSchema = z.object({
46
+ operation_id: identifier,
47
+ action: z.literal("create"),
48
+ fields: bulkFieldsSchema,
49
+ source_references: z.array(sourceReferenceSchema).min(1).max(20),
50
+ }).strict();
51
+ const planSchema = z.object({
52
+ plan_id: identifier.describe("Test Case 批量创建计划 ID;由 Agent 生成,Preview 与 Commit 必须完全相同"),
53
+ operations: z.array(operationSchema).min(1).max(50),
54
+ }).strict();
55
+ export function registerTestCaseBulkTools(server, services, logger, runtime, writeApprovalMode) {
56
+ server.registerTool("pingcode_test_case_bulk_create_preview", {
57
+ title: "预览批量创建 PingCode Test Case",
58
+ description: "使用 PingCode 官方批量 Test Case 接口预览一次创建多个用例。创建的最小输入是 plan_id、operations[action=create]、fields.test_library_id 或 test_library_name(二选一)、fields.title 以及 operation 内的 source_references。用户未主动指定测试库时,先调用 pingcode_project_context_get;上下文只作为候选展示并询问是否复用,用户同意后才使用,否则调用 pingcode_test_library_list。只支持官方批量接口明确支持的字段;不包含模块、类型或 Relation,后续可使用对应 Tool 处理。Preview 不写入 PingCode,最多 50 个用例。不得在正常用户回复中展示内部审批字段或完整 JSON。",
59
+ inputSchema: {
60
+ ...planSchema.shape,
61
+ plan_id: planSchema.shape.plan_id.optional().describe("业务上必填;省略仅用于返回缺参引导"),
62
+ operations: planSchema.shape.operations.optional().describe("业务上必填;省略仅用于返回缺参引导"),
63
+ agent_session_id: agentSessionId,
64
+ },
65
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: true },
66
+ }, async (input, extra) => executeTool(logger, "pingcode_test_case_bulk_create_preview", requestIdForLog(extra.requestInfo?.headers["x-request-id"], extra.requestId), { planId: input.plan_id ?? "", operationCount: input.operations?.length ?? 0 }, () => {
67
+ if (input.plan_id === undefined || input.operations === undefined) {
68
+ throw new PingCodeError("缺少 plan_id 或 operations;请补充批量 Test Case 创建计划后重试 Preview", "BAD_REQUEST");
69
+ }
70
+ return previewBulkPlan({ plan_id: input.plan_id, operations: input.operations }, services, runtime, input.agent_session_id, extra.authInfo);
71
+ }, { formatResult: formatPreviewToolResult }));
72
+ server.registerTool("pingcode_test_case_bulk_create_commit", {
73
+ title: "提交批量创建 PingCode Test Case",
74
+ description: "依已核准的批量 Preview 创建 Test Case。必须原样复用 Preview 请求中的 plan_id 和 operations;批量接口可能部分成功,结果会逐条返回。响应无法逐条确认时返回 WRITE_OUTCOME_UNKNOWN,不得更换幂等键重试。不得在正常用户回复中展示内部审批字段或完整 JSON。",
75
+ inputSchema: {
76
+ ...planSchema.shape,
77
+ agent_session_id: agentSessionId,
78
+ preview_id: approvalContextId.optional().describe("可选。省略时 Server 依相同 plan_id 与 operations 自动匹配刚才的 Preview,并据此恢复 request hash、evidence hash、session binding 和幂等边界;仅当客户端确实读到 Preview 的 approvalContextId 时才需要传入"),
79
+ approval_context_id: approvalContextId.optional().describe("已弃用,等同 preview_id;新调用只传 preview_id"),
80
+ approval_token: approvalTokenSchema(writeApprovalMode),
81
+ idempotency_key: identifier.min(16).max(200).optional(),
82
+ },
83
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
84
+ }, async (input, extra) => executeTool(logger, "pingcode_test_case_bulk_create_commit", requestIdForLog(extra.requestInfo?.headers["x-request-id"], extra.requestId), { planId: input.plan_id, operationCount: input.operations.length }, async () => {
85
+ runtime.assertMcpWriteScope(extra.authInfo?.scopes);
86
+ const verification = await resolveCommitVerification(runtime, {
87
+ previewId: input.preview_id,
88
+ approvalContextId: input.approval_context_id,
89
+ idempotencyKey: input.idempotency_key,
90
+ requestHash: calculateRequestHash({ plan_id: input.plan_id, operations: input.operations }),
91
+ agentSessionId: input.agent_session_id,
92
+ authInfo: extra.authInfo,
93
+ }, "test_case");
94
+ const resolvedInput = {
95
+ ...input,
96
+ request_hash: verification.requestHash,
97
+ approval_context_id: verification.approvalContextId,
98
+ session_binding: verification.sessionBinding,
99
+ evidence_hash: verification.evidenceHash,
100
+ idempotency_key: verification.idempotencyKey,
101
+ };
102
+ const displayOperations = await buildDisplayOperations(resolvedInput, services);
103
+ assertCommitIntegrity(resolvedInput, displayOperations);
104
+ await requestClientWriteConfirmation(server, logger, writeApprovalMode, input.approval_token, bulkConfirmationMessage(resolvedInput, displayOperations), runtime.requiresConfirmation(["create"]));
105
+ return commitBulkPlan(resolvedInput, services, runtime, writeApprovalMode, extra.authInfo);
106
+ }, { formatResult: formatWriteToolResult }));
107
+ }
108
+ async function previewBulkPlan(input, services, runtime, agentSessionIdValue, authInfo) {
109
+ const operations = await buildDisplayOperations(input, services);
110
+ const requestHashValue = calculateRequestHash({ plan_id: input.plan_id, operations: input.operations });
111
+ const evidenceHash = calculateRequestHash({ planId: input.plan_id, requestHash: requestHashValue, operations });
112
+ const context = await runtime.createApprovalContext({
113
+ resourceType: "test_case",
114
+ requestHash: requestHashValue,
115
+ evidenceHash,
116
+ ...(agentSessionIdValue === undefined ? {} : { agentSessionId: agentSessionIdValue }),
117
+ ...(authInfo === undefined ? {} : { authInfo }),
118
+ });
119
+ return {
120
+ planId: input.plan_id,
121
+ requestHash: requestHashValue,
122
+ approvalContextId: context.approvalContextId,
123
+ sessionBinding: context.sessionBinding,
124
+ evidenceHash,
125
+ approvalExpiresAt: context.expiresAt,
126
+ counts: { creates: input.operations.length, updates: 0, relations: 0 },
127
+ warnings: ["批量接口可能逐条成功或失败;Commit 后将回读每个成功项", "模块、类型和 Relation 不在本批量请求中处理"],
128
+ operations,
129
+ };
130
+ }
131
+ async function buildDisplayOperations(input, services) {
132
+ const resolvedInput = await resolveBulkReferences(input, services);
133
+ const libraries = new Map();
134
+ await Promise.all([...new Set(resolvedInput.operations.map((operation) => operation.fields.test_library_id))].map(async (id) => {
135
+ if (id === undefined)
136
+ throw new PingCodeError("测试库尚未解析为有效资源", "BAD_REQUEST");
137
+ const library = await services.getMetadataSource().getTestLibrary(id);
138
+ libraries.set(id, `${library.name} (${library.identifier}),ID:${id}`);
139
+ }));
140
+ return resolvedInput.operations.map((operation) => ({
141
+ operationId: operation.operation_id,
142
+ action: "create",
143
+ targetId: null,
144
+ changes: Object.fromEntries(Object.entries(operation.fields).map(([field, value]) => [
145
+ field,
146
+ { before: null, after: field === "test_library_id" ? libraries.get(String(value)) ?? value : value },
147
+ ])),
148
+ sourceReferences: operation.source_references,
149
+ }));
150
+ }
151
+ async function resolveBulkReferences(input, services) {
152
+ const libraries = [];
153
+ if (input.operations.some((operation) => operation.fields.test_library_name !== undefined)) {
154
+ for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
155
+ const page = await services.getMetadataSource().listTestLibraries({ pageIndex, pageSize: 100 });
156
+ libraries.push(...page.values.map((library) => ({ id: library.id, name: library.name, identifier: library.identifier })));
157
+ if (libraries.length >= page.total || page.values.length === 0)
158
+ break;
159
+ }
160
+ }
161
+ const operations = [];
162
+ for (const operation of input.operations) {
163
+ const fields = { ...operation.fields };
164
+ if (fields.test_library_name !== undefined) {
165
+ fields.test_library_id = resolveCandidate("测试库", fields.test_library_id, fields.test_library_name, libraries);
166
+ }
167
+ else if (fields.test_library_id !== undefined) {
168
+ const library = await services.getMetadataSource().getTestLibrary(fields.test_library_id);
169
+ fields.test_library_id = library.id;
170
+ fields.test_library_name = `${library.name} (${library.identifier})`;
171
+ }
172
+ if (fields.test_library_name !== undefined && fields.test_library_id !== undefined) {
173
+ const selected = libraries.find((library) => library.id === fields.test_library_id);
174
+ if (selected)
175
+ fields.test_library_name = `${selected.name} (${selected.identifier ?? fields.test_library_id})`;
176
+ }
177
+ if (fields.maintenance_id !== undefined || fields.maintenance_name !== undefined) {
178
+ fields.maintenance_id = await resolveUserReference("维护人", fields.maintenance_id, fields.maintenance_name, services);
179
+ delete fields.maintenance_name;
180
+ }
181
+ if (fields.participant_names !== undefined) {
182
+ fields.participant_ids = await Promise.all(fields.participant_names.map(async (name) => {
183
+ const id = await resolveUserReference("关注人", undefined, name, services);
184
+ if (id === undefined)
185
+ throw new PingCodeError("关注人尚未解析为有效用户", "BAD_REQUEST");
186
+ return id;
187
+ }));
188
+ delete fields.participant_names;
189
+ }
190
+ else if (fields.participant_ids !== undefined) {
191
+ fields.participant_ids = await Promise.all(fields.participant_ids.map(async (id) => {
192
+ const resolved = await resolveUserReference("关注人", id, undefined, services);
193
+ if (resolved === undefined)
194
+ throw new PingCodeError("关注人尚未解析为有效用户", "BAD_REQUEST");
195
+ return resolved;
196
+ }));
197
+ }
198
+ operations.push({ ...operation, fields });
199
+ }
200
+ return { ...input, operations };
201
+ }
202
+ function assertCommitIntegrity(input, displayOperations) {
203
+ const plan = { plan_id: input.plan_id, operations: input.operations };
204
+ if (calculateRequestHash(plan) !== input.request_hash) {
205
+ throw new PingCodeError("Commit 内容与 Preview request hash 不一致", "CONFLICT");
206
+ }
207
+ const evidenceHash = calculateRequestHash({ planId: input.plan_id, requestHash: input.request_hash, operations: displayOperations });
208
+ if (evidenceHash !== input.evidence_hash) {
209
+ throw new PingCodeError("Commit 展示证据与 Preview 不一致,请重新生成 Preview", "CONFLICT");
210
+ }
211
+ }
212
+ function bulkConfirmationMessage(input, operations) {
213
+ const libraries = [...new Set(operations.map((operation) => String(operation.changes.test_library_id?.after ?? "未知测试库")))];
214
+ const titles = input.operations.map((operation) => operation.fields.title);
215
+ return formatWriteConfirmationMessage("即将批量创建 PingCode Test Case", [
216
+ `数量:${input.operations.length} 个`,
217
+ `目标测试库:${libraries.slice(0, 5).join("、")}${libraries.length > 5 ? `,另有 ${libraries.length - 5} 个` : ""}`,
218
+ `用例:${titles.slice(0, 5).join("、")}${titles.length > 5 ? `,另有 ${titles.length - 5} 个` : ""}`,
219
+ ]);
220
+ }
221
+ async function commitBulkPlan(input, services, runtime, writeApprovalMode, authInfo) {
222
+ const committed = await commitWithApproval(runtime, writeApprovalMode, {
223
+ resourceType: "test_case",
224
+ requestHash: input.request_hash,
225
+ evidenceHash: input.evidence_hash,
226
+ approvalContextId: input.approval_context_id,
227
+ sessionBinding: input.session_binding,
228
+ ...(input.agent_session_id === undefined ? {} : { agentSessionId: input.agent_session_id }),
229
+ approvalToken: input.approval_token,
230
+ idempotencyKey: input.idempotency_key,
231
+ ...(authInfo === undefined ? {} : { authInfo }),
232
+ actions: ["create"],
233
+ action: async () => {
234
+ const resolvedInput = await resolveBulkReferences(input, services);
235
+ const results = await services.getWriteSource().createTestCasesBulk(resolvedInput.operations.map((operation) => toWriteFields(operation.fields)));
236
+ if (results.length !== input.operations.length) {
237
+ throw new PingCodeError("批量创建响应数量与请求不一致,无法确认各项写入结果;禁止更换幂等键重试", "WRITE_OUTCOME_UNKNOWN");
238
+ }
239
+ const resources = [];
240
+ const failures = [];
241
+ for (const [index, result] of results.entries()) {
242
+ const operation = resolvedInput.operations[index];
243
+ if (result.state.toLowerCase() !== "success" || result.case === undefined) {
244
+ failures.push({ operationId: operation.operation_id, title: operation.fields.title, state: result.state, message: summarizeError(result.error) });
245
+ continue;
246
+ }
247
+ if (result.case.library.id !== operation.fields.test_library_id || result.case.title !== operation.fields.title) {
248
+ throw new PingCodeError("批量创建响应中的资源身份与请求不一致,无法安全确认写入结果;禁止更换幂等键重试", "WRITE_OUTCOME_UNKNOWN");
249
+ }
250
+ const verifiedId = await verifyCreatedTestCase(result.case.id, services);
251
+ const context = await services.getTestCaseSource().getTestCaseContext(verifiedId ?? result.case.id);
252
+ resources.push({
253
+ operationId: operation.operation_id,
254
+ action: "create",
255
+ id: context.source.id,
256
+ identifier: context.source.identifier,
257
+ title: context.title,
258
+ url: context.source.url,
259
+ relationIds: context.relationIds,
260
+ verified: true,
261
+ });
262
+ }
263
+ return { planId: input.plan_id, requestHash: input.request_hash, partial: failures.length > 0, resources, failures };
264
+ },
265
+ });
266
+ return {
267
+ planId: committed.result.planId,
268
+ partial: committed.result.partial,
269
+ resources: committed.result.resources,
270
+ failures: committed.result.failures,
271
+ replayed: committed.replayed,
272
+ approvedBy: committed.approval.approvedBy,
273
+ auditId: committed.auditId,
274
+ };
275
+ }
276
+ function toWriteFields(fields) {
277
+ return {
278
+ testLibraryId: fields.test_library_id,
279
+ title: fields.title,
280
+ importantLevel: fields.important_level,
281
+ maintenanceId: fields.maintenance_id,
282
+ participantIds: fields.participant_ids,
283
+ properties: fields.properties,
284
+ description: fields.description,
285
+ precondition: fields.precondition,
286
+ steps: fields.steps?.map((step) => ({ description: step.description, expectedValue: step.expected_value })),
287
+ };
288
+ }
289
+ function summarizeError(error) {
290
+ if (typeof error === "string" && error.trim())
291
+ return error.slice(0, 300);
292
+ if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
293
+ return error.message.slice(0, 300);
294
+ }
295
+ return "PingCode 未返回该项的详细错误";
296
+ }
297
+ //# sourceMappingURL=test-case-bulk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-bulk.js","sourceRoot":"","sources":["../../../src/mcp/tools/test-case-bulk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Logger } from "../../logger.js";
3
+ import type { Services } from "../../services.js";
4
+ import type { WriteRuntime } from "../../write/runtime.js";
5
+ import { type WriteApprovalMode } from "../write-approval.js";
6
+ export declare function registerTestCaseDeleteTools(server: McpServer, services: Services, logger: Logger, runtime: WriteRuntime, writeApprovalMode: WriteApprovalMode): void;
7
+ //# sourceMappingURL=test-case-delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-delete.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/test-case-delete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAI9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAQL,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAoD9B,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,EACrB,iBAAiB,EAAE,iBAAiB,GACnC,IAAI,CAkEN"}
@@ -0,0 +1,247 @@
1
+ import * as z from "zod/v4";
2
+ import { PingCodeError } from "../../pingcode/errors.js";
3
+ import { contentHashSchema, normalizeContentHash } from "../../domain/content-hash.js";
4
+ import { requestHash } from "../../write/plan.js";
5
+ import { executeTool, requestIdForLog } from "../tool-runtime.js";
6
+ import { approvalTokenSchema, commitWithApproval, formatPreviewToolResult, formatWriteConfirmationMessage, formatWriteToolResult, requestClientWriteConfirmation, resolveCommitVerification, } from "../write-approval.js";
7
+ const identifier = z.string().trim().min(1).max(200);
8
+ const contentHash = contentHashSchema;
9
+ const approvalContextId = z.string().uuid();
10
+ const agentSessionId = z.string().trim().min(8).max(200).optional();
11
+ const sourceReferenceSchema = z.object({
12
+ type: z.enum(["wiki", "task", "test_case", "spec", "plan", "code", "project", "test_library"]),
13
+ id: identifier,
14
+ url: z.url().optional(),
15
+ content_hash: contentHash.optional(),
16
+ }).strict();
17
+ const deleteOperationSchema = z.object({
18
+ operation_id: identifier.describe("删除计划内唯一操作 ID"),
19
+ action: z.literal("delete"),
20
+ fields: z.object({
21
+ test_case_id: identifier.describe("由 pingcode_test_case_get 返回的 Test Case 内部 ID"),
22
+ expected_content_hash: contentHash.describe("最近一次 pingcode_test_case_get 返回的 source.contentHash"),
23
+ }).strict(),
24
+ source_references: z.array(sourceReferenceSchema).min(1).max(20),
25
+ }).strict();
26
+ const testCaseDeletePlanSchema = z.object({
27
+ plan_id: identifier.describe("Test Case 删除计划 ID;Preview 与 Commit 必须完全相同"),
28
+ operations: z.array(deleteOperationSchema).length(1),
29
+ }).strict();
30
+ // Preview 的顶层字段允许先进入 handler,以便空参数返回统一的中文 BAD_REQUEST;
31
+ // operations 内部结构仍由 Zod 严格校验,Commit 继续使用完整必填 Schema。
32
+ const testCaseDeletePreviewInputSchema = z.object({
33
+ plan_id: identifier.optional().describe("业务上必填的 Test Case 删除计划 ID;省略仅用于触发缺参引导,正常 Preview 必须提供"),
34
+ operations: z.array(deleteOperationSchema).length(1).optional().describe("业务上必填,且只允许一个 delete operation;缺少时请补充删除目标和最新 content hash"),
35
+ agent_session_id: agentSessionId,
36
+ }).strict();
37
+ export function registerTestCaseDeleteTools(server, services, logger, runtime, writeApprovalMode) {
38
+ server.registerTool("pingcode_test_case_delete_preview", {
39
+ title: "预览删除 PingCode Test Case",
40
+ description: "预览删除一个明确的 PingCode Test Case,不会写入 PingCode。最小输入是 plan_id、operations[action=delete]、目标 Test Case 的 test_case_id(必须来自 pingcode_test_case_get 或列表)以及最新 expected_content_hash/source.contentHash;调用前必须先用 pingcode_test_case_get 取得最新 Hash。预览会显示测试库、标题、ID 和现有关联。此 Tool 不删除测试库、工作项、Wiki 页面或 Relation 目标,删除不可恢复;是否显示 MCP Client 确认由 PINGCODE_WRITE_CONFIRMATION 决定,但 Commit 仍必须通过有效 Approval、hash、幂等和审计校验。不得在正常用户回复中展示内部 hash 或审批字段。",
41
+ inputSchema: testCaseDeletePreviewInputSchema.shape,
42
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: true },
43
+ }, async (input, extra) => executeTool(logger, "pingcode_test_case_delete_preview", requestIdForLog(extra.requestInfo?.headers["x-request-id"], extra.requestId), { planId: input.plan_id ?? "" }, () => previewDeletePlan(input, services, runtime, input.agent_session_id, extra.authInfo), { formatResult: formatPreviewToolResult }));
44
+ server.registerTool("pingcode_test_case_delete_commit", {
45
+ title: "提交删除 PingCode Test Case",
46
+ description: "依已核准的 Preview 删除一个 PingCode Test Case。Commit 必须原样复用 Preview 的 plan_id、operations 和验证字段;是否要求当前 MCP Client 确认由 PINGCODE_WRITE_CONFIRMATION 决定,删除后由 MCP 回读确认 Test Case 已不存在。结果不确定时不得更换幂等键重试。",
47
+ inputSchema: {
48
+ ...testCaseDeletePlanSchema.shape,
49
+ agent_session_id: agentSessionId,
50
+ preview_id: approvalContextId.optional().describe("可选。省略时 Server 依相同 plan_id 与 operations 自动匹配刚才的 Preview,并据此恢复 request hash、evidence hash、session binding 和幂等边界;仅当客户端确实读到 Preview 的 approvalContextId 时才需要传入"),
51
+ approval_context_id: approvalContextId.optional().describe("已弃用,等同 preview_id;新调用只传 preview_id"),
52
+ approval_token: approvalTokenSchema(writeApprovalMode),
53
+ idempotency_key: identifier.min(16).max(200).optional(),
54
+ },
55
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
56
+ }, async (input, extra) => executeTool(logger, "pingcode_test_case_delete_commit", requestIdForLog(extra.requestInfo?.headers["x-request-id"], extra.requestId), { planId: input.plan_id }, async () => {
57
+ runtime.assertMcpWriteScope(extra.authInfo?.scopes);
58
+ const verification = await resolveCommitVerification(runtime, {
59
+ previewId: input.preview_id,
60
+ approvalContextId: input.approval_context_id,
61
+ idempotencyKey: input.idempotency_key,
62
+ requestHash: requestHash({ plan_id: input.plan_id, operations: input.operations }),
63
+ agentSessionId: input.agent_session_id,
64
+ authInfo: extra.authInfo,
65
+ }, "test_case");
66
+ const resolvedInput = {
67
+ ...input,
68
+ request_hash: verification.requestHash,
69
+ approval_context_id: verification.approvalContextId,
70
+ session_binding: verification.sessionBinding,
71
+ evidence_hash: verification.evidenceHash,
72
+ idempotency_key: verification.idempotencyKey,
73
+ };
74
+ const prepared = await prepareDelete(resolvedInput.operations[0], services);
75
+ assertDeletePlanIntegrity(resolvedInput, prepared);
76
+ await requestClientWriteConfirmation(server, logger, writeApprovalMode, input.approval_token, deleteConfirmationMessage(prepared), runtime.requiresConfirmation(["delete"]));
77
+ return commitDeletePlan(resolvedInput, prepared, services, runtime, writeApprovalMode, extra.authInfo);
78
+ }, { formatResult: formatWriteToolResult }));
79
+ }
80
+ async function previewDeletePlan(input, services, runtime, agentSessionIdValue, authInfo) {
81
+ if (input.plan_id === undefined) {
82
+ throw new PingCodeError("缺少 plan_id;请补充 Test Case 删除计划 ID,再重试 Preview", "BAD_REQUEST");
83
+ }
84
+ if (input.operations === undefined) {
85
+ throw new PingCodeError("缺少 operations;请先调用 pingcode_test_case_get 取得目标 Test Case 和最新 contentHash,再提供一个 delete operation", "BAD_REQUEST");
86
+ }
87
+ const operation = input.operations[0];
88
+ if (!operation) {
89
+ throw new PingCodeError("Test Case 删除计划不能为空", "BAD_REQUEST");
90
+ }
91
+ const prepared = await prepareDelete(operation, services);
92
+ const displayOperation = deleteDisplayOperation(prepared);
93
+ const plan = { plan_id: input.plan_id, operations: input.operations };
94
+ const requestHashValue = requestHash(plan);
95
+ const evidenceHash = requestHash({ planId: input.plan_id, requestHash: requestHashValue, operations: [displayOperation] });
96
+ const context = await runtime.createApprovalContext({
97
+ resourceType: "test_case",
98
+ requestHash: requestHashValue,
99
+ evidenceHash,
100
+ ...(agentSessionIdValue === undefined ? {} : { agentSessionId: agentSessionIdValue }),
101
+ ...(authInfo === undefined ? {} : { authInfo }),
102
+ });
103
+ return {
104
+ planId: input.plan_id,
105
+ requestHash: requestHashValue,
106
+ approvalContextId: context.approvalContextId,
107
+ sessionBinding: context.sessionBinding,
108
+ evidenceHash,
109
+ approvalExpiresAt: context.expiresAt,
110
+ counts: { creates: 0, updates: 0, relations: 0 },
111
+ warnings: [
112
+ "删除 Test Case 不可恢复",
113
+ "此 Tool 只删除 Test Case 本身,不主动删除测试库、工作项、Wiki 页面或 Relation 目标",
114
+ ],
115
+ operations: [displayOperation],
116
+ };
117
+ }
118
+ async function commitDeletePlan(input, prepared, services, runtime, writeApprovalMode, authInfo) {
119
+ assertDeletePlanIntegrity(input, prepared);
120
+ const committed = await commitWithApproval(runtime, writeApprovalMode, {
121
+ resourceType: "test_case",
122
+ requestHash: input.request_hash,
123
+ evidenceHash: input.evidence_hash,
124
+ approvalContextId: input.approval_context_id,
125
+ sessionBinding: input.session_binding,
126
+ ...(input.agent_session_id === undefined ? {} : { agentSessionId: input.agent_session_id }),
127
+ approvalToken: input.approval_token,
128
+ idempotencyKey: input.idempotency_key,
129
+ ...(authInfo === undefined ? {} : { authInfo }),
130
+ actions: ["delete"],
131
+ action: async () => {
132
+ await services.getWriteSource().deleteTestCase(prepared.context.source.id);
133
+ await verifyDeleted(prepared.context, services);
134
+ return {
135
+ planId: input.plan_id,
136
+ resources: [{
137
+ operationId: prepared.operation.operation_id,
138
+ action: "delete",
139
+ id: prepared.context.source.id,
140
+ identifier: prepared.context.source.identifier,
141
+ title: prepared.context.title,
142
+ verified: true,
143
+ }],
144
+ };
145
+ },
146
+ });
147
+ return {
148
+ ...committed.result,
149
+ replayed: committed.replayed,
150
+ approvedBy: committed.approval.approvedBy,
151
+ auditId: committed.auditId,
152
+ };
153
+ }
154
+ function assertDeletePlanIntegrity(input, prepared) {
155
+ const plan = { plan_id: input.plan_id, operations: input.operations };
156
+ if (requestHash(plan) !== input.request_hash) {
157
+ throw new PingCodeError("Commit 内容与 Test Case 删除 Preview request hash 不一致", "CONFLICT");
158
+ }
159
+ const evidenceHash = requestHash({
160
+ planId: input.plan_id,
161
+ requestHash: input.request_hash,
162
+ operations: [deleteDisplayOperation(prepared)],
163
+ });
164
+ if (evidenceHash !== input.evidence_hash) {
165
+ throw new PingCodeError("Commit 内容与 Test Case 删除 Preview evidence hash 不一致", "CONFLICT");
166
+ }
167
+ }
168
+ async function prepareDelete(operation, services) {
169
+ const context = await services.getTestCaseSource().getTestCaseContext(operation.fields.test_case_id);
170
+ if (context.source.contentHash !== normalizeContentHash(operation.fields.expected_content_hash)) {
171
+ throw new PingCodeError(`Test Case ${context.title} 的内容已变化;请先重新调用 pingcode_test_case_get,再重新 Preview。未执行删除`, "CONFLICT");
172
+ }
173
+ return { operation, context };
174
+ }
175
+ async function verifyDeleted(context, services) {
176
+ try {
177
+ await services.getTestCaseSource().getTestCaseContext(context.source.id);
178
+ }
179
+ catch (error) {
180
+ if (error instanceof PingCodeError && error.code === "NOT_FOUND") {
181
+ return;
182
+ }
183
+ // PingCode 某些租户在资源删除后,详情接口返回 BAD_REQUEST 而不是 NOT_FOUND。
184
+ // 只读列表可以确认资源是否仍存在;绝不在此处重发 DELETE。
185
+ if (error instanceof PingCodeError && error.code === "BAD_REQUEST") {
186
+ try {
187
+ const absent = await isAbsentFromTestCaseList(context, services);
188
+ if (absent)
189
+ return;
190
+ throw new PingCodeError(`Test Case ${context.title} 的删除请求已发送,但列表回读时仍存在;禁止更换幂等键重试`, "WRITE_OUTCOME_UNKNOWN");
191
+ }
192
+ catch (listError) {
193
+ if (listError instanceof PingCodeError && listError.code === "WRITE_OUTCOME_UNKNOWN") {
194
+ throw listError;
195
+ }
196
+ throw new PingCodeError(`Test Case ${context.title} 的删除请求已发送,但 MCP 无法通过列表确认结果;禁止更换幂等键重试`, "WRITE_OUTCOME_UNKNOWN", { cause: listError });
197
+ }
198
+ }
199
+ throw new PingCodeError(`Test Case ${context.title} 的删除请求已发送,但 MCP 无法确认结果;禁止更换幂等键重试`, "WRITE_OUTCOME_UNKNOWN", { cause: error });
200
+ }
201
+ throw new PingCodeError(`Test Case ${context.title} 的删除请求已发送,但回读时仍存在;禁止更换幂等键重试`, "WRITE_OUTCOME_UNKNOWN");
202
+ }
203
+ async function isAbsentFromTestCaseList(context, services) {
204
+ let pageIndex = 0;
205
+ for (let pageCount = 0; pageCount < 100; pageCount += 1) {
206
+ const page = await services.getTestCaseSource().listTestCases({
207
+ libraryId: context.source.libraryId,
208
+ pageIndex,
209
+ pageSize: 100,
210
+ });
211
+ if (page.values.some((testCase) => testCase.id === context.source.id)) {
212
+ return false;
213
+ }
214
+ if (page.values.length === 0 || (page.pageIndex + 1) * page.pageSize >= page.total) {
215
+ return true;
216
+ }
217
+ pageIndex = page.pageIndex + 1;
218
+ }
219
+ throw new PingCodeError("Test Case 列表超过安全回读上限,无法确认删除结果", "RESPONSE_TOO_LARGE");
220
+ }
221
+ function deleteDisplayOperation(prepared) {
222
+ const context = prepared.context;
223
+ return {
224
+ operationId: prepared.operation.operation_id,
225
+ action: "delete",
226
+ targetId: context.source.id,
227
+ changes: {
228
+ test_case: { before: `${context.title} (${context.source.identifier})`, after: null },
229
+ test_library: {
230
+ before: `${context.source.libraryName} (${context.source.libraryIdentifier})`,
231
+ after: `${context.source.libraryName} (${context.source.libraryIdentifier})(保留)`,
232
+ },
233
+ relations: { before: context.relationIds, after: "不主动删除" },
234
+ },
235
+ sourceReferences: prepared.operation.source_references,
236
+ };
237
+ }
238
+ function deleteConfirmationMessage(prepared) {
239
+ const context = prepared.context;
240
+ return formatWriteConfirmationMessage("即将在 PingCode 测试管理中删除 Test Case", [
241
+ `测试用例:${context.title} (${context.source.identifier})`,
242
+ `所属测试库:${context.source.libraryName} (${context.source.libraryIdentifier})`,
243
+ `现有关联:${context.relationIds.length} 个`,
244
+ "删除不可恢复;不会主动删除测试库、工作项、Wiki 页面或 Relation 目标",
245
+ ], "确认后将立即删除该 Test Case,请核对以上资源和 Preview 差异。");
246
+ }
247
+ //# sourceMappingURL=test-case-delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-delete.js","sourceRoot":"","sources":["../../../src/mcp/tools/test-case-delete.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Logger } from "../../logger.js";
3
+ import type { Services } from "../../services.js";
4
+ export declare function registerTestCaseTools(server: McpServer, services: Services, logger: Logger): void;
5
+ //# sourceMappingURL=test-case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/test-case.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAkBlD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GACb,IAAI,CAqHN"}