@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.
- package/CHANGELOG.md +50 -0
- package/MCP_ZENTAO_REBUILD_PLAN.md +505 -0
- package/README.md +319 -0
- package/dist/api/bug.d.ts +32 -0
- package/dist/api/bug.js +85 -0
- package/dist/api/bug.js.map +1 -0
- package/dist/api/build.d.ts +31 -0
- package/dist/api/build.js +21 -0
- package/dist/api/build.js.map +1 -0
- package/dist/api/comment.d.ts +20 -0
- package/dist/api/comment.js +47 -0
- package/dist/api/comment.js.map +1 -0
- package/dist/api/development-context.d.ts +14 -0
- package/dist/api/development-context.js +35 -0
- package/dist/api/development-context.js.map +1 -0
- package/dist/api/execution.d.ts +46 -0
- package/dist/api/execution.js +47 -0
- package/dist/api/execution.js.map +1 -0
- package/dist/api/index.d.ts +43 -0
- package/dist/api/index.js +46 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/plan.d.ts +18 -0
- package/dist/api/plan.js +33 -0
- package/dist/api/plan.js.map +1 -0
- package/dist/api/product.d.ts +7 -0
- package/dist/api/product.js +14 -0
- package/dist/api/product.js.map +1 -0
- package/dist/api/program.d.ts +7 -0
- package/dist/api/program.js +14 -0
- package/dist/api/program.js.map +1 -0
- package/dist/api/project.d.ts +8 -0
- package/dist/api/project.js +15 -0
- package/dist/api/project.js.map +1 -0
- package/dist/api/relation.d.ts +17 -0
- package/dist/api/relation.js +66 -0
- package/dist/api/relation.js.map +1 -0
- package/dist/api/release.d.ts +6 -0
- package/dist/api/release.js +11 -0
- package/dist/api/release.js.map +1 -0
- package/dist/api/search.d.ts +17 -0
- package/dist/api/search.js +168 -0
- package/dist/api/search.js.map +1 -0
- package/dist/api/statistics.d.ts +13 -0
- package/dist/api/statistics.js +67 -0
- package/dist/api/statistics.js.map +1 -0
- package/dist/api/story.d.ts +14 -0
- package/dist/api/story.js +23 -0
- package/dist/api/story.js.map +1 -0
- package/dist/api/task.d.ts +17 -0
- package/dist/api/task.js +37 -0
- package/dist/api/task.js.map +1 -0
- package/dist/api/testcase.d.ts +51 -0
- package/dist/api/testcase.js +31 -0
- package/dist/api/testcase.js.map +1 -0
- package/dist/api/testtask.d.ts +41 -0
- package/dist/api/testtask.js +34 -0
- package/dist/api/testtask.js.map +1 -0
- package/dist/api/user.d.ts +6 -0
- package/dist/api/user.js +9 -0
- package/dist/api/user.js.map +1 -0
- package/dist/bin/zentao-dev.d.ts +2 -0
- package/dist/bin/zentao-dev.js +8 -0
- package/dist/bin/zentao-dev.js.map +1 -0
- package/dist/bin/zentao-pm.d.ts +2 -0
- package/dist/bin/zentao-pm.js +8 -0
- package/dist/bin/zentao-pm.js.map +1 -0
- package/dist/bin/zentao-qa.d.ts +2 -0
- package/dist/bin/zentao-qa.js +8 -0
- package/dist/bin/zentao-qa.js.map +1 -0
- package/dist/bin/zentao.d.ts +2 -0
- package/dist/bin/zentao.js +8 -0
- package/dist/bin/zentao.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +74 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/api-provider.d.ts +3 -0
- package/dist/core/api-provider.js +17 -0
- package/dist/core/api-provider.js.map +1 -0
- package/dist/core/auth.d.ts +13 -0
- package/dist/core/auth.js +90 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/cli-registry.d.ts +18 -0
- package/dist/core/cli-registry.js +128 -0
- package/dist/core/cli-registry.js.map +1 -0
- package/dist/core/config.d.ts +7 -0
- package/dist/core/config.js +58 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/http.d.ts +12 -0
- package/dist/core/http.js +50 -0
- package/dist/core/http.js.map +1 -0
- package/dist/core/list-result.d.ts +14 -0
- package/dist/core/list-result.js +59 -0
- package/dist/core/list-result.js.map +1 -0
- package/dist/core/pagination.d.ts +9 -0
- package/dist/core/pagination.js +12 -0
- package/dist/core/pagination.js.map +1 -0
- package/dist/core/roles.d.ts +4 -0
- package/dist/core/roles.js +13 -0
- package/dist/core/roles.js.map +1 -0
- package/dist/core/tool-registry.d.ts +3 -0
- package/dist/core/tool-registry.js +77 -0
- package/dist/core/tool-registry.js.map +1 -0
- package/dist/core/write-guard.d.ts +25 -0
- package/dist/core/write-guard.js +53 -0
- package/dist/core/write-guard.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/bug.d.ts +2 -0
- package/dist/tools/bug.js +41 -0
- package/dist/tools/bug.js.map +1 -0
- package/dist/tools/build.d.ts +2 -0
- package/dist/tools/build.js +8 -0
- package/dist/tools/build.js.map +1 -0
- package/dist/tools/comment.d.ts +2 -0
- package/dist/tools/comment.js +23 -0
- package/dist/tools/comment.js.map +1 -0
- package/dist/tools/context.d.ts +2 -0
- package/dist/tools/context.js +11 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/execution.d.ts +2 -0
- package/dist/tools/execution.js +21 -0
- package/dist/tools/execution.js.map +1 -0
- package/dist/tools/init.d.ts +2 -0
- package/dist/tools/init.js +28 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/phase3a.d.ts +4 -0
- package/dist/tools/phase3a.js +123 -0
- package/dist/tools/phase3a.js.map +1 -0
- package/dist/tools/phase3b.d.ts +5 -0
- package/dist/tools/phase3b.js +161 -0
- package/dist/tools/phase3b.js.map +1 -0
- package/dist/tools/plan.d.ts +2 -0
- package/dist/tools/plan.js +14 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/product.d.ts +2 -0
- package/dist/tools/product.js +10 -0
- package/dist/tools/product.js.map +1 -0
- package/dist/tools/profile.d.ts +2 -0
- package/dist/tools/profile.js +6 -0
- package/dist/tools/profile.js.map +1 -0
- package/dist/tools/program.d.ts +2 -0
- package/dist/tools/program.js +8 -0
- package/dist/tools/program.js.map +1 -0
- package/dist/tools/project.d.ts +2 -0
- package/dist/tools/project.js +13 -0
- package/dist/tools/project.js.map +1 -0
- package/dist/tools/relation.d.ts +2 -0
- package/dist/tools/relation.js +13 -0
- package/dist/tools/relation.js.map +1 -0
- package/dist/tools/release.d.ts +2 -0
- package/dist/tools/release.js +7 -0
- package/dist/tools/release.js.map +1 -0
- package/dist/tools/search.d.ts +2 -0
- package/dist/tools/search.js +18 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/shared.d.ts +2 -0
- package/dist/tools/shared.js +11 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/statistics.d.ts +2 -0
- package/dist/tools/statistics.js +10 -0
- package/dist/tools/statistics.js.map +1 -0
- package/dist/tools/story.d.ts +2 -0
- package/dist/tools/story.js +14 -0
- package/dist/tools/story.js.map +1 -0
- package/dist/tools/task.d.ts +2 -0
- package/dist/tools/task.js +48 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/tools/testcase.d.ts +2 -0
- package/dist/tools/testcase.js +16 -0
- package/dist/tools/testcase.js.map +1 -0
- package/dist/tools/testtask.d.ts +2 -0
- package/dist/tools/testtask.js +14 -0
- package/dist/tools/testtask.js.map +1 -0
- package/dist/types/common.d.ts +15 -0
- package/dist/types/common.js +2 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/zentao.d.ts +42 -0
- package/dist/types/zentao.js +2 -0
- package/dist/types/zentao.js.map +1 -0
- package/dist/utils/json.d.ts +2 -0
- package/dist/utils/json.js +27 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- 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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -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,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,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,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,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,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,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":"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"}
|
|
@@ -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
|