@cloudglab/zentao-cli 0.1.3

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 (187) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/MCP_ZENTAO_REBUILD_PLAN.md +505 -0
  3. package/README.md +319 -0
  4. package/dist/api/bug.d.ts +32 -0
  5. package/dist/api/bug.js +85 -0
  6. package/dist/api/bug.js.map +1 -0
  7. package/dist/api/build.d.ts +31 -0
  8. package/dist/api/build.js +21 -0
  9. package/dist/api/build.js.map +1 -0
  10. package/dist/api/comment.d.ts +20 -0
  11. package/dist/api/comment.js +47 -0
  12. package/dist/api/comment.js.map +1 -0
  13. package/dist/api/development-context.d.ts +14 -0
  14. package/dist/api/development-context.js +35 -0
  15. package/dist/api/development-context.js.map +1 -0
  16. package/dist/api/execution.d.ts +46 -0
  17. package/dist/api/execution.js +47 -0
  18. package/dist/api/execution.js.map +1 -0
  19. package/dist/api/index.d.ts +43 -0
  20. package/dist/api/index.js +46 -0
  21. package/dist/api/index.js.map +1 -0
  22. package/dist/api/plan.d.ts +18 -0
  23. package/dist/api/plan.js +33 -0
  24. package/dist/api/plan.js.map +1 -0
  25. package/dist/api/product.d.ts +7 -0
  26. package/dist/api/product.js +14 -0
  27. package/dist/api/product.js.map +1 -0
  28. package/dist/api/program.d.ts +7 -0
  29. package/dist/api/program.js +14 -0
  30. package/dist/api/program.js.map +1 -0
  31. package/dist/api/project.d.ts +8 -0
  32. package/dist/api/project.js +15 -0
  33. package/dist/api/project.js.map +1 -0
  34. package/dist/api/relation.d.ts +17 -0
  35. package/dist/api/relation.js +66 -0
  36. package/dist/api/relation.js.map +1 -0
  37. package/dist/api/release.d.ts +6 -0
  38. package/dist/api/release.js +11 -0
  39. package/dist/api/release.js.map +1 -0
  40. package/dist/api/search.d.ts +17 -0
  41. package/dist/api/search.js +168 -0
  42. package/dist/api/search.js.map +1 -0
  43. package/dist/api/statistics.d.ts +13 -0
  44. package/dist/api/statistics.js +67 -0
  45. package/dist/api/statistics.js.map +1 -0
  46. package/dist/api/story.d.ts +14 -0
  47. package/dist/api/story.js +23 -0
  48. package/dist/api/story.js.map +1 -0
  49. package/dist/api/task.d.ts +17 -0
  50. package/dist/api/task.js +37 -0
  51. package/dist/api/task.js.map +1 -0
  52. package/dist/api/testcase.d.ts +51 -0
  53. package/dist/api/testcase.js +31 -0
  54. package/dist/api/testcase.js.map +1 -0
  55. package/dist/api/testtask.d.ts +41 -0
  56. package/dist/api/testtask.js +34 -0
  57. package/dist/api/testtask.js.map +1 -0
  58. package/dist/api/user.d.ts +6 -0
  59. package/dist/api/user.js +9 -0
  60. package/dist/api/user.js.map +1 -0
  61. package/dist/bin/zentao-dev.d.ts +2 -0
  62. package/dist/bin/zentao-dev.js +8 -0
  63. package/dist/bin/zentao-dev.js.map +1 -0
  64. package/dist/bin/zentao-pm.d.ts +2 -0
  65. package/dist/bin/zentao-pm.js +8 -0
  66. package/dist/bin/zentao-pm.js.map +1 -0
  67. package/dist/bin/zentao-qa.d.ts +2 -0
  68. package/dist/bin/zentao-qa.js +8 -0
  69. package/dist/bin/zentao-qa.js.map +1 -0
  70. package/dist/bin/zentao.d.ts +2 -0
  71. package/dist/bin/zentao.js +8 -0
  72. package/dist/bin/zentao.js.map +1 -0
  73. package/dist/cli.d.ts +1 -0
  74. package/dist/cli.js +74 -0
  75. package/dist/cli.js.map +1 -0
  76. package/dist/core/api-provider.d.ts +3 -0
  77. package/dist/core/api-provider.js +17 -0
  78. package/dist/core/api-provider.js.map +1 -0
  79. package/dist/core/auth.d.ts +13 -0
  80. package/dist/core/auth.js +90 -0
  81. package/dist/core/auth.js.map +1 -0
  82. package/dist/core/cli-registry.d.ts +18 -0
  83. package/dist/core/cli-registry.js +128 -0
  84. package/dist/core/cli-registry.js.map +1 -0
  85. package/dist/core/config.d.ts +7 -0
  86. package/dist/core/config.js +58 -0
  87. package/dist/core/config.js.map +1 -0
  88. package/dist/core/http.d.ts +12 -0
  89. package/dist/core/http.js +50 -0
  90. package/dist/core/http.js.map +1 -0
  91. package/dist/core/list-result.d.ts +14 -0
  92. package/dist/core/list-result.js +59 -0
  93. package/dist/core/list-result.js.map +1 -0
  94. package/dist/core/pagination.d.ts +9 -0
  95. package/dist/core/pagination.js +12 -0
  96. package/dist/core/pagination.js.map +1 -0
  97. package/dist/core/roles.d.ts +4 -0
  98. package/dist/core/roles.js +13 -0
  99. package/dist/core/roles.js.map +1 -0
  100. package/dist/core/tool-registry.d.ts +3 -0
  101. package/dist/core/tool-registry.js +77 -0
  102. package/dist/core/tool-registry.js.map +1 -0
  103. package/dist/core/write-guard.d.ts +25 -0
  104. package/dist/core/write-guard.js +53 -0
  105. package/dist/core/write-guard.js.map +1 -0
  106. package/dist/index.d.ts +3 -0
  107. package/dist/index.js +3 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/tools/bug.d.ts +2 -0
  110. package/dist/tools/bug.js +41 -0
  111. package/dist/tools/bug.js.map +1 -0
  112. package/dist/tools/build.d.ts +2 -0
  113. package/dist/tools/build.js +8 -0
  114. package/dist/tools/build.js.map +1 -0
  115. package/dist/tools/comment.d.ts +2 -0
  116. package/dist/tools/comment.js +23 -0
  117. package/dist/tools/comment.js.map +1 -0
  118. package/dist/tools/context.d.ts +2 -0
  119. package/dist/tools/context.js +11 -0
  120. package/dist/tools/context.js.map +1 -0
  121. package/dist/tools/execution.d.ts +2 -0
  122. package/dist/tools/execution.js +21 -0
  123. package/dist/tools/execution.js.map +1 -0
  124. package/dist/tools/init.d.ts +2 -0
  125. package/dist/tools/init.js +28 -0
  126. package/dist/tools/init.js.map +1 -0
  127. package/dist/tools/phase3a.d.ts +4 -0
  128. package/dist/tools/phase3a.js +123 -0
  129. package/dist/tools/phase3a.js.map +1 -0
  130. package/dist/tools/phase3b.d.ts +5 -0
  131. package/dist/tools/phase3b.js +161 -0
  132. package/dist/tools/phase3b.js.map +1 -0
  133. package/dist/tools/plan.d.ts +2 -0
  134. package/dist/tools/plan.js +14 -0
  135. package/dist/tools/plan.js.map +1 -0
  136. package/dist/tools/product.d.ts +2 -0
  137. package/dist/tools/product.js +10 -0
  138. package/dist/tools/product.js.map +1 -0
  139. package/dist/tools/profile.d.ts +2 -0
  140. package/dist/tools/profile.js +6 -0
  141. package/dist/tools/profile.js.map +1 -0
  142. package/dist/tools/program.d.ts +2 -0
  143. package/dist/tools/program.js +8 -0
  144. package/dist/tools/program.js.map +1 -0
  145. package/dist/tools/project.d.ts +2 -0
  146. package/dist/tools/project.js +13 -0
  147. package/dist/tools/project.js.map +1 -0
  148. package/dist/tools/relation.d.ts +2 -0
  149. package/dist/tools/relation.js +13 -0
  150. package/dist/tools/relation.js.map +1 -0
  151. package/dist/tools/release.d.ts +2 -0
  152. package/dist/tools/release.js +7 -0
  153. package/dist/tools/release.js.map +1 -0
  154. package/dist/tools/search.d.ts +2 -0
  155. package/dist/tools/search.js +18 -0
  156. package/dist/tools/search.js.map +1 -0
  157. package/dist/tools/shared.d.ts +2 -0
  158. package/dist/tools/shared.js +11 -0
  159. package/dist/tools/shared.js.map +1 -0
  160. package/dist/tools/statistics.d.ts +2 -0
  161. package/dist/tools/statistics.js +10 -0
  162. package/dist/tools/statistics.js.map +1 -0
  163. package/dist/tools/story.d.ts +2 -0
  164. package/dist/tools/story.js +14 -0
  165. package/dist/tools/story.js.map +1 -0
  166. package/dist/tools/task.d.ts +2 -0
  167. package/dist/tools/task.js +48 -0
  168. package/dist/tools/task.js.map +1 -0
  169. package/dist/tools/testcase.d.ts +2 -0
  170. package/dist/tools/testcase.js +16 -0
  171. package/dist/tools/testcase.js.map +1 -0
  172. package/dist/tools/testtask.d.ts +2 -0
  173. package/dist/tools/testtask.js +14 -0
  174. package/dist/tools/testtask.js.map +1 -0
  175. package/dist/types/common.d.ts +15 -0
  176. package/dist/types/common.js +2 -0
  177. package/dist/types/common.js.map +1 -0
  178. package/dist/types/zentao.d.ts +42 -0
  179. package/dist/types/zentao.js +2 -0
  180. package/dist/types/zentao.js.map +1 -0
  181. package/dist/utils/json.d.ts +2 -0
  182. package/dist/utils/json.js +27 -0
  183. package/dist/utils/json.js.map +1 -0
  184. package/dist/version.d.ts +1 -0
  185. package/dist/version.js +2 -0
  186. package/dist/version.js.map +1 -0
  187. package/package.json +48 -0
