@catchmexz/fedin-vibe-mcp-server 0.1.1 → 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/dist/common/miniprogram-utils.js +57 -0
- package/dist/common/supabase-utils.js +59 -0
- package/dist/common/types.js +2 -26
- package/dist/index.js +14 -3
- package/dist/operations/codeup/files.js +45 -7
- package/dist/operations/codeup/repositories.js +0 -9
- package/dist/operations/miniprogram/miniprogram.js +156 -0
- package/dist/operations/miniprogram/types.js +55 -0
- package/dist/tool-handlers/code-management.js +4 -2
- package/dist/tool-handlers/index.js +2 -26
- package/dist/tool-handlers/miniprogram.js +109 -0
- package/dist/tool-registry/code-management.js +0 -20
- package/dist/tool-registry/index.js +3 -1
- package/dist/tool-registry/miniprogram.js +24 -0
- package/package.json +1 -2
- package/LICENSE +0 -202
- package/dist/common/modularTemplates.js +0 -483
- package/dist/common/pipelineTemplates.js +0 -19
- package/dist/operations/appstack/appOrchestrations.js +0 -235
- package/dist/operations/appstack/appTags.js +0 -147
- package/dist/operations/appstack/appTemplates.js +0 -67
- package/dist/operations/appstack/applications.js +0 -154
- package/dist/operations/appstack/changeOrders.js +0 -293
- package/dist/operations/appstack/changeRequests.js +0 -263
- package/dist/operations/appstack/deploymentResources.js +0 -265
- package/dist/operations/appstack/globalVars.js +0 -200
- package/dist/operations/appstack/releaseWorkflows.js +0 -178
- package/dist/operations/appstack/variableGroups.js +0 -216
- package/dist/operations/flow/hostGroup.js +0 -48
- package/dist/operations/flow/pipeline.js +0 -530
- package/dist/operations/flow/pipelineJob.js +0 -113
- package/dist/operations/flow/serviceConnection.js +0 -23
- package/dist/operations/flow/types.js +0 -377
- package/dist/operations/git/git-repository.js +0 -334
- package/dist/operations/git/index.js +0 -210
- package/dist/operations/packages/artifacts.js +0 -64
- package/dist/operations/packages/repositories.js +0 -35
- package/dist/operations/packages/types.js +0 -56
- package/dist/operations/projex/project.js +0 -206
- package/dist/operations/projex/sprint.js +0 -90
- package/dist/operations/projex/types.js +0 -390
- package/dist/operations/projex/workitem.js +0 -452
- package/dist/tool-handlers/appstack-change-orders.js +0 -55
- package/dist/tool-handlers/appstack-change-requests.js +0 -49
- package/dist/tool-handlers/appstack-deployment-resources.js +0 -43
- package/dist/tool-handlers/appstack-global-vars.js +0 -43
- package/dist/tool-handlers/appstack-orchestrations.js +0 -49
- package/dist/tool-handlers/appstack-tags.js +0 -43
- package/dist/tool-handlers/appstack-templates.js +0 -19
- package/dist/tool-handlers/appstack-variable-groups.js +0 -55
- package/dist/tool-handlers/appstack.js +0 -37
- package/dist/tool-handlers/git/branch-operations.js +0 -1
- package/dist/tool-handlers/git/clone-repository.js +0 -36
- package/dist/tool-handlers/git/create-branch.js +0 -26
- package/dist/tool-handlers/git/get-repository-status.js +0 -33
- package/dist/tool-handlers/git/pull-repository.js +0 -27
- package/dist/tool-handlers/git/push-repository.js +0 -37
- package/dist/tool-handlers/git/switch-branch.js +0 -25
- package/dist/tool-handlers/packages.js +0 -32
- package/dist/tool-handlers/pipeline.js +0 -272
- package/dist/tool-handlers/project-management.js +0 -152
- package/dist/tool-handlers/service-connections.js +0 -16
- package/dist/tool-registry/appstack-change-orders.js +0 -40
- package/dist/tool-registry/appstack-change-requests.js +0 -35
- package/dist/tool-registry/appstack-deployment-resources.js +0 -30
- package/dist/tool-registry/appstack-global-vars.js +0 -30
- package/dist/tool-registry/appstack-orchestrations.js +0 -35
- package/dist/tool-registry/appstack-tags.js +0 -30
- package/dist/tool-registry/appstack-templates.js +0 -10
- package/dist/tool-registry/appstack-variable-groups.js +0 -40
- package/dist/tool-registry/appstack.js +0 -25
- package/dist/tool-registry/git-repository.js +0 -41
- package/dist/tool-registry/packages.js +0 -21
- package/dist/tool-registry/pipeline.js +0 -157
- package/dist/tool-registry/project-management.js +0 -108
- package/dist/tool-registry/service-connections.js +0 -10
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 小程序相关的请求工具函数
|
|
3
|
+
*/
|
|
4
|
+
const MINIPROGRAM_API_BASE_URL = "https://backend.api.fedin.cn/api";
|
|
5
|
+
// API端点配置
|
|
6
|
+
export const MINIPROGRAM_ENDPOINTS = {
|
|
7
|
+
getPreAuthKey: '/wechatcomponent/get_pre_auth_key',
|
|
8
|
+
queryAuthStatus: '/wechatcomponent/auth/status',
|
|
9
|
+
queryAuthInfo: '/wechatcomponent/auth/info',
|
|
10
|
+
submitCode: '/wechatcomponent/submit/code',
|
|
11
|
+
auditStatus: '/wechatcomponent/audit/status'
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* 小程序API请求函数
|
|
15
|
+
* @param endpoint API端点
|
|
16
|
+
* @param options 请求选项
|
|
17
|
+
* @returns 响应数据
|
|
18
|
+
*/
|
|
19
|
+
export async function miniprogramRequest(endpoint, options = {}) {
|
|
20
|
+
const url = `${MINIPROGRAM_API_BASE_URL}${endpoint}`;
|
|
21
|
+
const requestHeaders = {
|
|
22
|
+
"Accept": "application/json",
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
...options.headers,
|
|
25
|
+
};
|
|
26
|
+
// console.info(`[MINIPROGRAM] Request: ${options.method || 'GET'} ${url}`);
|
|
27
|
+
const response = await fetch(url, {
|
|
28
|
+
method: options.method || "GET",
|
|
29
|
+
headers: requestHeaders,
|
|
30
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
31
|
+
});
|
|
32
|
+
const responseBody = await response.json();
|
|
33
|
+
// console.info(`[MINIPROGRAM] Response status: ${response.status}, code: ${responseBody.code}`);
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new Error(`HTTP ${response.status}: ${responseBody.message || 'Request failed'}`);
|
|
36
|
+
}
|
|
37
|
+
// 检查业务状态码
|
|
38
|
+
if (responseBody.code !== 200) {
|
|
39
|
+
throw new Error(`API Error ${responseBody.code}: ${responseBody.message || 'Unknown error'}`);
|
|
40
|
+
}
|
|
41
|
+
return responseBody.data;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 构建带查询参数的端点路径
|
|
45
|
+
* @param endpoint 端点
|
|
46
|
+
* @param params 查询参数
|
|
47
|
+
* @returns 带查询参数的端点路径
|
|
48
|
+
*/
|
|
49
|
+
export function buildMiniprogramUrl(endpoint, params) {
|
|
50
|
+
const url = new URL(`http://dummy.com${endpoint}`); // 使用dummy域名只是为了构建查询参数
|
|
51
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
52
|
+
if (value !== undefined) {
|
|
53
|
+
url.searchParams.append(key, value.toString());
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return url.pathname + url.search; // 只返回路径和查询参数,不包含域名
|
|
57
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase 相关的工具函数
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 根据 PAT 从 Supabase 获取项目信息
|
|
6
|
+
* @param pat Personal Access Token
|
|
7
|
+
* @returns 项目信息
|
|
8
|
+
*/
|
|
9
|
+
export async function getProjectInfoWithPat(pat) {
|
|
10
|
+
const query = `
|
|
11
|
+
SELECT
|
|
12
|
+
ch.id as project_id,
|
|
13
|
+
ch.mini_app_id
|
|
14
|
+
FROM
|
|
15
|
+
schema_dev.chat_history AS ch
|
|
16
|
+
WHERE
|
|
17
|
+
ch.pat = '${pat}'
|
|
18
|
+
`;
|
|
19
|
+
try {
|
|
20
|
+
const response = await fetch('https://dev.fedin.cn/api/supabase/query', {
|
|
21
|
+
method: "post",
|
|
22
|
+
body: JSON.stringify({
|
|
23
|
+
query
|
|
24
|
+
}),
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
if (data.length > 0) {
|
|
31
|
+
return {
|
|
32
|
+
projectId: data[0].project_id,
|
|
33
|
+
miniappId: data[0].mini_app_id
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new Error("PAT密钥无效:未找到对应的项目信息");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error("获取项目信息失败:" + (error instanceof Error ? error.message : String(error)));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 从命令行参数中获取 PAT
|
|
46
|
+
* @returns PAT 字符串
|
|
47
|
+
*/
|
|
48
|
+
export function getPATFromArgs() {
|
|
49
|
+
let pat = "";
|
|
50
|
+
process.argv.forEach(arg => {
|
|
51
|
+
if (arg.includes("--project-pat")) {
|
|
52
|
+
pat = arg.split("=")?.[1];
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (!pat) {
|
|
56
|
+
throw new Error("缺少项目访问令牌 project-pat");
|
|
57
|
+
}
|
|
58
|
+
return pat;
|
|
59
|
+
}
|
package/dist/common/types.js
CHANGED
|
@@ -14,29 +14,5 @@ GetCompareSchema,
|
|
|
14
14
|
GetChangeRequestSchema, ListChangeRequestsSchema, CreateChangeRequestSchema, ListChangeRequestPatchSetsSchema,
|
|
15
15
|
// Change request comment schemas
|
|
16
16
|
CreateChangeRequestCommentSchema, ListChangeRequestCommentsSchema } from "../operations/codeup/types.js";
|
|
17
|
-
//
|
|
18
|
-
export {
|
|
19
|
-
// Project schemas
|
|
20
|
-
GetProjectSchema, SearchProjectsSchema,
|
|
21
|
-
// Sprint schemas
|
|
22
|
-
GetSprintSchema, ListSprintsSchema, CreateSprintSchema, UpdateSprintSchema,
|
|
23
|
-
// Work item schemas
|
|
24
|
-
GetWorkItemSchema, CreateWorkItemSchema, SearchWorkitemsSchema, UpdateWorkItemSchema,
|
|
25
|
-
// Work item type schemas
|
|
26
|
-
ListAllWorkItemTypesSchema, ListWorkItemTypesSchema, GetWorkItemTypeSchema, ListWorkItemRelationWorkItemTypesSchema, GetWorkItemTypeFieldConfigSchema, GetWorkItemWorkflowSchema,
|
|
27
|
-
// Work item comment schemas
|
|
28
|
-
ListWorkItemCommentsSchema, CreateWorkItemCommentSchema } from "../operations/projex/types.js";
|
|
29
|
-
// Flow types
|
|
30
|
-
export {
|
|
31
|
-
// Pipeline schemas
|
|
32
|
-
GetPipelineSchema, ListPipelinesSchema, CreatePipelineFromDescriptionSchema, CreatePipelineRunSchema, GetLatestPipelineRunSchema, GetPipelineRunSchema, ListPipelineRunsSchema, UpdatePipelineSchema,
|
|
33
|
-
// Pipeline job schemas
|
|
34
|
-
ListPipelineJobsByCategorySchema, ListPipelineJobHistorysSchema, ExecutePipelineJobRunSchema, GetPipelineJobRunLogSchema,
|
|
35
|
-
// Service connection schemas
|
|
36
|
-
ListServiceConnectionsSchema } from "../operations/flow/types.js";
|
|
37
|
-
// Packages types
|
|
38
|
-
export {
|
|
39
|
-
// Package repository schemas
|
|
40
|
-
ListPackageRepositoriesSchema,
|
|
41
|
-
// Artifact schemas
|
|
42
|
-
ListArtifactsSchema, GetArtifactSchema } from "../operations/packages/types.js";
|
|
17
|
+
// Miniprogram types
|
|
18
|
+
export { GetMiniprogramBindingInfoSchema, GetMiniprogramAuthUrlSchema, SubmitMiniprogramDeploymentSchema, GetMiniprogramAuditStatusSchema, MiniprogramBindingInfoSchema, MiniprogramAuthUrlSchema, MiniprogramDeploymentResponseSchema, MiniprogramAuditStatusSchema } from "../operations/miniprogram/types.js";
|
package/dist/index.js
CHANGED
|
@@ -68,7 +68,9 @@ async function getRepositoryIdWithPat(pat) {
|
|
|
68
68
|
const query = `
|
|
69
69
|
SELECT
|
|
70
70
|
c.*,
|
|
71
|
-
ch.pat
|
|
71
|
+
ch.pat,
|
|
72
|
+
ch.id as project_id,
|
|
73
|
+
ch.mini_app_id
|
|
72
74
|
FROM
|
|
73
75
|
schema_dev.codeup AS c
|
|
74
76
|
INNER JOIN
|
|
@@ -90,7 +92,11 @@ async function getRepositoryIdWithPat(pat) {
|
|
|
90
92
|
});
|
|
91
93
|
const data = await response.json();
|
|
92
94
|
if (data.length > 0) {
|
|
93
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
repositoryId: data[0].repositoryId,
|
|
97
|
+
projectId: data[0].project_id,
|
|
98
|
+
miniappId: data[0].mini_app_id
|
|
99
|
+
};
|
|
94
100
|
}
|
|
95
101
|
else {
|
|
96
102
|
throw new Error("pat密钥无效:未找到对应的repositoryId");
|
|
@@ -119,11 +125,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
119
125
|
if (!pat) {
|
|
120
126
|
throw new Error("缺少项目访问令牌project-pat");
|
|
121
127
|
}
|
|
122
|
-
const repositoryId = await getRepositoryIdWithPat(pat);
|
|
128
|
+
const { repositoryId, projectId, miniappId } = await getRepositoryIdWithPat(pat);
|
|
123
129
|
if (!repositoryId) {
|
|
124
130
|
throw new Error("获取repositoryId失败");
|
|
125
131
|
}
|
|
126
132
|
request.params.arguments.repositoryId = repositoryId;
|
|
133
|
+
request.params.arguments.projectId = projectId;
|
|
134
|
+
// 只有当 miniappId 不为 null 时才注入,避免 Zod 验证错误
|
|
135
|
+
if (miniappId) {
|
|
136
|
+
request.params.arguments.miniappId = miniappId;
|
|
137
|
+
}
|
|
127
138
|
// Delegate to our modular tool handler
|
|
128
139
|
return await handleToolRequest(request);
|
|
129
140
|
}
|
|
@@ -248,7 +248,7 @@ export async function createFileFunc(organizationId, repositoryId, filePath, con
|
|
|
248
248
|
});
|
|
249
249
|
return CreateFileResponseSchema.parse(response);
|
|
250
250
|
}
|
|
251
|
-
export async function pushFilesFunc(organizationId, repositoryId, commitMessage, projectPath) {
|
|
251
|
+
export async function pushFilesFunc(organizationId, repositoryId, commitMessage, projectPath, projectId) {
|
|
252
252
|
// 读取 .gitignore 模式
|
|
253
253
|
// const ignorePatterns = readGitignore(projectPath);
|
|
254
254
|
const ignorePatterns = [
|
|
@@ -267,6 +267,21 @@ export async function pushFilesFunc(organizationId, repositoryId, commitMessage,
|
|
|
267
267
|
];
|
|
268
268
|
// 获取所有文件
|
|
269
269
|
const files = getAllFiles(projectPath, ignorePatterns);
|
|
270
|
+
// 检测项目类型
|
|
271
|
+
let projectType = "default"; // 默认值
|
|
272
|
+
// 检查是否存在 Next.js 配置文件
|
|
273
|
+
const hasNextConfig = files.some(file => file.path === 'next.config.js' ||
|
|
274
|
+
file.path === 'next.config.ts');
|
|
275
|
+
// 检查是否存在 Vite 配置文件
|
|
276
|
+
const hasViteConfig = files.some(file => file.path === 'vite.config.js' ||
|
|
277
|
+
file.path === 'vite.config.ts');
|
|
278
|
+
// 根据配置文件设置项目类型
|
|
279
|
+
if (hasNextConfig) {
|
|
280
|
+
projectType = "fc";
|
|
281
|
+
}
|
|
282
|
+
else if (hasViteConfig) {
|
|
283
|
+
projectType = "oss";
|
|
284
|
+
}
|
|
270
285
|
const remoteFileList = await listFilesFunc(organizationId, repositoryId, undefined, "master", "RECURSIVE");
|
|
271
286
|
const remoteFilePathArr = remoteFileList.map((i) => i.path);
|
|
272
287
|
const shouldCreateFiles = files.filter((file) => !remoteFilePathArr.includes(file.path));
|
|
@@ -308,13 +323,36 @@ export async function pushFilesFunc(organizationId, repositoryId, commitMessage,
|
|
|
308
323
|
deleteFileErrors.push(error.message);
|
|
309
324
|
}
|
|
310
325
|
}
|
|
326
|
+
const pipelineResponse = await fetch('https://ai.fedin.cn/api/alicloud/create-pipeline-run', {
|
|
327
|
+
method: "POST",
|
|
328
|
+
body: JSON.stringify({
|
|
329
|
+
name: projectId,
|
|
330
|
+
projectId: projectId,
|
|
331
|
+
repoUrl: `https://codeup.aliyun.com/ctrod/fedin-ai-project/${projectId}.git`,
|
|
332
|
+
projectType,
|
|
333
|
+
organizationId: organizationId,
|
|
334
|
+
token: process.env.YUNXIAO_ACCESS_TOKEN
|
|
335
|
+
}),
|
|
336
|
+
headers: {
|
|
337
|
+
"Content-Type": "application/json",
|
|
338
|
+
token: "fedin_ac_9x7k2m8p4w6q1z5n3v7b9c2e8r4t6"
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
const pipelineResult = await pipelineResponse.json();
|
|
342
|
+
let onlineUrl;
|
|
343
|
+
if (pipelineResult.success && pipelineResult.data?.onlineUrl) {
|
|
344
|
+
onlineUrl = pipelineResult.data.onlineUrl;
|
|
345
|
+
}
|
|
311
346
|
return {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
347
|
+
pushResult: {
|
|
348
|
+
createFilesSuccess,
|
|
349
|
+
createFileErrors,
|
|
350
|
+
updateFilesSuccess,
|
|
351
|
+
updateFileErrors,
|
|
352
|
+
deleteFilesSuccess,
|
|
353
|
+
deleteFileErrors,
|
|
354
|
+
},
|
|
355
|
+
onlineUrl: onlineUrl || ''
|
|
318
356
|
};
|
|
319
357
|
}
|
|
320
358
|
/**
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 代码库(Repository)相关操作
|
|
3
|
-
*
|
|
4
|
-
* 概念说明:
|
|
5
|
-
* - 代码库(Repository)是云效平台中的代码管理单元,属于CodeUp产品
|
|
6
|
-
* - 代码库与项目(Project)是不同的概念,项目属于项目管理领域
|
|
7
|
-
* - 代码库用于存储和管理源代码,而项目用于管理工作项、迭代等
|
|
8
|
-
* - 请勿混淆这两个概念,它们是不同的资源类型
|
|
9
|
-
*/
|
|
10
1
|
import { yunxiaoRequest, buildUrl, handleRepositoryIdEncoding } from "../../common/utils.js";
|
|
11
2
|
import { RepositorySchema } from "./types.js";
|
|
12
3
|
/**
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { miniprogramRequest, buildMiniprogramUrl, MINIPROGRAM_ENDPOINTS } from "../../common/miniprogram-utils.js";
|
|
2
|
+
import { MiniprogramBindingInfoSchema, MiniprogramAuthUrlSchema, MiniprogramDeploymentResponseSchema, MiniprogramAuditStatusSchema } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* 查询小程序绑定信息(简化版:直接使用注入的项目信息)
|
|
5
|
+
* @param projectId 项目ID(由系统自动注入)
|
|
6
|
+
* @param miniappId 小程序ID(由系统自动注入,可选)
|
|
7
|
+
*/
|
|
8
|
+
export async function getMiniprogramBindingInfoFunc(projectId, miniappId) {
|
|
9
|
+
try {
|
|
10
|
+
console.error(`[MINIPROGRAM] 查询项目 ${projectId} 的小程序绑定信息`);
|
|
11
|
+
// 直接尝试查询授权信息
|
|
12
|
+
try {
|
|
13
|
+
const url = buildMiniprogramUrl(MINIPROGRAM_ENDPOINTS.queryAuthInfo, { projectId });
|
|
14
|
+
const authInfo = await miniprogramRequest(url, {
|
|
15
|
+
method: "GET"
|
|
16
|
+
});
|
|
17
|
+
// 如果有返回数据,说明授权成功
|
|
18
|
+
console.error(`[MINIPROGRAM] 授权信息查询成功,小程序已绑定`);
|
|
19
|
+
// 解析授权方信息
|
|
20
|
+
let authorizerInfo = null;
|
|
21
|
+
try {
|
|
22
|
+
if (authInfo.authorizerInfo) {
|
|
23
|
+
authorizerInfo = JSON.parse(authInfo.authorizerInfo);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
console.error('解析授权方信息失败');
|
|
28
|
+
}
|
|
29
|
+
const bindingInfo = {
|
|
30
|
+
projectId: projectId,
|
|
31
|
+
appId: authInfo.authorizerAppid,
|
|
32
|
+
bindingStatus: "bound",
|
|
33
|
+
bindingTime: authInfo.authFinishTime || undefined,
|
|
34
|
+
lastUpdateTime: authInfo.dateCreated,
|
|
35
|
+
principalName: authInfo.principalName, // 添加主体名称
|
|
36
|
+
authorizerInfo: authorizerInfo ? {
|
|
37
|
+
nickName: authorizerInfo.nickName,
|
|
38
|
+
headImg: authorizerInfo.headImg,
|
|
39
|
+
verifyStatus: authorizerInfo.verifyTypeInfo === 0 ? '已认证' : '未认证!', // 添加认证状态
|
|
40
|
+
serviceTypeInfo: authorizerInfo.serviceTypeInfo ? {
|
|
41
|
+
id: authorizerInfo.serviceTypeInfo.id
|
|
42
|
+
} : undefined,
|
|
43
|
+
verifyTypeInfo: authorizerInfo.verifyTypeInfo !== undefined ? {
|
|
44
|
+
id: authorizerInfo.verifyTypeInfo
|
|
45
|
+
} : undefined
|
|
46
|
+
} : undefined
|
|
47
|
+
};
|
|
48
|
+
return MiniprogramBindingInfoSchema.parse(bindingInfo);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// 如果查询授权信息失败,说明需要授权,生成授权链接
|
|
52
|
+
console.error(`[MINIPROGRAM] 授权信息查询失败,需要获取授权链接`);
|
|
53
|
+
try {
|
|
54
|
+
const authUrl = await miniprogramRequest(MINIPROGRAM_ENDPOINTS.getPreAuthKey, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
body: {
|
|
57
|
+
projectId: projectId
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const unboundInfo = {
|
|
61
|
+
projectId: projectId,
|
|
62
|
+
bindingStatus: "unbound",
|
|
63
|
+
authUrl: authUrl
|
|
64
|
+
};
|
|
65
|
+
return MiniprogramBindingInfoSchema.parse(unboundInfo);
|
|
66
|
+
}
|
|
67
|
+
catch (authError) {
|
|
68
|
+
console.error(`[MINIPROGRAM] 生成授权链接失败`);
|
|
69
|
+
const unboundInfo = {
|
|
70
|
+
projectId: projectId,
|
|
71
|
+
bindingStatus: "unbound"
|
|
72
|
+
};
|
|
73
|
+
return MiniprogramBindingInfoSchema.parse(unboundInfo);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error(`[MINIPROGRAM] 查询绑定信息失败`);
|
|
79
|
+
throw new Error(`查询小程序绑定信息失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 获取小程序授权地址
|
|
84
|
+
* @param projectId 项目ID
|
|
85
|
+
*/
|
|
86
|
+
export async function getMiniprogramAuthUrlFunc(projectId) {
|
|
87
|
+
const authUrl = await miniprogramRequest(MINIPROGRAM_ENDPOINTS.getPreAuthKey, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
body: {
|
|
90
|
+
projectId: projectId
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// 构造返回数据(基于前端逻辑推断)
|
|
94
|
+
const result = {
|
|
95
|
+
authUrl: authUrl,
|
|
96
|
+
preAuthCode: "generated_pre_auth_code", // 实际应该从响应中获取
|
|
97
|
+
expiresIn: 600, // 10分钟过期
|
|
98
|
+
};
|
|
99
|
+
return MiniprogramAuthUrlSchema.parse(result);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 提交小程序代码部署
|
|
103
|
+
* @param projectId 项目ID
|
|
104
|
+
* @param appId 小程序AppID(由系统注入)
|
|
105
|
+
* @param version 版本号
|
|
106
|
+
* @param description 版本描述
|
|
107
|
+
* @param templateId 模板ID
|
|
108
|
+
* @param extJson 第三方平台自定义数据
|
|
109
|
+
* @param userVersion 代码版本号
|
|
110
|
+
* @param userDesc 代码描述
|
|
111
|
+
* @param autoSubmitAudit 是否自动提交审核
|
|
112
|
+
*/
|
|
113
|
+
export async function submitMiniprogramDeploymentFunc(appId, version) {
|
|
114
|
+
if (!appId) {
|
|
115
|
+
throw new Error("小程序AppID不存在,无法部署");
|
|
116
|
+
}
|
|
117
|
+
const deployResult = await miniprogramRequest(MINIPROGRAM_ENDPOINTS.submitCode, {
|
|
118
|
+
method: "POST",
|
|
119
|
+
body: {
|
|
120
|
+
appId: appId,
|
|
121
|
+
version: version
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
const result = {
|
|
125
|
+
success: true,
|
|
126
|
+
message: `部署提交成功,状态:${deployResult.status}`,
|
|
127
|
+
version: version
|
|
128
|
+
};
|
|
129
|
+
return MiniprogramDeploymentResponseSchema.parse(result);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 获取小程序代码审核状态
|
|
133
|
+
* @param projectId 项目ID
|
|
134
|
+
* @param appId 小程序AppID(由系统注入)
|
|
135
|
+
* @param auditId 审核ID(可选)
|
|
136
|
+
*/
|
|
137
|
+
export async function getMiniprogramAuditStatusFunc(appId) {
|
|
138
|
+
if (!appId) {
|
|
139
|
+
throw new Error("小程序AppID不存在,无法查询审核状态");
|
|
140
|
+
}
|
|
141
|
+
const auditResult = await miniprogramRequest(MINIPROGRAM_ENDPOINTS.auditStatus, {
|
|
142
|
+
method: "POST",
|
|
143
|
+
body: {
|
|
144
|
+
appId: appId
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// 直接使用API返回的状态值,不进行映射
|
|
148
|
+
const validStatuses = ["RELEASED", "CHECK_FAILED", "CHECKING", "CANCEL"];
|
|
149
|
+
const status = validStatuses.includes(auditResult.status) ? auditResult.status : "CHECKING";
|
|
150
|
+
const result = {
|
|
151
|
+
status: status,
|
|
152
|
+
reason: auditResult.reason || undefined,
|
|
153
|
+
testQrCode: auditResult.testQrCode || undefined
|
|
154
|
+
};
|
|
155
|
+
return MiniprogramAuditStatusSchema.parse(result);
|
|
156
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// 小程序绑定信息相关Schema
|
|
3
|
+
export const MiniprogramBindingInfoSchema = z.object({
|
|
4
|
+
projectId: z.string().describe("项目ID"),
|
|
5
|
+
appId: z.string().optional().describe("小程序AppID"),
|
|
6
|
+
appSecret: z.string().optional().describe("小程序AppSecret"),
|
|
7
|
+
bindingStatus: z.enum(["unbound", "bound"]).describe("绑定状态:unbound-未绑定,bound-已绑定"),
|
|
8
|
+
bindingTime: z.string().optional().describe("绑定时间"),
|
|
9
|
+
lastUpdateTime: z.string().optional().describe("最后更新时间"),
|
|
10
|
+
principalName: z.string().optional().describe("主体名称"),
|
|
11
|
+
authUrl: z.string().optional().describe("授权链接(当状态为unbound时提供)"),
|
|
12
|
+
authorizerInfo: z.object({
|
|
13
|
+
nickName: z.string().optional().describe("小程序昵称"),
|
|
14
|
+
headImg: z.string().optional().describe("小程序头像"),
|
|
15
|
+
verifyStatus: z.string().optional().describe("微信认证状态:已认证/未认证!"),
|
|
16
|
+
serviceTypeInfo: z.object({
|
|
17
|
+
id: z.number().optional().describe("服务类型ID")
|
|
18
|
+
}).optional().describe("服务类型信息"),
|
|
19
|
+
verifyTypeInfo: z.object({
|
|
20
|
+
id: z.number().optional().describe("认证类型ID")
|
|
21
|
+
}).optional().describe("认证类型信息")
|
|
22
|
+
}).optional().describe("授权方信息")
|
|
23
|
+
});
|
|
24
|
+
// 小程序授权地址相关Schema
|
|
25
|
+
export const MiniprogramAuthUrlSchema = z.object({
|
|
26
|
+
authUrl: z.string().url().describe("授权地址"),
|
|
27
|
+
preAuthCode: z.string().describe("预授权码"),
|
|
28
|
+
expiresIn: z.number().describe("过期时间(秒)"),
|
|
29
|
+
});
|
|
30
|
+
export const MiniprogramDeploymentResponseSchema = z.object({
|
|
31
|
+
success: z.boolean().describe("提交是否成功"),
|
|
32
|
+
message: z.string().describe("返回消息"),
|
|
33
|
+
taskId: z.string().optional().describe("任务ID"),
|
|
34
|
+
version: z.string().optional().describe("版本号")
|
|
35
|
+
});
|
|
36
|
+
// 小程序审核状态相关Schema
|
|
37
|
+
export const MiniprogramAuditStatusSchema = z.object({
|
|
38
|
+
status: z.enum(["RELEASED", "CHECK_FAILED", "CHECKING", "CANCEL"]).describe("审核状态:RELEASED-已发布,CHECK_FAILED-审核失败,CHECKING-审核中,CANCEL-已取消"),
|
|
39
|
+
reason: z.string().nullable().optional().describe("审核结果说明"),
|
|
40
|
+
testQrCode: z.string().nullable().optional().describe("体验版二维码URL链接,可复制到浏览器查看或在微信中扫描")
|
|
41
|
+
});
|
|
42
|
+
// 请求参数Schema定义
|
|
43
|
+
export const GetMiniprogramBindingInfoSchema = z.object({
|
|
44
|
+
// 无需任何参数,直接从PAT获取项目信息
|
|
45
|
+
});
|
|
46
|
+
export const GetMiniprogramAuthUrlSchema = z.object({
|
|
47
|
+
// 无需任何参数,直接从PAT获取项目信息
|
|
48
|
+
});
|
|
49
|
+
// 小程序部署提交相关Schema
|
|
50
|
+
export const SubmitMiniprogramDeploymentSchema = z.object({
|
|
51
|
+
version: z.string().describe("版本号,格式如:1.0.0(必填,用户必须指定)"),
|
|
52
|
+
});
|
|
53
|
+
export const GetMiniprogramAuditStatusSchema = z.object({
|
|
54
|
+
auditId: z.string().optional().describe("审核ID,如不提供则查询最新的审核状态")
|
|
55
|
+
});
|
|
@@ -53,9 +53,11 @@ export const handleCodeManagementTools = async (request) => {
|
|
|
53
53
|
}
|
|
54
54
|
case "push_files": {
|
|
55
55
|
const args = request.params.arguments;
|
|
56
|
-
const result = await files.pushFilesFunc(args.organizationId, args.repositoryId, args.commitMessage, args.projectPath);
|
|
56
|
+
const result = await files.pushFilesFunc(args.organizationId, args.repositoryId, args.commitMessage, args.projectPath, args.projectId);
|
|
57
|
+
const returnText = `项目部署地址:${result.onlineUrl}\n文件推送结果:${JSON.stringify(result.pushResult)}
|
|
58
|
+
`;
|
|
57
59
|
return {
|
|
58
|
-
content: [{ type: "text", text:
|
|
60
|
+
content: [{ type: "text", text: returnText }]
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
63
|
case "pull_files": {
|
|
@@ -1,36 +1,12 @@
|
|
|
1
1
|
import { handleCodeManagementTools } from './code-management.js';
|
|
2
2
|
import { handleOrganizationTools } from './organization.js';
|
|
3
|
-
import {
|
|
4
|
-
import { handlePipelineTools } from './pipeline.js';
|
|
5
|
-
import { handlePackageManagementTools } from './packages.js';
|
|
6
|
-
import { handleServiceConnectionTools } from './service-connections.js';
|
|
7
|
-
import { handleAppStackTools } from './appstack.js';
|
|
8
|
-
import { handleAppStackTagTools } from './appstack-tags.js';
|
|
9
|
-
import { handleAppStackTemplateTools } from './appstack-templates.js';
|
|
10
|
-
import { handleAppStackGlobalVarTools } from './appstack-global-vars.js';
|
|
11
|
-
import { handleAppStackVariableGroupTools } from './appstack-variable-groups.js';
|
|
12
|
-
import { handleAppStackOrchestrationTools } from './appstack-orchestrations.js';
|
|
13
|
-
import { handleAppStackChangeRequestTools } from './appstack-change-requests.js';
|
|
14
|
-
import { handleAppStackDeploymentResourceTools } from './appstack-deployment-resources.js';
|
|
15
|
-
import { handleAppStackChangeOrderTools } from './appstack-change-orders.js';
|
|
3
|
+
import { handleMiniprogramTools } from './miniprogram.js';
|
|
16
4
|
export const handleToolRequest = async (request) => {
|
|
17
5
|
// Try each handler in sequence until one returns a result
|
|
18
6
|
const handlers = [
|
|
19
7
|
handleCodeManagementTools,
|
|
20
8
|
handleOrganizationTools,
|
|
21
|
-
|
|
22
|
-
handlePipelineTools,
|
|
23
|
-
handlePackageManagementTools,
|
|
24
|
-
handleServiceConnectionTools,
|
|
25
|
-
handleAppStackTools,
|
|
26
|
-
handleAppStackTagTools,
|
|
27
|
-
handleAppStackTemplateTools,
|
|
28
|
-
handleAppStackGlobalVarTools,
|
|
29
|
-
handleAppStackVariableGroupTools,
|
|
30
|
-
handleAppStackOrchestrationTools,
|
|
31
|
-
handleAppStackChangeRequestTools,
|
|
32
|
-
handleAppStackDeploymentResourceTools,
|
|
33
|
-
handleAppStackChangeOrderTools
|
|
9
|
+
handleMiniprogramTools
|
|
34
10
|
];
|
|
35
11
|
for (const handler of handlers) {
|
|
36
12
|
const result = await handler(request);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as miniprogram from '../operations/miniprogram/miniprogram.js';
|
|
2
|
+
import * as types from '../common/types.js';
|
|
3
|
+
import { getProjectInfoWithPat, getPATFromArgs } from '../common/supabase-utils.js';
|
|
4
|
+
export const handleMiniprogramTools = async (request) => {
|
|
5
|
+
// 从命令行参数获取PAT,然后查询项目信息
|
|
6
|
+
const pat = getPATFromArgs();
|
|
7
|
+
const { projectId, miniappId } = await getProjectInfoWithPat(pat);
|
|
8
|
+
if (!projectId) {
|
|
9
|
+
throw new Error("MCP异常,无法获取到当前的项目ID。");
|
|
10
|
+
}
|
|
11
|
+
switch (request.params.name) {
|
|
12
|
+
case "get_miniprogram_binding_info": {
|
|
13
|
+
// 如果没有 miniappId,说明还未绑定,自动获取授权URL
|
|
14
|
+
if (!miniappId) {
|
|
15
|
+
const authUrl = await miniprogram.getMiniprogramAuthUrlFunc(projectId);
|
|
16
|
+
const resultText = `小程序未绑定,请使用以下授权链接完成绑定:
|
|
17
|
+
|
|
18
|
+
🔗 授权链接: ${authUrl.authUrl}
|
|
19
|
+
⏰ 有效期: ${authUrl.expiresIn} 秒
|
|
20
|
+
|
|
21
|
+
请复制链接到浏览器中打开,完成小程序授权绑定。`;
|
|
22
|
+
return {
|
|
23
|
+
content: [{ type: "text", text: resultText }]
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// 有 miniappId 时查询绑定信息
|
|
27
|
+
const bindingInfo = await miniprogram.getMiniprogramBindingInfoFunc(projectId, miniappId);
|
|
28
|
+
// 根据绑定状态提供不同的提示信息
|
|
29
|
+
let resultText = `小程序绑定信息:
|
|
30
|
+
${JSON.stringify(bindingInfo, null, 2)}`;
|
|
31
|
+
if (bindingInfo.bindingStatus === "unbound") {
|
|
32
|
+
if (bindingInfo.authUrl) {
|
|
33
|
+
resultText += `
|
|
34
|
+
|
|
35
|
+
🔗 小程序未绑定,请复制以下授权链接到浏览器中打开完成授权:
|
|
36
|
+
${bindingInfo.authUrl}`;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
resultText += `
|
|
40
|
+
|
|
41
|
+
❌ 小程序未绑定,且无法生成授权链接,请检查网络连接或稍后重试。`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (bindingInfo.bindingStatus === "bound") {
|
|
45
|
+
resultText += `
|
|
46
|
+
|
|
47
|
+
✅ 小程序已成功绑定,可以进行部署操作。`;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
content: [{ type: "text", text: resultText }]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
case "get_miniprogram_auth_url": {
|
|
54
|
+
const authUrl = await miniprogram.getMiniprogramAuthUrlFunc(projectId);
|
|
55
|
+
return {
|
|
56
|
+
content: [{ type: "text", text: JSON.stringify(authUrl, null, 2) }]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
case "submit_miniprogram_deployment": {
|
|
60
|
+
const args = types.SubmitMiniprogramDeploymentSchema.parse(request.params.arguments);
|
|
61
|
+
// 确保有AppID才能部署
|
|
62
|
+
if (!miniappId) {
|
|
63
|
+
throw new Error("小程序未绑定,无法部署。请先使用 get_miniprogram_binding_info 工具完成绑定。");
|
|
64
|
+
}
|
|
65
|
+
// 先返回开始提示
|
|
66
|
+
console.log(`🚀 开始提交小程序代码部署...
|
|
67
|
+
版本号: ${args.version}
|
|
68
|
+
预计耗时: 约40秒
|
|
69
|
+
请稍候,正在处理中...`);
|
|
70
|
+
const deploymentResult = await miniprogram.submitMiniprogramDeploymentFunc(miniappId, args.version);
|
|
71
|
+
let resultText = `小程序部署提交结果:\n${JSON.stringify(deploymentResult, null, 2)}`;
|
|
72
|
+
if (deploymentResult.success) {
|
|
73
|
+
resultText += `\n\n已自动提交审核,请使用 get_miniprogram_audit_status 工具查看审核状态。`;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: "text", text: resultText }]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
case "get_miniprogram_audit_status": {
|
|
80
|
+
const args = types.GetMiniprogramAuditStatusSchema.parse(request.params.arguments);
|
|
81
|
+
// 确保有AppID才能查询审核状态
|
|
82
|
+
if (!miniappId) {
|
|
83
|
+
throw new Error("小程序未绑定,无法查询审核状态。请先使用 get_miniprogram_binding_info 工具完成绑定。");
|
|
84
|
+
}
|
|
85
|
+
const auditStatus = await miniprogram.getMiniprogramAuditStatusFunc(miniappId);
|
|
86
|
+
// 格式化审核状态显示
|
|
87
|
+
let resultText = `📊 小程序审核状态查询结果:
|
|
88
|
+
|
|
89
|
+
🔍 审核状态: ${auditStatus.status}`;
|
|
90
|
+
if (auditStatus.reason) {
|
|
91
|
+
resultText += `
|
|
92
|
+
💬 审核说明: ${auditStatus.reason}`;
|
|
93
|
+
}
|
|
94
|
+
if (auditStatus.testQrCode) {
|
|
95
|
+
resultText += `
|
|
96
|
+
|
|
97
|
+
📱 体验版二维码:
|
|
98
|
+
${auditStatus.testQrCode}
|
|
99
|
+
|
|
100
|
+
请复制上述链接到浏览器中查看体验版二维码,或直接在微信中扫描使用。`;
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
content: [{ type: "text", text: resultText }]
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
default:
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
};
|