@zzp123/mcp-zentao 1.16.0 → 1.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +80 -10
- package/dist/index-dev.d.ts +10 -0
- package/dist/index-dev.js +896 -0
- package/dist/index-pm.d.ts +10 -0
- package/dist/index-pm.js +1131 -0
- package/dist/index-qa.d.ts +10 -0
- package/dist/index-qa.js +916 -0
- package/dist/index.js +1 -1
- package/dist/roleConfig.d.ts +48 -0
- package/dist/roleConfig.js +204 -0
- package/json-args.js +0 -0
- package/package.json +3 -3
- package/scripts/generate-role-versions.cjs +213 -0
package/dist/index.js
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export type Role = 'pm' | 'qa' | 'dev' | 'admin' | 'all';
|
|
2
|
+
export declare const TOOL_CATEGORIES: {
|
|
3
|
+
init: string[];
|
|
4
|
+
story: string[];
|
|
5
|
+
storyReadonly: string[];
|
|
6
|
+
product: string[];
|
|
7
|
+
plan: string[];
|
|
8
|
+
program: string[];
|
|
9
|
+
feedback: string[];
|
|
10
|
+
bug: string[];
|
|
11
|
+
bugResolve: string[];
|
|
12
|
+
bugReadonly: string[];
|
|
13
|
+
testcase: string[];
|
|
14
|
+
task: string[];
|
|
15
|
+
taskReadonly: string[];
|
|
16
|
+
project: string[];
|
|
17
|
+
execution: string[];
|
|
18
|
+
build: string[];
|
|
19
|
+
ticket: string[];
|
|
20
|
+
comment: string[];
|
|
21
|
+
utility: string[];
|
|
22
|
+
user: string[];
|
|
23
|
+
};
|
|
24
|
+
export declare const ROLE_PERMISSIONS: Record<Role, string[]>;
|
|
25
|
+
/**
|
|
26
|
+
* 检查当前角色是否有权限使用指定工具
|
|
27
|
+
* @param toolName 工具名称
|
|
28
|
+
* @param role 当前角色
|
|
29
|
+
* @returns true 如果有权限,false 否则
|
|
30
|
+
*/
|
|
31
|
+
export declare function hasPermission(toolName: string, role?: Role): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* 获取当前运行环境的角色
|
|
34
|
+
* @returns 角色类型
|
|
35
|
+
*/
|
|
36
|
+
export declare function getCurrentRole(): Role;
|
|
37
|
+
/**
|
|
38
|
+
* 获取当前角色的工具列表
|
|
39
|
+
* @param role 角色类型
|
|
40
|
+
* @returns 工具名称数组
|
|
41
|
+
*/
|
|
42
|
+
export declare function getToolsForRole(role: Role): string[];
|
|
43
|
+
/**
|
|
44
|
+
* 获取角色的显示名称
|
|
45
|
+
* @param role 角色类型
|
|
46
|
+
* @returns 角色的中文显示名称
|
|
47
|
+
*/
|
|
48
|
+
export declare function getRoleName(role: Role): string;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// 角色配置 - 定义每个角色可以使用的工具
|
|
2
|
+
// 工具分类
|
|
3
|
+
export const TOOL_CATEGORIES = {
|
|
4
|
+
// 初始化工具(所有角色都需要)
|
|
5
|
+
init: ['initZentao'],
|
|
6
|
+
// 需求管理(产品经理完整权限,其他只读)
|
|
7
|
+
story: [
|
|
8
|
+
'createStory', 'createRequirement', 'getStoryDetail',
|
|
9
|
+
'changeStory', 'changeRequirement', 'deleteStory', 'deleteRequirement',
|
|
10
|
+
'getRequirementDetail', 'getProductStories', 'addStoryComment'
|
|
11
|
+
],
|
|
12
|
+
storyReadonly: ['getStoryDetail', 'getRequirementDetail', 'getProductStories'],
|
|
13
|
+
// 产品管理(仅产品经理)
|
|
14
|
+
product: [
|
|
15
|
+
'getProducts', 'getProductDetail', 'createProduct',
|
|
16
|
+
'updateProduct', 'deleteProduct'
|
|
17
|
+
],
|
|
18
|
+
// 计划管理(仅产品经理)
|
|
19
|
+
plan: [
|
|
20
|
+
'getProductPlans', 'getPlanDetail', 'createPlan',
|
|
21
|
+
'updatePlan', 'deletePlan', 'linkStoriesToPlan',
|
|
22
|
+
'unlinkStoriesFromPlan', 'linkBugsToPlan', 'unlinkBugsFromPlan'
|
|
23
|
+
],
|
|
24
|
+
// 项目集管理(仅产品经理)
|
|
25
|
+
program: [
|
|
26
|
+
'getPrograms', 'getProgramDetail', 'createProgram',
|
|
27
|
+
'updateProgram', 'deleteProgram'
|
|
28
|
+
],
|
|
29
|
+
// 反馈管理(仅产品经理)
|
|
30
|
+
feedback: [
|
|
31
|
+
'getFeedbacks', 'getFeedbackDetail', 'createFeedback',
|
|
32
|
+
'updateFeedback', 'deleteFeedback', 'assignFeedback', 'closeFeedback'
|
|
33
|
+
],
|
|
34
|
+
// Bug管理(测试完整权限,开发可以解决,产品只读)
|
|
35
|
+
bug: [
|
|
36
|
+
'getMyBugs', 'getProductBugs', 'getBugDetail', 'createBug',
|
|
37
|
+
'updateBug', 'deleteBug', 'resolveBug', 'addBugComment'
|
|
38
|
+
],
|
|
39
|
+
bugResolve: ['getMyBugs', 'getBugDetail', 'resolveBug', 'addBugComment'],
|
|
40
|
+
bugReadonly: ['getMyBugs', 'getProductBugs', 'getBugDetail'],
|
|
41
|
+
// 测试用例(仅测试)
|
|
42
|
+
testcase: [
|
|
43
|
+
'getProductTestCases', 'getTestCaseDetail', 'createTestCase',
|
|
44
|
+
'updateTestCase', 'deleteTestCase'
|
|
45
|
+
],
|
|
46
|
+
// 任务管理(开发完整权限,其他只读)
|
|
47
|
+
task: [
|
|
48
|
+
'getMyTasks', 'getTaskDetail', 'createTask',
|
|
49
|
+
'updateTask', 'finishTask', 'deleteTask', 'addTaskComment'
|
|
50
|
+
],
|
|
51
|
+
taskReadonly: ['getMyTasks', 'getTaskDetail'],
|
|
52
|
+
// 项目管理(仅开发)
|
|
53
|
+
project: [
|
|
54
|
+
'getProjects', 'getProjectDetail', 'createProject',
|
|
55
|
+
'updateProject', 'deleteProject', 'getProjectReleases',
|
|
56
|
+
'getProjectExecutions', 'getProjectBuilds'
|
|
57
|
+
],
|
|
58
|
+
// 迭代管理(仅开发)
|
|
59
|
+
execution: [
|
|
60
|
+
'getExecutionDetail', 'createExecution', 'updateExecution',
|
|
61
|
+
'deleteExecution', 'getExecutionBuilds'
|
|
62
|
+
],
|
|
63
|
+
// 版本构建(测试和开发)
|
|
64
|
+
build: [
|
|
65
|
+
'getBuildDetail', 'createBuild', 'updateBuild', 'deleteBuild'
|
|
66
|
+
],
|
|
67
|
+
// 工单管理(所有角色)
|
|
68
|
+
ticket: [
|
|
69
|
+
'getTickets', 'getTicketDetail', 'createTicket',
|
|
70
|
+
'updateTicket', 'deleteTicket'
|
|
71
|
+
],
|
|
72
|
+
// 评论功能(所有角色)
|
|
73
|
+
comment: [
|
|
74
|
+
'getComments', 'getCommentDetail', 'addComment',
|
|
75
|
+
'updateComment', 'deleteComment', 'addTaskComment', 'addBugComment'
|
|
76
|
+
],
|
|
77
|
+
// 模块和文件(所有角色)
|
|
78
|
+
utility: [
|
|
79
|
+
'getModules', 'uploadFile', 'uploadImageFromClipboard', 'downloadFile'
|
|
80
|
+
],
|
|
81
|
+
// 用户管理(仅管理员)
|
|
82
|
+
user: [
|
|
83
|
+
'getUsers', 'getUserDetail', 'getMyProfile', 'createUser',
|
|
84
|
+
'updateUser', 'deleteUser'
|
|
85
|
+
]
|
|
86
|
+
};
|
|
87
|
+
// 角色权限配置
|
|
88
|
+
export const ROLE_PERMISSIONS = {
|
|
89
|
+
// 产品经理:需求、产品、计划、项目集、反馈、评论
|
|
90
|
+
pm: [
|
|
91
|
+
...TOOL_CATEGORIES.init,
|
|
92
|
+
...TOOL_CATEGORIES.story,
|
|
93
|
+
...TOOL_CATEGORIES.product,
|
|
94
|
+
...TOOL_CATEGORIES.plan,
|
|
95
|
+
...TOOL_CATEGORIES.program,
|
|
96
|
+
...TOOL_CATEGORIES.feedback,
|
|
97
|
+
...TOOL_CATEGORIES.bugReadonly,
|
|
98
|
+
...TOOL_CATEGORIES.taskReadonly,
|
|
99
|
+
...TOOL_CATEGORIES.comment,
|
|
100
|
+
...TOOL_CATEGORIES.ticket,
|
|
101
|
+
...TOOL_CATEGORIES.utility
|
|
102
|
+
],
|
|
103
|
+
// 测试工程师:Bug、测试用例、版本构建、评论
|
|
104
|
+
qa: [
|
|
105
|
+
...TOOL_CATEGORIES.init,
|
|
106
|
+
...TOOL_CATEGORIES.bug,
|
|
107
|
+
...TOOL_CATEGORIES.testcase,
|
|
108
|
+
...TOOL_CATEGORIES.build,
|
|
109
|
+
...TOOL_CATEGORIES.storyReadonly,
|
|
110
|
+
...TOOL_CATEGORIES.taskReadonly,
|
|
111
|
+
...TOOL_CATEGORIES.comment,
|
|
112
|
+
...TOOL_CATEGORIES.ticket,
|
|
113
|
+
...TOOL_CATEGORIES.utility
|
|
114
|
+
],
|
|
115
|
+
// 开发工程师:任务、Bug解决、项目、迭代、版本构建、评论
|
|
116
|
+
dev: [
|
|
117
|
+
...TOOL_CATEGORIES.init,
|
|
118
|
+
...TOOL_CATEGORIES.task,
|
|
119
|
+
...TOOL_CATEGORIES.bugResolve,
|
|
120
|
+
...TOOL_CATEGORIES.project,
|
|
121
|
+
...TOOL_CATEGORIES.execution,
|
|
122
|
+
...TOOL_CATEGORIES.build,
|
|
123
|
+
...TOOL_CATEGORIES.storyReadonly,
|
|
124
|
+
...TOOL_CATEGORIES.comment,
|
|
125
|
+
...TOOL_CATEGORIES.utility
|
|
126
|
+
],
|
|
127
|
+
// 管理员:所有工具
|
|
128
|
+
admin: [
|
|
129
|
+
...TOOL_CATEGORIES.init,
|
|
130
|
+
...TOOL_CATEGORIES.story,
|
|
131
|
+
...TOOL_CATEGORIES.product,
|
|
132
|
+
...TOOL_CATEGORIES.plan,
|
|
133
|
+
...TOOL_CATEGORIES.program,
|
|
134
|
+
...TOOL_CATEGORIES.feedback,
|
|
135
|
+
...TOOL_CATEGORIES.bug,
|
|
136
|
+
...TOOL_CATEGORIES.testcase,
|
|
137
|
+
...TOOL_CATEGORIES.task,
|
|
138
|
+
...TOOL_CATEGORIES.project,
|
|
139
|
+
...TOOL_CATEGORIES.execution,
|
|
140
|
+
...TOOL_CATEGORIES.build,
|
|
141
|
+
...TOOL_CATEGORIES.comment,
|
|
142
|
+
...TOOL_CATEGORIES.ticket,
|
|
143
|
+
...TOOL_CATEGORIES.utility,
|
|
144
|
+
...TOOL_CATEGORIES.user
|
|
145
|
+
],
|
|
146
|
+
// 完整权限(默认)
|
|
147
|
+
all: [] // 空数组表示所有工具都可用
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* 检查当前角色是否有权限使用指定工具
|
|
151
|
+
* @param toolName 工具名称
|
|
152
|
+
* @param role 当前角色
|
|
153
|
+
* @returns true 如果有权限,false 否则
|
|
154
|
+
*/
|
|
155
|
+
export function hasPermission(toolName, role = 'all') {
|
|
156
|
+
// 'all' 角色有所有权限
|
|
157
|
+
if (role === 'all')
|
|
158
|
+
return true;
|
|
159
|
+
// 检查该角色的权限列表
|
|
160
|
+
const permissions = ROLE_PERMISSIONS[role];
|
|
161
|
+
if (!permissions)
|
|
162
|
+
return false;
|
|
163
|
+
return permissions.includes(toolName);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 获取当前运行环境的角色
|
|
167
|
+
* @returns 角色类型
|
|
168
|
+
*/
|
|
169
|
+
export function getCurrentRole() {
|
|
170
|
+
const role = process.env.ZENTAO_ROLE?.toLowerCase();
|
|
171
|
+
// 验证是否是有效的角色
|
|
172
|
+
if (role && ['pm', 'qa', 'dev', 'admin', 'all'].includes(role)) {
|
|
173
|
+
return role;
|
|
174
|
+
}
|
|
175
|
+
// 默认返回 'all'(所有权限)
|
|
176
|
+
return 'all';
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 获取当前角色的工具列表
|
|
180
|
+
* @param role 角色类型
|
|
181
|
+
* @returns 工具名称数组
|
|
182
|
+
*/
|
|
183
|
+
export function getToolsForRole(role) {
|
|
184
|
+
if (role === 'all') {
|
|
185
|
+
// 返回所有工具
|
|
186
|
+
return Object.values(TOOL_CATEGORIES).flat();
|
|
187
|
+
}
|
|
188
|
+
return ROLE_PERMISSIONS[role] || [];
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 获取角色的显示名称
|
|
192
|
+
* @param role 角色类型
|
|
193
|
+
* @returns 角色的中文显示名称
|
|
194
|
+
*/
|
|
195
|
+
export function getRoleName(role) {
|
|
196
|
+
const names = {
|
|
197
|
+
pm: '产品经理',
|
|
198
|
+
qa: '测试工程师',
|
|
199
|
+
dev: '开发工程师',
|
|
200
|
+
admin: '管理员',
|
|
201
|
+
all: '完整权限'
|
|
202
|
+
};
|
|
203
|
+
return names[role] || '未知角色';
|
|
204
|
+
}
|
package/json-args.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zzp123/mcp-zentao",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "禅道项目管理系统的高级API
|
|
3
|
+
"version": "1.17.1",
|
|
4
|
+
"description": "禅道项目管理系统的高级API集成包 - 完整版,包含所有94个工具。另有产品经理、测试工程师、开发工程师专用精简版本可选",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"zentao": "
|
|
9
|
+
"mcp-zentao": "dist/index.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// 角色工具配置
|
|
5
|
+
const TOOL_CATEGORIES = {
|
|
6
|
+
init: ['initZentao'],
|
|
7
|
+
story: ['createStory', 'getStoryDetail', 'changeStory', 'deleteStory', 'getProductStories', 'addStoryComment'],
|
|
8
|
+
storyReadonly: ['getStoryDetail', 'getProductStories'],
|
|
9
|
+
product: ['getProducts', 'getProductDetail', 'createProduct', 'updateProduct', 'deleteProduct'],
|
|
10
|
+
plan: ['getProductPlans', 'getPlanDetail', 'createPlan', 'updatePlan', 'deletePlan', 'linkStoriesToPlan', 'unlinkStoriesFromPlan', 'linkBugsToPlan', 'unlinkBugsFromPlan'],
|
|
11
|
+
program: ['getPrograms', 'getProgramDetail', 'createProgram', 'updateProgram', 'deleteProgram'],
|
|
12
|
+
feedback: ['getFeedbacks', 'getFeedbackDetail', 'createFeedback', 'updateFeedback', 'deleteFeedback', 'assignFeedback', 'closeFeedback'],
|
|
13
|
+
bug: ['getMyBugs', 'getProductBugs', 'getBugDetail', 'createBug', 'updateBug', 'deleteBug', 'resolveBug', 'addBugComment'],
|
|
14
|
+
bugResolve: ['getMyBugs', 'getBugDetail', 'resolveBug', 'addBugComment'],
|
|
15
|
+
bugReadonly: ['getMyBugs', 'getProductBugs', 'getBugDetail'],
|
|
16
|
+
testcase: ['getProductTestCases', 'getTestCaseDetail', 'createTestCase', 'updateTestCase', 'deleteTestCase'],
|
|
17
|
+
task: ['getMyTasks', 'getTaskDetail', 'createTask', 'updateTask', 'finishTask', 'deleteTask', 'addTaskComment'],
|
|
18
|
+
taskReadonly: ['getMyTasks', 'getTaskDetail'],
|
|
19
|
+
project: ['getProjects', 'getProjectDetail', 'createProject', 'updateProject', 'deleteProject', 'getProjectReleases', 'getProjectExecutions', 'getProjectBuilds'],
|
|
20
|
+
execution: ['getExecutionDetail', 'createExecution', 'updateExecution', 'deleteExecution', 'getExecutionBuilds'],
|
|
21
|
+
build: ['getBuildDetail', 'createBuild', 'updateBuild', 'deleteBuild'],
|
|
22
|
+
ticket: ['getTickets', 'getTicketDetail', 'createTicket', 'updateTicket', 'deleteTicket'],
|
|
23
|
+
comment: ['getComments', 'getCommentDetail', 'addComment', 'updateComment', 'deleteComment', 'addTaskComment', 'addBugComment', 'addStoryComment'],
|
|
24
|
+
utility: ['getModules', 'uploadFile', 'uploadImageFromClipboard', 'downloadFile'],
|
|
25
|
+
user: ['getUsers', 'getUserDetail', 'getMyProfile', 'createUser', 'updateUser', 'deleteUser']
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const ROLE_PERMISSIONS = {
|
|
29
|
+
pm: [
|
|
30
|
+
...TOOL_CATEGORIES.init,
|
|
31
|
+
...TOOL_CATEGORIES.story,
|
|
32
|
+
...TOOL_CATEGORIES.product,
|
|
33
|
+
...TOOL_CATEGORIES.plan,
|
|
34
|
+
...TOOL_CATEGORIES.program,
|
|
35
|
+
...TOOL_CATEGORIES.feedback,
|
|
36
|
+
...TOOL_CATEGORIES.bugReadonly,
|
|
37
|
+
...TOOL_CATEGORIES.taskReadonly,
|
|
38
|
+
...TOOL_CATEGORIES.comment,
|
|
39
|
+
...TOOL_CATEGORIES.ticket,
|
|
40
|
+
...TOOL_CATEGORIES.utility
|
|
41
|
+
],
|
|
42
|
+
qa: [
|
|
43
|
+
...TOOL_CATEGORIES.init,
|
|
44
|
+
...TOOL_CATEGORIES.bug,
|
|
45
|
+
...TOOL_CATEGORIES.testcase,
|
|
46
|
+
...TOOL_CATEGORIES.build,
|
|
47
|
+
...TOOL_CATEGORIES.storyReadonly,
|
|
48
|
+
...TOOL_CATEGORIES.taskReadonly,
|
|
49
|
+
...TOOL_CATEGORIES.comment,
|
|
50
|
+
...TOOL_CATEGORIES.ticket,
|
|
51
|
+
...TOOL_CATEGORIES.utility
|
|
52
|
+
],
|
|
53
|
+
dev: [
|
|
54
|
+
...TOOL_CATEGORIES.init,
|
|
55
|
+
...TOOL_CATEGORIES.task,
|
|
56
|
+
...TOOL_CATEGORIES.bugResolve,
|
|
57
|
+
...TOOL_CATEGORIES.project,
|
|
58
|
+
...TOOL_CATEGORIES.execution,
|
|
59
|
+
...TOOL_CATEGORIES.build,
|
|
60
|
+
...TOOL_CATEGORIES.storyReadonly,
|
|
61
|
+
...TOOL_CATEGORIES.comment,
|
|
62
|
+
...TOOL_CATEGORIES.utility
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const ROLE_NAMES = {
|
|
67
|
+
pm: '产品经理',
|
|
68
|
+
qa: '测试工程师',
|
|
69
|
+
dev: '开发工程师'
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// 读取完整的 index.ts
|
|
73
|
+
const indexPath = path.join(__dirname, '..', 'src', 'index.ts');
|
|
74
|
+
const indexContent = fs.readFileSync(indexPath, 'utf8');
|
|
75
|
+
|
|
76
|
+
// 提取工具注册块的函数
|
|
77
|
+
function extractToolBlocks(content) {
|
|
78
|
+
const lines = content.split('\n');
|
|
79
|
+
const blocks = [];
|
|
80
|
+
let currentBlock = null;
|
|
81
|
+
let braceDepth = 0;
|
|
82
|
+
let parenDepth = 0;
|
|
83
|
+
|
|
84
|
+
for (let i = 0; i < lines.length; i++) {
|
|
85
|
+
const line = lines[i];
|
|
86
|
+
const trimmed = line.trim();
|
|
87
|
+
|
|
88
|
+
// 检测 server.tool 的开始
|
|
89
|
+
if (trimmed.startsWith('server.tool(')) {
|
|
90
|
+
// 提取工具名
|
|
91
|
+
const match = trimmed.match(/server\.tool\("([^"]+)"/);
|
|
92
|
+
if (match) {
|
|
93
|
+
currentBlock = {
|
|
94
|
+
toolName: match[1],
|
|
95
|
+
startLine: i,
|
|
96
|
+
lines: [line],
|
|
97
|
+
braceDepth: 0,
|
|
98
|
+
parenDepth: 0
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// 计算当前行的括号和大括号
|
|
102
|
+
currentBlock.parenDepth += (line.match(/\(/g) || []).length - (line.match(/\)/g) || []).length;
|
|
103
|
+
currentBlock.braceDepth += (line.match(/\{/g) || []).length - (line.match(/\}/g) || []).length;
|
|
104
|
+
}
|
|
105
|
+
} else if (currentBlock) {
|
|
106
|
+
// 在工具块内
|
|
107
|
+
currentBlock.lines.push(line);
|
|
108
|
+
currentBlock.parenDepth += (line.match(/\(/g) || []).length - (line.match(/\)/g) || []).length;
|
|
109
|
+
currentBlock.braceDepth += (line.match(/\{/g) || []).length - (line.match(/\}/g) || []).length;
|
|
110
|
+
|
|
111
|
+
// 检查是否到达块的结束(圆括号和大括号都平衡,且以 ); 结尾)
|
|
112
|
+
if (currentBlock.parenDepth === 0 && currentBlock.braceDepth === 0 && trimmed.endsWith(');')) {
|
|
113
|
+
currentBlock.endLine = i;
|
|
114
|
+
blocks.push(currentBlock);
|
|
115
|
+
currentBlock = null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return blocks;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 为每个角色生成文件
|
|
124
|
+
['pm', 'qa', 'dev'].forEach(role => {
|
|
125
|
+
console.log(`\n正在生成 ${ROLE_NAMES[role]} (${role}) 版本...`);
|
|
126
|
+
|
|
127
|
+
const allowedTools = new Set(ROLE_PERMISSIONS[role]);
|
|
128
|
+
console.log(` 允许的工具: ${Array.from(allowedTools).join(', ')}`);
|
|
129
|
+
|
|
130
|
+
// 提取所有工具块
|
|
131
|
+
const toolBlocks = extractToolBlocks(indexContent);
|
|
132
|
+
console.log(` 总工具数: ${toolBlocks.length}`);
|
|
133
|
+
|
|
134
|
+
// 过滤出允许的工具
|
|
135
|
+
const allowedBlocks = toolBlocks.filter(block => allowedTools.has(block.toolName));
|
|
136
|
+
console.log(` ${ROLE_NAMES[role]}可用工具数: ${allowedBlocks.length}`);
|
|
137
|
+
|
|
138
|
+
// 构建新文件内容
|
|
139
|
+
const lines = indexContent.split('\n');
|
|
140
|
+
const outputLines = [];
|
|
141
|
+
const includedLines = new Set();
|
|
142
|
+
|
|
143
|
+
// 标记所有要包含的行
|
|
144
|
+
allowedBlocks.forEach(block => {
|
|
145
|
+
for (let i = block.startLine; i <= block.endLine; i++) {
|
|
146
|
+
includedLines.add(i);
|
|
147
|
+
}
|
|
148
|
+
// 如果前一行是注释,也包含进来
|
|
149
|
+
if (block.startLine > 0 && lines[block.startLine - 1].trim().startsWith('//')) {
|
|
150
|
+
includedLines.add(block.startLine - 1);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// 找到第一个 server.tool 的位置
|
|
155
|
+
let firstToolLine = toolBlocks.length > 0 ? toolBlocks[0].startLine : lines.length;
|
|
156
|
+
|
|
157
|
+
// 输出文件头部(到第一个工具之前)
|
|
158
|
+
for (let i = 0; i < firstToolLine; i++) {
|
|
159
|
+
outputLines.push(lines[i]);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 更新服务器名称和版本
|
|
163
|
+
const headerContent = outputLines.join('\n');
|
|
164
|
+
let updatedHeader = headerContent
|
|
165
|
+
.replace(/name: "Zentao API"/, `name: "Zentao API (${ROLE_NAMES[role]})"`)
|
|
166
|
+
.replace(/version: "1\.16\.0"/, `version: "1.17.0"`);
|
|
167
|
+
|
|
168
|
+
// 输出更新后的头部
|
|
169
|
+
const finalLines = updatedHeader.split('\n');
|
|
170
|
+
|
|
171
|
+
// 添加所有允许的工具块
|
|
172
|
+
let lastEndLine = firstToolLine - 1;
|
|
173
|
+
allowedBlocks.forEach((block, index) => {
|
|
174
|
+
// 添加空行分隔(如果需要)
|
|
175
|
+
if (block.startLine > lastEndLine + 1) {
|
|
176
|
+
finalLines.push('');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 添加工具块
|
|
180
|
+
for (let i = block.startLine; i <= block.endLine; i++) {
|
|
181
|
+
finalLines.push(lines[i]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
lastEndLine = block.endLine;
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// 添加文件尾部(服务器启动代码)
|
|
188
|
+
const lastToolBlock = toolBlocks[toolBlocks.length - 1];
|
|
189
|
+
if (lastToolBlock) {
|
|
190
|
+
for (let i = lastToolBlock.endLine + 1; i < lines.length; i++) {
|
|
191
|
+
finalLines.push(lines[i]);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 写入文件
|
|
196
|
+
const output = finalLines.join('\n');
|
|
197
|
+
const outputPath = path.join(__dirname, '..', 'src', `index-${role}.ts`);
|
|
198
|
+
fs.writeFileSync(outputPath, output, 'utf8');
|
|
199
|
+
|
|
200
|
+
console.log(` ✓ 已生成: ${outputPath}`);
|
|
201
|
+
|
|
202
|
+
// 统计文件大小
|
|
203
|
+
const stats = fs.statSync(outputPath);
|
|
204
|
+
const originalStats = fs.statSync(indexPath);
|
|
205
|
+
const reduction = ((1 - stats.size / originalStats.size) * 100).toFixed(1);
|
|
206
|
+
console.log(` 文件大小: ${(stats.size / 1024).toFixed(1)} KB (原始: ${(originalStats.size / 1024).toFixed(1)} KB, 减少 ${reduction}%)`);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
console.log('\n✓ 所有角色版本生成完成!');
|
|
210
|
+
console.log('\n下一步:');
|
|
211
|
+
console.log('1. 运行 npx tsc 编译所有版本');
|
|
212
|
+
console.log('2. 配置 package.json 的构建脚本');
|
|
213
|
+
console.log('3. 测试各个版本');
|