@@ -0,0 +1,25 @@
1
+ export interface WriteGuardInput {
2
+ action: string;
3
+ confirm?: boolean;
4
+ payload: unknown;
5
+ }
6
+ export interface WritePreview {
7
+ ok: false;
8
+ preview: true;
9
+ reason: string;
10
+ action: string;
11
+ payload: unknown;
12
+ }
13
+ export interface UnsupportedWriteDiagnostic {
14
+ ok: false;
15
+ supported: false;
16
+ error: string;
17
+ action: string;
18
+ diagnostic: string;
19
+ payload: unknown;
20
+ }
21
+ export declare function isWriteEnabled(): boolean;
22
+ export declare function getWritePreview(input: WriteGuardInput, reason: string): WritePreview;
23
+ export declare function getUnsupportedWriteDiagnostic(input: WriteGuardInput, diagnostic: string): UnsupportedWriteDiagnostic;
24
+ export declare function assertWriteAllowed(input: WriteGuardInput): void;
25
+ export declare function previewOrAssertWriteAllowed(input: WriteGuardInput): WritePreview | UnsupportedWriteDiagnostic | null;
@@ -0,0 +1,53 @@
1
+ const UNSUPPORTED_WRITE_ACTIONS = {
2
+ updateExecution: '禅道 18.5 v1 executionEntry::put() 在启用迭代代号时存在字段拼接缺逗号问题,code 不会进入服务端 $_POST,客户端无法稳定绕过。',
3
+ updateTestTask: '禅道 18.5 v1 testtaskEntry 只有 get/delete,没有 put 更新入口。',
4
+ addComment: '禅道 18.5 v1 没有 comment/comments API entry;只能通过对象详情 actions 读取评论,不能用 REST v1 新增评论。',
5
+ };
6
+ export function isWriteEnabled() {
7
+ return process.env.ZENTAO_ENABLE_WRITE === 'true';
8
+ }
9
+ export function getWritePreview(input, reason) {
10
+ return {
11
+ ok: false,
12
+ preview: true,
13
+ reason,
14
+ action: input.action,
15
+ payload: input.payload,
16
+ };
17
+ }
18
+ export function getUnsupportedWriteDiagnostic(input, diagnostic) {
19
+ return {
20
+ ok: false,
21
+ supported: false,
22
+ error: `写操作 ${input.action} 当前不能真实执行`,
23
+ action: input.action,
24
+ diagnostic,
25
+ payload: input.payload,
26
+ };
27
+ }
28
+ export function assertWriteAllowed(input) {
29
+ const unsupportedReason = UNSUPPORTED_WRITE_ACTIONS[input.action];
30
+ if (unsupportedReason) {
31
+ throw new Error(`写操作 ${input.action} 当前不支持真实执行:${unsupportedReason}`);
32
+ }
33
+ if (!isWriteEnabled()) {
34
+ throw new Error(`写操作已禁用。若要执行 ${input.action},需要设置 ZENTAO_ENABLE_WRITE=true。`);
35
+ }
36
+ if (input.confirm !== true) {
37
+ throw new Error(`写操作缺少确认。若要执行 ${input.action},需要传入 confirm: true。`);
38
+ }
39
+ }
40
+ export function previewOrAssertWriteAllowed(input) {
41
+ const unsupportedReason = UNSUPPORTED_WRITE_ACTIONS[input.action];
42
+ if (unsupportedReason) {
43
+ return getUnsupportedWriteDiagnostic(input, unsupportedReason);
44
+ }
45
+ if (!isWriteEnabled()) {
46
+ return getWritePreview(input, `写操作已禁用。若要执行 ${input.action},需要设置 ZENTAO_ENABLE_WRITE=true。`);
47
+ }
48
+ if (input.confirm !== true) {
49
+ return getWritePreview(input, `写操作缺少确认。若要执行 ${input.action},需要传入 confirm: true。`);
50
+ }
51
+ return null;
52
+ }
53
+ //# sourceMappingURL=write-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-guard.js","sourceRoot":"","sources":["../../src/core/write-guard.ts"],"names":[],"mappings":"AAuBA,MAAM,yBAAyB,GAA2B;IACxD,eAAe,EAAE,qFAAqF;IACtG,cAAc,EAAE,qDAAqD;IACrE,UAAU,EAAE,kFAAkF;CAC/F,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAsB,EAAE,MAAc;IACpE,OAAO;QACL,EAAE,EAAE,KAAK;QACT,OAAO,EAAE,IAAI;QACb,MAAM;QACN,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAsB,EAAE,UAAkB;IACtF,OAAO;QACL,EAAE,EAAE,KAAK;QACT,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,WAAW;QACrC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,UAAU;QACV,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,MAAM,cAAc,iBAAiB,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,CAAC,MAAM,iCAAiC,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,gBAAgB,KAAK,CAAC,MAAM,sBAAsB,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAsB;IAChE,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,6BAA6B,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,OAAO,eAAe,CAAC,KAAK,EAAE,eAAe,KAAK,CAAC,MAAM,iCAAiC,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,eAAe,CAAC,KAAK,EAAE,gBAAgB,KAAK,CAAC,MAAM,sBAAsB,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ZentaoApi } from './api/index.js';
2
+ export { runCli } from './cli.js';
3
+ export type { Role, ZentaoConfig } from './types/common.js';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ZentaoApi } from './api/index.js';
2
+ export { runCli } from './cli.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerBugTools(server: CliRegistry): void;
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { previewOrAssertWriteAllowed } from '../core/write-guard.js';
4
+ import { jsonResult } from './shared.js';
5
+ export function registerBugTools(server) {
6
+ server.tool('getMyBugs', {
7
+ productId: z.number().int().positive().optional().describe('可选。禅道产品 ID。不传时默认查询跨所有产品“指派给我的 Bug”;传入时只查该产品内我的 Bug。若用户问的是业务产品的线上 / 生产 / 客户反馈 / 售后反馈问题,不要直接把业务产品名当成这里的 productId。'),
8
+ page: z.number().int().positive().optional(),
9
+ limit: z.number().int().positive().max(100).optional(),
10
+ branch: z.string().optional(),
11
+ order: z.string().optional(),
12
+ }, async (input) => jsonResult(await getApi().bug.getMyBugs(input)));
13
+ server.tool('getProductBugs', {
14
+ productId: z.number().int().positive().describe('禅道产品 ID。仅用于查询某个禅道产品下的 Bug。若用户问的是某业务产品的线上 Bug / 生产问题 / 客户反馈问题,先查固定禅道产品“市场和售后问题跟踪”,再按模块匹配真实业务产品,不要直接把业务产品名映射成这里的 productId。'),
15
+ page: z.number().int().positive().optional(),
16
+ limit: z.number().int().positive().max(100).optional(),
17
+ status: z.string().optional().default('all'),
18
+ branch: z.string().optional(),
19
+ order: z.string().optional(),
20
+ }, async (input) => jsonResult(await getApi().bug.getProductBugs(input)));
21
+ server.tool('getBugDetail', {
22
+ bugId: z.number().int().positive(),
23
+ }, async ({ bugId }) => jsonResult(await getApi().bug.getBugDetail(bugId)));
24
+ server.tool('resolveBug', {
25
+ bugId: z.number().int().positive(),
26
+ resolution: z.enum(['fixed', 'bydesign', 'duplicate', 'external', 'notrepro', 'postponed', 'willnotfix']),
27
+ resolvedBuild: z.string().optional(),
28
+ resolvedDate: z.string().optional().describe('解决日期/时间,禅道 18.5 bugresolve 支持该字段'),
29
+ assignedTo: z.string().optional(),
30
+ comment: z.string().optional(),
31
+ duplicateBug: z.number().int().positive().optional(),
32
+ confirm: z.boolean().optional().default(false),
33
+ }, async ({ bugId, confirm, ...resolution }) => {
34
+ const payload = { bugId, resolution };
35
+ const preview = previewOrAssertWriteAllowed({ action: 'resolveBug', confirm, payload });
36
+ if (preview)
37
+ return jsonResult(preview);
38
+ return jsonResult(await getApi().bug.resolveBug(bugId, resolution));
39
+ });
40
+ }
41
+ //# sourceMappingURL=bug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug.js","sourceRoot":"","sources":["../../src/tools/bug.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerBuildTools(server: CliRegistry): void;
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { jsonResult } from './shared.js';
4
+ export function registerBuildTools(server) {
5
+ server.tool('getProjectBuilds', { projectId: z.number().int().positive() }, async ({ projectId }) => jsonResult(await getApi().build.getProjectBuilds(projectId)));
6
+ server.tool('getBuildDetail', { buildId: z.number().int().positive() }, async ({ buildId }) => jsonResult(await getApi().build.getBuildDetail(buildId)));
7
+ }
8
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/tools/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACnK,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3J,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerCommentTools(server: CliRegistry): void;
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { previewOrAssertWriteAllowed } from '../core/write-guard.js';
4
+ import { jsonResult } from './shared.js';
5
+ const objectTypeSchema = z.enum(['task', 'bug', 'story', 'product', 'project', 'execution']);
6
+ export function registerCommentTools(server) {
7
+ server.tool('getComments', {
8
+ objectType: objectTypeSchema,
9
+ objectID: z.number().int().positive(),
10
+ }, async ({ objectType, objectID }) => jsonResult(await getApi().comment.getComments(objectType, objectID)));
11
+ server.tool('addComment', {
12
+ objectType: objectTypeSchema,
13
+ objectID: z.number().int().positive(),
14
+ comment: z.string().min(1),
15
+ confirm: z.boolean().optional().default(false),
16
+ }, async ({ confirm, ...input }) => {
17
+ const preview = previewOrAssertWriteAllowed({ action: 'addComment', confirm, payload: input });
18
+ if (preview)
19
+ return jsonResult(preview);
20
+ return jsonResult(await getApi().comment.addComment(input));
21
+ });
22
+ }
23
+ //# sourceMappingURL=comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment.js","sourceRoot":"","sources":["../../src/tools/comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AAE7F,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,MAAM,CAAC,IAAI,CACT,aAAa,EACb;QACE,UAAU,EAAE,gBAAgB;QAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACtC,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CACzG,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ;QACE,UAAU,EAAE,gBAAgB;QAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,2BAA2B,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/F,IAAI,OAAO;YAAE,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerContextTools(server: CliRegistry): void;
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { jsonResult } from './shared.js';
4
+ export function registerContextTools(server) {
5
+ server.tool('getDevelopmentContext', {
6
+ entityType: z.enum(['story', 'bug']),
7
+ entityId: z.number().int().positive(),
8
+ productId: z.number().int().positive().optional().describe('可选。story 上下文查询关联 Bug 时可用于兜底过滤。'),
9
+ }, async (input) => jsonResult(await getApi().developmentContext.getDevelopmentContext(input)));
10
+ }
11
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB;QACE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KAC7F,EACD,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAC5F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerExecutionTools(server: CliRegistry): void;
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { jsonResult } from './shared.js';
4
+ export function registerExecutionTools(server) {
5
+ server.tool('getExecutionDetail', {
6
+ executionId: z.number().int().positive(),
7
+ }, async ({ executionId }) => jsonResult(await getApi().execution.getExecutionDetail(executionId)));
8
+ server.tool('getProjectExecutions', {
9
+ projectId: z.number().int().positive(),
10
+ }, async ({ projectId }) => jsonResult(await getApi().execution.getProjectExecutions(projectId)));
11
+ server.tool('getExecutionBuilds', {
12
+ executionId: z.number().int().positive(),
13
+ }, async ({ executionId }) => jsonResult(await getApi().execution.getExecutionBuilds(executionId)));
14
+ server.tool('getExecutionBugs', {
15
+ executionId: z.number().int().positive(),
16
+ page: z.number().int().positive().optional(),
17
+ limit: z.number().int().positive().max(100).optional(),
18
+ status: z.string().optional().describe('可选,按禅道接口支持的状态过滤'),
19
+ }, async ({ executionId, page, limit, status }) => jsonResult(await getApi().execution.getExecutionBugs(executionId, { page, limit, status })));
20
+ }
21
+ //# sourceMappingURL=execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/tools/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,sBAAsB,CAAC,MAAmB;IACxD,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACzC,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAChG,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACvC,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAC9F,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACzC,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAChG,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;QACtD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KAC1D,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAC5I,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerInitTools(server: CliRegistry): void;
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ import { ZentaoApi } from '../api/index.js';
3
+ import { loadConfig, maskConfig, normalizeConfig, saveConfig } from '../core/config.js';
4
+ import { setApi } from '../core/api-provider.js';
5
+ import { jsonResult } from './shared.js';
6
+ export function registerInitTools(server) {
7
+ server.tool('initZentao', {
8
+ url: z.string().optional().describe('禅道根域名,例如 https://zentao.cloudglab.cn,不要带 /zentao'),
9
+ username: z.string().optional().describe('禅道账号'),
10
+ password: z.string().optional().describe('禅道密码'),
11
+ apiVersion: z.string().optional().default('v1').describe('API 版本,默认 v1'),
12
+ apiBaseUrl: z.string().optional().describe('可选。完整 API 基础地址,例如 https://host/custom/api.php/v1;不传则默认拼接 /zentao/api.php/{apiVersion}'),
13
+ save: z.boolean().optional().default(false).describe('是否写入 ~/.zentao/config.json。默认 false,仅当前会话生效'),
14
+ }, async (input) => {
15
+ const config = input.url || input.username || input.password || input.apiBaseUrl
16
+ ? normalizeConfig(input)
17
+ : loadConfig();
18
+ if (!config)
19
+ throw new Error('未找到禅道配置。');
20
+ if (input.save)
21
+ saveConfig(config);
22
+ const api = new ZentaoApi(config);
23
+ await api.getToken();
24
+ setApi(api);
25
+ return jsonResult({ ok: true, saved: Boolean(input.save), config: maskConfig(config) });
26
+ });
27
+ }
28
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/tools/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,MAAM,CAAC,IAAI,CACT,YAAY,EACZ;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;QACvF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;QAChD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;QAChD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QACxE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;QACnI,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;KACpG,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,UAAU;YAC9E,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC;YACxB,CAAC,CAAC,UAAU,EAAE,CAAC;QAEjB,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QAEzC,IAAI,KAAK,CAAC,IAAI;YAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAEnC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC;QAEZ,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerStoryWriteTools(server: CliRegistry): void;
3
+ export declare function registerTaskDerivedTools(server: CliRegistry): void;
4
+ export declare function registerPlanRelationTools(server: CliRegistry): void;
@@ -0,0 +1,123 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { previewOrAssertWriteAllowed } from '../core/write-guard.js';
4
+ import { jsonResult } from './shared.js';
5
+ async function runPreviewed(action, confirm, payload, runner) {
6
+ const preview = previewOrAssertWriteAllowed({ action, confirm, payload });
7
+ if (preview)
8
+ return jsonResult(preview);
9
+ return jsonResult(await runner());
10
+ }
11
+ export function registerStoryWriteTools(server) {
12
+ server.tool('updateStory', {
13
+ storyId: z.number().int().positive(),
14
+ title: z.string().optional(),
15
+ product: z.number().int().positive().optional(),
16
+ parent: z.number().int().nonnegative().optional(),
17
+ reviewer: z.string().optional(),
18
+ type: z.string().optional(),
19
+ plan: z.number().int().nonnegative().optional(),
20
+ module: z.number().int().nonnegative().optional(),
21
+ source: z.string().optional(),
22
+ sourceNote: z.string().optional(),
23
+ pri: z.number().optional(),
24
+ estimate: z.number().optional(),
25
+ category: z.string().optional(),
26
+ mailto: z.array(z.string()).optional(),
27
+ keywords: z.string().optional(),
28
+ stage: z.string().optional(),
29
+ notifyEmail: z.array(z.string()).optional(),
30
+ confirm: z.boolean().optional().default(false),
31
+ }, async ({ storyId, confirm, ...update }) => runPreviewed('updateStory', confirm, { storyId, update }, () => getApi().story.updateStory(storyId, update)));
32
+ server.tool('changeStory', {
33
+ storyId: z.number().int().positive(),
34
+ title: z.string().min(1).describe('禅道 18.5 change story 必填'),
35
+ spec: z.string().optional(),
36
+ verify: z.string().optional(),
37
+ reviewer: z.string().optional(),
38
+ comment: z.string().optional(),
39
+ executions: z.array(z.number().int().positive()).optional(),
40
+ bugs: z.array(z.number().int().positive()).optional(),
41
+ cases: z.array(z.number().int().positive()).optional(),
42
+ tasks: z.array(z.number().int().positive()).optional(),
43
+ reviewedBy: z.string().optional(),
44
+ confirm: z.boolean().optional().default(false),
45
+ }, async ({ storyId, confirm, ...update }) => runPreviewed('changeStory', confirm, { storyId, update }, () => getApi().story.changeStory(storyId, update)));
46
+ }
47
+ export function registerTaskDerivedTools(server) {
48
+ server.tool('createTaskFromStory', {
49
+ storyId: z.number().int().positive(),
50
+ execution: z.number().int().positive(),
51
+ taskName: z.string().min(1),
52
+ type: z.string().optional().default('devel'),
53
+ assignedTo: z.string().min(1).describe('指派人账号。禅道 18.5 创建任务必填'),
54
+ estimate: z.number().optional(),
55
+ estStarted: z.string().min(1).describe('预计开始日期。禅道 18.5 创建任务必填,格式 YYYY-MM-DD'),
56
+ deadline: z.string().min(1).describe('截止日期。禅道 18.5 创建任务必填,格式 YYYY-MM-DD'),
57
+ desc: z.string().optional(),
58
+ confirm: z.boolean().optional().default(false),
59
+ }, async ({ storyId, execution, taskName, type, assignedTo, estimate, estStarted, deadline, desc, confirm }) => {
60
+ const story = await getApi().story.getStoryDetail(storyId);
61
+ const payload = {
62
+ execution,
63
+ name: taskName,
64
+ type,
65
+ assignedTo,
66
+ estimate,
67
+ estStarted,
68
+ deadline,
69
+ story: storyId,
70
+ desc: desc ?? `基于需求 #${storyId}: ${story.title}`,
71
+ };
72
+ return runPreviewed('createTaskFromStory', confirm, payload, () => getApi().task.createTask(payload));
73
+ });
74
+ server.tool('createTaskFromBug', {
75
+ bugId: z.number().int().positive(),
76
+ execution: z.number().int().positive(),
77
+ taskName: z.string().optional(),
78
+ type: z.string().optional().default('devel'),
79
+ assignedTo: z.string().min(1).describe('指派人账号。禅道 18.5 创建任务必填'),
80
+ estimate: z.number().optional(),
81
+ estStarted: z.string().min(1).describe('预计开始日期。禅道 18.5 创建任务必填,格式 YYYY-MM-DD'),
82
+ deadline: z.string().min(1).describe('截止日期。禅道 18.5 创建任务必填,格式 YYYY-MM-DD'),
83
+ desc: z.string().optional(),
84
+ confirm: z.boolean().optional().default(false),
85
+ }, async ({ bugId, execution, taskName, type, assignedTo, estimate, estStarted, deadline, desc, confirm }) => {
86
+ const bug = await getApi().bug.getBugDetail(bugId);
87
+ const payload = {
88
+ execution,
89
+ name: taskName ?? `修复Bug #${bugId}: ${bug.title}`,
90
+ type,
91
+ assignedTo,
92
+ estimate,
93
+ estStarted,
94
+ deadline,
95
+ fromBug: bugId,
96
+ desc: desc ?? `修复Bug #${bugId}: ${bug.title}\n\n复现步骤:\n${String(bug.steps ?? '无')}`,
97
+ };
98
+ return runPreviewed('createTaskFromBug', confirm, payload, () => getApi().task.createTask(payload));
99
+ });
100
+ }
101
+ export function registerPlanRelationTools(server) {
102
+ server.tool('linkStoriesToPlan', {
103
+ planId: z.number().int().positive(),
104
+ storyIds: z.array(z.number().int().positive()).min(1).max(20),
105
+ confirm: z.boolean().optional().default(false),
106
+ }, async ({ planId, storyIds, confirm }) => runPreviewed('linkStoriesToPlan', confirm, { planId, storyIds }, () => getApi().plan.linkStoriesToPlan(planId, storyIds)));
107
+ server.tool('unlinkStoriesFromPlan', {
108
+ planId: z.number().int().positive(),
109
+ storyIds: z.array(z.number().int().positive()).min(1).max(20),
110
+ confirm: z.boolean().optional().default(false),
111
+ }, async ({ planId, storyIds, confirm }) => runPreviewed('unlinkStoriesFromPlan', confirm, { planId, storyIds }, () => getApi().plan.unlinkStoriesFromPlan(planId, storyIds)));
112
+ server.tool('linkBugsToPlan', {
113
+ planId: z.number().int().positive(),
114
+ bugIds: z.array(z.number().int().positive()).min(1).max(20),
115
+ confirm: z.boolean().optional().default(false),
116
+ }, async ({ planId, bugIds, confirm }) => runPreviewed('linkBugsToPlan', confirm, { planId, bugIds }, () => getApi().plan.linkBugsToPlan(planId, bugIds)));
117
+ server.tool('unlinkBugsFromPlan', {
118
+ planId: z.number().int().positive(),
119
+ bugIds: z.array(z.number().int().positive()).min(1).max(20),
120
+ confirm: z.boolean().optional().default(false),
121
+ }, async ({ planId, bugIds, confirm }) => runPreviewed('unlinkBugsFromPlan', confirm, { planId, bugIds }, () => getApi().plan.unlinkBugsFromPlan(planId, bugIds)));
122
+ }
123
+ //# sourceMappingURL=phase3a.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phase3a.js","sourceRoot":"","sources":["../../src/tools/phase3a.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,OAA4B,EAAE,OAAgB,EAAE,MAA8B;IACxH,MAAM,OAAO,GAAG,2BAA2B,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,IAAI,OAAO;QAAE,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAmB;IACzD,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE;QACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;QACjD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;QAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;QACjD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QAC3C,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAE5J,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE;QACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC5D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QAC3D,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QACrD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QACtD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QACtD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9J,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAmB;IAC1D,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACpC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;QAC5C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC9D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC7E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACzE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7G,MAAM,KAAK,GAAG,MAAM,MAAM,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG;YACd,SAAS;YACT,IAAI,EAAE,QAAQ;YACd,IAAI;YACJ,UAAU;YACV,QAAQ;YACR,UAAU;YACV,QAAQ;YACR,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,IAAI,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC,KAAK,EAAE;SACjD,CAAC;QACF,OAAO,YAAY,CAAC,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IACxG,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE;QAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;QAC5C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC9D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC7E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACzE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3G,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG;YACd,SAAS;YACT,IAAI,EAAE,QAAQ,IAAI,UAAU,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE;YACjD,IAAI;YACJ,UAAU;YACV,QAAQ;YACR,UAAU;YACV,QAAQ;YACR,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,IAAI,IAAI,UAAU,KAAK,KAAK,GAAG,CAAC,KAAK,cAAc,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE;SACpF,CAAC;QACF,OAAO,YAAY,CAAC,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAmB;IAC3D,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE;QAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACnC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEvK,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE;QACnC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACnC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,uBAAuB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE/K,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACnC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAE3J,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;QAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACnC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/C,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,oBAAoB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACrK,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { CliRegistry } from '../core/cli-registry.js';
2
+ export declare function registerExecutionWriteTools(server: CliRegistry): void;
3
+ export declare function registerBuildWriteTools(server: CliRegistry): void;
4
+ export declare function registerTestCaseWriteTools(server: CliRegistry): void;
5
+ export declare function registerTestTaskWriteTools(server: CliRegistry): void;
@@ -0,0 +1,161 @@
1
+ import { z } from 'zod';
2
+ import { getApi } from '../core/api-provider.js';
3
+ import { previewOrAssertWriteAllowed } from '../core/write-guard.js';
4
+ import { jsonResult } from './shared.js';
5
+ async function runPreviewed(action, confirm, payload, runner) {
6
+ const preview = previewOrAssertWriteAllowed({ action, confirm, payload });
7
+ if (preview)
8
+ return jsonResult(preview);
9
+ return jsonResult(await runner());
10
+ }
11
+ export function registerExecutionWriteTools(server) {
12
+ server.tool('updateExecution', {
13
+ executionId: z.number().int().positive(),
14
+ project: z.number().int().positive().optional().describe('所属项目 ID。禅道官方文档标为必填,建议从 getExecutionDetail 读回后原样传入'),
15
+ name: z.string().optional(),
16
+ code: z.string().optional().describe('迭代代号,实机验证发现当前实例更新执行时通常必填'),
17
+ desc: z.string().optional(),
18
+ begin: z.string().optional().describe('格式 YYYY-MM-DD'),
19
+ end: z.string().optional().describe('格式 YYYY-MM-DD'),
20
+ days: z.number().int().positive().optional().describe('可用工作日'),
21
+ lifetime: z.string().optional().describe('类型:short | long | ops'),
22
+ PO: z.string().optional().describe('产品负责人禅道账号'),
23
+ PM: z.string().optional().describe('负责人禅道账号'),
24
+ QD: z.string().optional().describe('测试负责人禅道账号'),
25
+ RD: z.string().optional().describe('发布负责人禅道账号'),
26
+ teamMembers: z.array(z.string()).optional().describe('团队成员账号数组'),
27
+ acl: z.string().optional().describe('访问控制:private | open'),
28
+ whitelist: z.array(z.string()).optional().describe('白名单账号数组'),
29
+ confirm: z.boolean().optional().default(false),
30
+ }, async ({ executionId, confirm, ...update }) => runPreviewed('updateExecution', confirm, { executionId, update }, () => getApi().execution.updateExecution(executionId, update)));
31
+ server.tool('startExecution', {
32
+ executionId: z.number().int().positive(),
33
+ realBegan: z.string().optional().describe('格式 YYYY-MM-DD'),
34
+ comment: z.string().optional(),
35
+ confirm: z.boolean().optional().default(false),
36
+ }, async ({ executionId, confirm, ...payload }) => runPreviewed('startExecution', confirm, { executionId, payload }, () => getApi().execution.startExecution(executionId, payload)));
37
+ server.tool('closeExecution', {
38
+ executionId: z.number().int().positive(),
39
+ realEnd: z.string().optional().describe('格式 YYYY-MM-DD'),
40
+ comment: z.string().optional(),
41
+ confirm: z.boolean().optional().default(false),
42
+ }, async ({ executionId, confirm, ...payload }) => runPreviewed('closeExecution', confirm, { executionId, payload }, () => getApi().execution.closeExecution(executionId, payload)));
43
+ server.tool('suspendExecution', {
44
+ executionId: z.number().int().positive(),
45
+ comment: z.string().optional(),
46
+ confirm: z.boolean().optional().default(false),
47
+ }, async ({ executionId, confirm, ...payload }) => runPreviewed('suspendExecution', confirm, { executionId, payload }, () => getApi().execution.suspendExecution(executionId, payload)));
48
+ server.tool('activateExecution', {
49
+ executionId: z.number().int().positive(),
50
+ comment: z.string().optional(),
51
+ confirm: z.boolean().optional().default(false),
52
+ }, async ({ executionId, confirm, ...payload }) => runPreviewed('activateExecution', confirm, { executionId, payload }, () => getApi().execution.activateExecution(executionId, payload)));
53
+ server.tool('putoffExecution', {
54
+ executionId: z.number().int().positive(),
55
+ days: z.number().int().positive(),
56
+ comment: z.string().optional(),
57
+ confirm: z.boolean().optional().default(false),
58
+ }, async ({ executionId, confirm, ...payload }) => runPreviewed('putoffExecution', confirm, { executionId, payload }, () => getApi().execution.putoffExecution(executionId, payload)));
59
+ }
60
+ export function registerBuildWriteTools(server) {
61
+ server.tool('createBuild', {
62
+ project: z.number().int().positive(),
63
+ execution: z.number().int().positive(),
64
+ product: z.number().int().positive(),
65
+ branch: z.number().int().nonnegative().optional(),
66
+ name: z.string().min(1),
67
+ builder: z.string().min(1),
68
+ date: z.string().optional().describe('格式 YYYY-MM-DD'),
69
+ desc: z.string().optional(),
70
+ scmPath: z.string().optional(),
71
+ filePath: z.string().optional(),
72
+ confirm: z.boolean().optional().default(false),
73
+ }, async ({ confirm, ...payload }) => runPreviewed('createBuild', confirm, payload, () => getApi().build.createBuild(payload)));
74
+ server.tool('updateBuild', {
75
+ buildId: z.number().int().positive(),
76
+ execution: z.number().int().positive().optional(),
77
+ product: z.number().int().positive().optional(),
78
+ name: z.string().optional(),
79
+ builder: z.string().optional(),
80
+ date: z.string().optional().describe('格式 YYYY-MM-DD'),
81
+ desc: z.string().optional(),
82
+ scmPath: z.string().optional(),
83
+ filePath: z.string().optional(),
84
+ confirm: z.boolean().optional().default(false),
85
+ }, async ({ buildId, confirm, ...update }) => runPreviewed('updateBuild', confirm, { buildId, update }, () => getApi().build.updateBuild(buildId, update)));
86
+ }
87
+ const testCaseStepSchema = z.object({
88
+ desc: z.string().min(1),
89
+ expect: z.string().min(1),
90
+ type: z.enum(['step', 'item', 'group']).optional().describe('禅道 18.5 支持 step/item/group,默认 step'),
91
+ });
92
+ export function registerTestCaseWriteTools(server) {
93
+ server.tool('createTestCase', {
94
+ productId: z.number().int().positive(),
95
+ title: z.string().min(1),
96
+ type: z.string().min(1),
97
+ steps: z.array(testCaseStepSchema).min(1),
98
+ branch: z.number().int().nonnegative().optional(),
99
+ module: z.number().int().nonnegative().optional(),
100
+ story: z.number().int().nonnegative().optional(),
101
+ stage: z.string().optional(),
102
+ precondition: z.string().optional(),
103
+ script: z.string().optional(),
104
+ pri: z.number().int().optional(),
105
+ keywords: z.string().optional().describe('禅道 18.5 REST v1 创建用例不接收该字段,传入会被忽略'),
106
+ project: z.number().int().positive().optional().describe('禅道 18.5 REST v1 创建产品用例不绑定项目,传入会被忽略'),
107
+ execution: z.number().int().positive().optional().describe('禅道 18.5 REST v1 创建产品用例不绑定执行,传入会被忽略'),
108
+ confirm: z.boolean().optional().default(false),
109
+ }, async ({ productId, confirm, ...payload }) => runPreviewed('createTestCase', confirm, { productId, ...payload }, () => getApi().testcase.createTestCase(productId, payload)));
110
+ server.tool('updateTestCase', {
111
+ testCaseId: z.number().int().positive(),
112
+ branch: z.number().int().nonnegative().optional(),
113
+ module: z.number().int().nonnegative().optional(),
114
+ story: z.number().int().nonnegative().optional(),
115
+ title: z.string().optional(),
116
+ type: z.string().optional(),
117
+ stage: z.string().optional(),
118
+ precondition: z.string().optional(),
119
+ script: z.string().optional(),
120
+ pri: z.number().int().optional(),
121
+ steps: z.array(testCaseStepSchema).min(1).optional(),
122
+ keywords: z.string().optional().describe('禅道 18.5 REST v1 更新用例不接收该字段,传入会被忽略'),
123
+ project: z.number().int().positive().optional().describe('禅道 18.5 REST v1 更新用例不接收该字段,传入会被忽略'),
124
+ execution: z.number().int().positive().optional().describe('禅道 18.5 REST v1 更新用例不接收该字段,传入会被忽略'),
125
+ confirm: z.boolean().optional().default(false),
126
+ }, async ({ testCaseId, confirm, ...update }) => runPreviewed('updateTestCase', confirm, { testCaseId, update }, () => getApi().testcase.updateTestCase(testCaseId, update)));
127
+ }
128
+ export function registerTestTaskWriteTools(server) {
129
+ server.tool('createTestTask', {
130
+ project: z.number().int().positive().describe('所属项目 ID,实机验证发现当前实例创建测试单时必填'),
131
+ productID: z.number().int().positive(),
132
+ name: z.string().min(1),
133
+ build: z.union([z.number().int().positive(), z.string().min(1)]),
134
+ begin: z.string().min(1).describe('格式 YYYY-MM-DD'),
135
+ end: z.string().min(1).describe('格式 YYYY-MM-DD'),
136
+ execution: z.number().int().positive().optional(),
137
+ type: z.array(z.string()).optional(),
138
+ owner: z.string().optional(),
139
+ status: z.string().optional(),
140
+ pri: z.number().int().optional(),
141
+ desc: z.string().optional(),
142
+ confirm: z.boolean().optional().default(false),
143
+ }, async ({ confirm, ...payload }) => runPreviewed('createTestTask', confirm, payload, () => getApi().testtask.createTestTask(payload)));
144
+ server.tool('updateTestTask', {
145
+ testTaskId: z.number().int().positive(),
146
+ project: z.number().int().positive().optional(),
147
+ productID: z.number().int().positive().optional(),
148
+ name: z.string().optional(),
149
+ build: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
150
+ execution: z.number().int().positive().optional(),
151
+ type: z.array(z.string()).optional(),
152
+ owner: z.string().optional(),
153
+ status: z.string().optional(),
154
+ pri: z.number().int().optional(),
155
+ begin: z.string().optional().describe('格式 YYYY-MM-DD'),
156
+ end: z.string().optional().describe('格式 YYYY-MM-DD'),
157
+ desc: z.string().optional(),
158
+ confirm: z.boolean().optional().default(false),
159
+ }, async ({ testTaskId, confirm, ...update }) => runPreviewed('updateTestTask', confirm, { testTaskId, update }, () => getApi().testtask.updateTestTask(testTaskId, update)));
160
+ }
161
+ //# sourceMappingURL=phase3b.js.map