cloudcc-cli 2.2.5 → 2.2.7
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/.cloudcc-cache.json +38 -0
- package/README.md +1435 -522
- package/bin/cc.js +7 -2
- package/bin/index.js +4 -0
- package/java/com/cloudcc/core/BaseException.java +100 -0
- package/java/com/cloudcc/core/BusiException.java +43 -0
- package/java/com/cloudcc/core/CCService.java +3 -1
- package/java/com/cloudcc/core/StringUtils.java +7 -0
- package/java/com/cloudcc/core/TimeUtil.java +33 -0
- package/java/com/cloudcc/core/UserInfo.java +9 -0
- package/package.json +7 -1
- package/pom.xml +1 -1
- package/skill/BACKEND_CODE.md +114 -0
- package/skill/CLI_CHEATSHEET.md +90 -0
- package/skill/INSTALL_AND_BOOTSTRAP.md +59 -0
- package/skill/OBJECTS_AND_FIELDS.md +120 -0
- package/skill/REQUIREMENTS_BREAKDOWN.md +98 -0
- package/skill/SKILL.md +33 -0
- package/skill/VUE_CUSTOM_COMPONENT.md +50 -0
- package/src/api/backend-sdk-java.md +427 -0
- package/src/api/ccdk-sdk.md +1039 -0
- package/src/application/create.js +114 -0
- package/src/application/get.js +13 -0
- package/src/application/index.js +8 -0
- package/src/classes/doc.js +486 -0
- package/src/classes/index.js +1 -0
- package/src/mcp/cliRunner.js +61 -0
- package/src/mcp/index.js +84 -12
- package/src/mcp/readme.md +6 -3
- package/src/mcp/tools/Application Creator/handler.js +78 -0
- package/src/mcp/tools/Approval/handler.js +34 -151
- package/src/mcp/tools/Class Creator/handler.js +18 -15
- package/src/mcp/tools/Class Detail Retriever/handler.js +8 -9
- package/src/mcp/tools/Class Editor Guide/handler.js +5 -19
- package/src/mcp/tools/Class List Retriever/handler.js +8 -3
- package/src/mcp/tools/Class Publisher/handler.js +7 -9
- package/src/mcp/tools/Class Puller/handler.js +6 -65
- package/src/mcp/tools/Client Script Detail Retriever/handler.js +12 -18
- package/src/mcp/tools/Client Script Editor Guide/handler.js +9 -605
- package/src/mcp/tools/Client Script List Retriever/handler.js +30 -33
- package/src/mcp/tools/Client Script Publisher/handler.js +12 -11
- package/src/mcp/tools/Client Script Puller/handler.js +23 -30
- package/src/mcp/tools/CloudCC Development Overview/handler.js +11 -5
- package/src/mcp/tools/Component Creator/handler.js +12 -11
- package/src/mcp/tools/Component Detail Retriever/handler.js +12 -9
- package/src/mcp/tools/Component Editor Guide/handler.js +5 -22
- package/src/mcp/tools/Component List Retriever/handler.js +21 -18
- package/src/mcp/tools/Component Publisher/handler.js +25 -3
- package/src/mcp/tools/Component Puller/handler.js +13 -16
- package/src/mcp/tools/Dev Environment Creator/handler.js +5 -72
- package/src/mcp/tools/Dev Environment Validator/handler.js +5 -66
- package/src/mcp/tools/Developer Key Setup Guide/handler.js +11 -20
- package/src/mcp/tools/JSP Migrator/handler.js +842 -0
- package/src/mcp/tools/Menu Creator/handler.js +86 -0
- package/src/mcp/tools/Object Creator/handler.js +14 -6
- package/src/mcp/tools/Object Fields Creator/handler.js +9 -10
- package/src/mcp/tools/Object Fields Retriever/handler.js +6 -3
- package/src/mcp/tools/Object List Retriever/handler.js +10 -7
- package/src/mcp/tools/Scheduled Class Creator/handler.js +12 -16
- package/src/mcp/tools/Scheduled Class Detail Retriever/handler.js +7 -9
- package/src/mcp/tools/Scheduled Class List Retriever/handler.js +21 -23
- package/src/mcp/tools/Scheduled Class Publisher/handler.js +7 -9
- package/src/mcp/tools/Scheduled Class Puller/handler.js +6 -70
- package/src/mcp/tools/Trigger Creator/handler.js +12 -20
- package/src/mcp/tools/Trigger Detail Retriever/handler.js +7 -9
- package/src/mcp/tools/Trigger Editor Guide/handler.js +10 -35
- package/src/mcp/tools/Trigger List Retriever/handler.js +12 -4
- package/src/mcp/tools/Trigger Publisher/handler.js +8 -11
- package/src/mcp/tools/Trigger Puller/handler.js +12 -17
- package/src/menu/common.js +16 -0
- package/src/menu/create-object.js +94 -0
- package/src/menu/create-page.js +108 -0
- package/src/menu/create-script.js +108 -0
- package/src/menu/create-site.js +108 -0
- package/src/menu/create.js +54 -0
- package/src/menu/index.js +7 -0
- package/src/plugin/doc.js +801 -0
- package/src/plugin/index.js +1 -0
- package/src/plugin/pull.js +3 -0
- package/src/project/doc.js +378 -0
- package/src/project/index.js +1 -0
- package/src/script/doc.js +259 -0
- package/src/script/index.js +1 -0
- package/src/timer/index.js +1 -0
- package/src/triggers/doc.js +342 -0
- package/src/triggers/index.js +5 -0
- package/target/classes/com/cloudcc/core/BaseException.class +0 -0
- package/target/classes/com/cloudcc/core/BusiException.class +0 -0
- package/target/classes/com/cloudcc/core/CCService.class +0 -0
- package/target/classes/com/cloudcc/core/StringUtils.class +0 -0
- package/target/classes/com/cloudcc/core/TimeUtil.class +0 -0
- package/target/classes/com/cloudcc/core/UserInfo.class +0 -0
- package/template/lib/ccopenapi-0.0.4.jar +0 -0
- package/test/application.cli.test.js +30 -0
- package/test/classes.cli.test.js +121 -0
- package/test/fields.cli.test.js +69 -0
- package/test/mcp.cli.test.js +21 -0
- package/test/menu.cli.test.js +41 -0
- package/test/object.cli.test.js +64 -0
- package/test/plugin.cli.test.js +109 -0
- package/test/script.cli.test.js +101 -0
- package/test/timer.cli.test.js +107 -0
- package/test/trigger.cli.test.js +146 -0
- package/.vscode/settings.json +0 -3
- package/bin/mcp-svc.js +0 -13
- package/src/mcp/MCP/345/234/272/346/231/257/346/250/241/346/213/237.md +0 -8
- package/src/mcp/index-sse-svc.js +0 -126
- package/src/mcp/index-streamable-svc.js +0 -180
- package/src/mcp/tools/Class Detail Retriever/prompt.js +0 -37
- package/src/mcp/tools/Class Editor Guide/prompt.js +0 -468
- package/src/mcp/tools/Class Publisher/prompt.js +0 -40
- package/src/mcp/tools/Class Puller/prompt.js +0 -49
- package/src/mcp/tools/Client Script Creator/handler.js +0 -179
- package/src/mcp/tools/CloudCC Development Overview/prompt.js +0 -870
- package/src/mcp/tools/Component Editor Guide/prompt.js +0 -519
- package/src/mcp/tools/Component Publisher/prompt.js +0 -659
- package/src/mcp/tools/Dev Environment Creator/prompt.js +0 -273
- package/src/mcp/tools/Dev Environment Validator/prompt.js +0 -193
- package/src/mcp/tools/Developer Key Setup Guide/prompt.js +0 -71
- package/src/mcp/tools/Object Fields Retriever/prompt.js +0 -10
- package/src/mcp/tools/Object List Retriever/prompt.js +0 -10
- package/src/mcp/tools/ccdk/fetcher.js +0 -18
- package/src/mcp/tools/ccdk/handler.js +0 -98
- package/src/mcp/tools/ccdk/prompt.js +0 -453
- package/target/ccopenapi-0.0.3-classes.jar +0 -0
- package/target/ccopenapi-0.0.3.jar +0 -0
- package/target/maven-archiver/pom.properties +0 -3
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -18
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -19
- package/template/lib/ccopenapi-0.0.3.jar +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const { spawnSync } = require("child_process");
|
|
3
|
+
|
|
4
|
+
function runCcCommand(args, options = {}) {
|
|
5
|
+
const { cwd = process.cwd(), timeoutMs = 120000 } = options;
|
|
6
|
+
const ccEntry = path.resolve(__dirname, "../../bin/cc.js");
|
|
7
|
+
|
|
8
|
+
const result = spawnSync(process.execPath, [ccEntry, ...args], {
|
|
9
|
+
cwd,
|
|
10
|
+
encoding: "utf8",
|
|
11
|
+
timeout: timeoutMs,
|
|
12
|
+
maxBuffer: 10 * 1024 * 1024
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const stdout = (result.stdout || "").trim();
|
|
16
|
+
const stderr = (result.stderr || "").trim();
|
|
17
|
+
const hasError = Boolean(result.error);
|
|
18
|
+
const code = typeof result.status === "number" ? result.status : -1;
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
success: !hasError && code === 0,
|
|
22
|
+
code,
|
|
23
|
+
stdout,
|
|
24
|
+
stderr,
|
|
25
|
+
error: hasError ? result.error.message : ""
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function buildRunDetail(runResult) {
|
|
30
|
+
return [runResult.error, runResult.stderr, runResult.stdout].filter(Boolean).join("\n");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function runCcJsonCommand(args, options = {}) {
|
|
34
|
+
const runResult = runCcCommand(args, options);
|
|
35
|
+
if (!runResult.success) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
runResult,
|
|
39
|
+
detail: buildRunDetail(runResult),
|
|
40
|
+
data: null
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const data = runResult.stdout ? JSON.parse(runResult.stdout) : null;
|
|
46
|
+
return { success: true, runResult, detail: "", data };
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
runResult,
|
|
51
|
+
detail: `JSON 解析失败: ${error.message}\n${buildRunDetail(runResult)}`,
|
|
52
|
+
data: null
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
runCcCommand,
|
|
59
|
+
runCcJsonCommand,
|
|
60
|
+
buildRunDetail
|
|
61
|
+
};
|
package/src/mcp/index.js
CHANGED
|
@@ -11,7 +11,6 @@ const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
11
11
|
const { z } = require("zod");
|
|
12
12
|
|
|
13
13
|
// 导入各个工具的处理器
|
|
14
|
-
const ccdkHandler = require("./tools/ccdk/handler.js");
|
|
15
14
|
const devEnvHandler = require("./tools/Dev Environment Creator/handler.js");
|
|
16
15
|
const keyGuideHandler = require("./tools/Developer Key Setup Guide/handler.js");
|
|
17
16
|
const devEnvValidatorHandler = require("./tools/Dev Environment Validator/handler.js");
|
|
@@ -20,6 +19,10 @@ const customObjectHandler = require('./tools/Object Creator/handler.js');
|
|
|
20
19
|
const objectListHandler = require('./tools/Object List Retriever/handler.js');
|
|
21
20
|
const objectFieldsHandler = require('./tools/Object Fields Retriever/handler.js');
|
|
22
21
|
const fieldCreatorHandler = require('./tools/Object Fields Creator/handler.js');
|
|
22
|
+
// 菜单相关工具处理器
|
|
23
|
+
const menuCreatorHandler = require('./tools/Menu Creator/handler.js');
|
|
24
|
+
// 应用相关工具处理器
|
|
25
|
+
const applicationCreatorHandler = require('./tools/Application Creator/handler.js');
|
|
23
26
|
// 自定义类工具处理器
|
|
24
27
|
const classesHandler = require("./tools/Class List Retriever/handler.js");
|
|
25
28
|
const classCreatorHandler = require('./tools/Class Creator/handler.js');
|
|
@@ -48,17 +51,18 @@ const componentEditorGuideHandler = require('./tools/Component Editor Guide/hand
|
|
|
48
51
|
const componentPullerHandler = require('./tools/Component Puller/handler.js');
|
|
49
52
|
const componentPublisherHandler = require('./tools/Component Publisher/handler.js');
|
|
50
53
|
// 客户端脚本工具处理器
|
|
51
|
-
const clientScriptCreatorHandler = require('./tools/Client Script Creator/handler.js');
|
|
52
54
|
const clientScriptListHandler = require('./tools/Client Script List Retriever/handler.js');
|
|
53
55
|
const clientScriptDetailHandler = require('./tools/Client Script Detail Retriever/handler.js');
|
|
54
56
|
const clientScriptEditorGuideHandler = require('./tools/Client Script Editor Guide/handler.js');
|
|
55
57
|
const clientScriptPullerHandler = require('./tools/Client Script Puller/handler.js');
|
|
56
58
|
const clientScriptPublisherHandler = require('./tools/Client Script Publisher/handler.js');
|
|
59
|
+
// JSP 迁移工具处理器
|
|
60
|
+
const jspMigratorHandler = require('./tools/JSP Migrator/handler.js');
|
|
57
61
|
// CloudCC 开发项目概要工具处理器
|
|
58
62
|
const cloudccOverviewHandler = require('./tools/CloudCC Development Overview/handler.js');
|
|
59
63
|
|
|
60
64
|
const mcpServer = new McpServer({
|
|
61
|
-
name: '
|
|
65
|
+
name: 'cici',
|
|
62
66
|
version: '1.0.0'
|
|
63
67
|
});
|
|
64
68
|
|
|
@@ -68,11 +72,11 @@ mcpServer.registerTool(
|
|
|
68
72
|
{
|
|
69
73
|
description: '帮助开发者检查本地环境是否支持开发 CloudCC 应用(例如自定义组件、自定义类),并按步骤、关键词、平台或难度返回对应的操作或验证命令。',
|
|
70
74
|
inputSchema: z.object({
|
|
71
|
-
step: z.number().int().optional().describe('可选,按步骤号返回具体步骤'),
|
|
72
|
-
search: z.string().optional().describe('可选,按关键词搜索步骤'),
|
|
73
|
-
difficulty: z.enum(['easy', 'medium', 'hard']).optional().describe('可选,按难度过滤'),
|
|
75
|
+
// step: z.number().int().optional().describe('可选,按步骤号返回具体步骤'),
|
|
76
|
+
// search: z.string().optional().describe('可选,按关键词搜索步骤'),
|
|
77
|
+
// difficulty: z.enum(['easy', 'medium', 'hard']).optional().describe('可选,按难度过滤'),
|
|
74
78
|
platform: z.enum(['windows', 'macos', 'linux']).optional().describe('可选,按平台获取命令'),
|
|
75
|
-
command: z.boolean().optional().describe('可选,返回所有命令的汇总')
|
|
79
|
+
// command: z.boolean().optional().describe('可选,返回所有命令的汇总')
|
|
76
80
|
})
|
|
77
81
|
},
|
|
78
82
|
devEnvValidatorHandler.getDevEnvSetup
|
|
@@ -84,11 +88,11 @@ mcpServer.registerTool(
|
|
|
84
88
|
{
|
|
85
89
|
description: '获取 CloudCC 开发环境搭建指南,帮助用户按步骤完成开发环境的安装与配置。',
|
|
86
90
|
inputSchema: z.object({
|
|
87
|
-
step: z.number().int().optional(),
|
|
88
|
-
search: z.string().optional(),
|
|
89
|
-
difficulty: z.enum(['easy', 'medium', 'hard']).optional(),
|
|
91
|
+
// step: z.number().int().optional(),
|
|
92
|
+
// search: z.string().optional(),
|
|
93
|
+
// difficulty: z.enum(['easy', 'medium', 'hard']).optional(),
|
|
90
94
|
platform: z.enum(['windows', 'macos', 'linux']).optional(),
|
|
91
|
-
command: z.boolean().optional(),
|
|
95
|
+
// command: z.boolean().optional(),
|
|
92
96
|
})
|
|
93
97
|
},
|
|
94
98
|
devEnvHandler.getDevEnvSetup
|
|
@@ -161,6 +165,36 @@ mcpServer.registerTool(
|
|
|
161
165
|
fieldCreatorHandler.createObjectField
|
|
162
166
|
);
|
|
163
167
|
|
|
168
|
+
// ==================== Menu Creator ====================
|
|
169
|
+
mcpServer.registerTool(
|
|
170
|
+
'create_menu',
|
|
171
|
+
{
|
|
172
|
+
description: '为 CloudCC CRM 创建菜单(标签页)。支持四种类型的菜单:object(自定义对象)、page(自定义页面)、script(自定义脚本)、site(站点)。菜单将在导航栏中显示,允许用户快速访问相应的资源。',
|
|
173
|
+
inputSchema: z.object({
|
|
174
|
+
menuType: z.enum(['object', 'page', 'script', 'site']).describe('菜单类型:object(自定义对象菜单)、page(自定义页面菜单)、script(自定义脚本菜单)、site(站点菜单)'),
|
|
175
|
+
resourceId: z.string().min(1).describe('资源ID。根据菜单类型不同,可以是:对象ID(object)、页面ID(page)、脚本ID(script)或站点ID(site)。可通过相应的列表工具获取'),
|
|
176
|
+
tabName: z.string().min(1).describe('菜单标签名称,将在导航栏中显示,建议使用对象的显示标签'),
|
|
177
|
+
projectPath: z.string().describe('项目根路径,默认为当前工作目录')
|
|
178
|
+
})
|
|
179
|
+
},
|
|
180
|
+
menuCreatorHandler.createMenuTool
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// ==================== Application Creator ====================
|
|
184
|
+
mcpServer.registerTool(
|
|
185
|
+
'create_application',
|
|
186
|
+
{
|
|
187
|
+
description: '在 CloudCC CRM 系统中创建一个应用(Application)。应用可以包含多个菜单,用于组织和管理相关的功能模块。',
|
|
188
|
+
inputSchema: z.object({
|
|
189
|
+
appName: z.string().min(1).describe('应用名称,将在系统中显示的标签'),
|
|
190
|
+
appCode: z.string().min(1).describe('应用代码,应用的唯一标识符'),
|
|
191
|
+
menuIds: z.string().optional().describe('菜单ID列表(可选),多个菜单ID时用逗号分隔。如果不提供,将使用默认菜单ID acf000001。如果提供,系统会自动确保 acf000001 包含在列表中'),
|
|
192
|
+
projectPath: z.string().describe('项目根路径,默认为当前工作目录')
|
|
193
|
+
})
|
|
194
|
+
},
|
|
195
|
+
applicationCreatorHandler.createApplicationTool
|
|
196
|
+
);
|
|
197
|
+
|
|
164
198
|
// ==================== Class List Retriever ====================
|
|
165
199
|
mcpServer.registerTool(
|
|
166
200
|
'get_custom_class_list',
|
|
@@ -428,7 +462,7 @@ mcpServer.registerTool(
|
|
|
428
462
|
mcpServer.registerTool(
|
|
429
463
|
'publish_custom_component',
|
|
430
464
|
{
|
|
431
|
-
description: '将 Vue 自定义组件编译并发布到 CloudCC
|
|
465
|
+
description: '将 Vue 自定义组件编译并发布到 CloudCC 服务器',
|
|
432
466
|
inputSchema: z.object({
|
|
433
467
|
componentName: z.string().min(1).describe('要发布的组件名称'),
|
|
434
468
|
projectPath: z.string().optional().describe('项目根目录路径,默认为当前工作目录')
|
|
@@ -628,4 +662,42 @@ mcpServer.registerTool(
|
|
|
628
662
|
cloudccOverviewHandler.getCloudCCDevelopmentOverview
|
|
629
663
|
);
|
|
630
664
|
|
|
665
|
+
// ==================== JSP Migration Analyzer 工具 ====================
|
|
666
|
+
mcpServer.registerTool(
|
|
667
|
+
'analyze_jsp_migration',
|
|
668
|
+
{
|
|
669
|
+
description: '分析旧 JSP 页面,提取 reason 分支、对象依赖和迁移风险,输出迁移报告(不落地代码)。',
|
|
670
|
+
inputSchema: z.object({
|
|
671
|
+
jspPath: z.string().min(1).describe('JSP 文件路径(绝对路径或相对 projectPath)'),
|
|
672
|
+
helpDocPath: z.string().optional().describe('帮助文档路径(可选),如 jspTemp/帮助文档.md'),
|
|
673
|
+
projectPath: z.string().optional().describe('项目根路径,默认当前工作目录'),
|
|
674
|
+
className: z.string().optional().describe('可选,指定生成类名'),
|
|
675
|
+
componentName: z.string().optional().describe('可选,指定生成组件名'),
|
|
676
|
+
outputProjectPath: z.string().optional().describe('可选,输出项目路径,默认等于 projectPath'),
|
|
677
|
+
reportDir: z.string().optional().describe('可选,报告目录,默认 migration-report')
|
|
678
|
+
})
|
|
679
|
+
},
|
|
680
|
+
jspMigratorHandler.analyzeJspMigration
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
// ==================== JSP Splitter 工具 ====================
|
|
684
|
+
mcpServer.registerTool(
|
|
685
|
+
'split_jsp_to_cloudcc',
|
|
686
|
+
{
|
|
687
|
+
description: '将旧 JSP 页面拆分为 CloudCC 自定义类和自定义组件,并生成迁移报告。支持 apply/dry-run 两种模式。',
|
|
688
|
+
inputSchema: z.object({
|
|
689
|
+
jspPath: z.string().min(1).describe('JSP 文件路径(绝对路径或相对 projectPath)'),
|
|
690
|
+
helpDocPath: z.string().optional().describe('帮助文档路径(可选),如 jspTemp/帮助文档.md'),
|
|
691
|
+
projectPath: z.string().optional().describe('项目根路径,默认当前工作目录'),
|
|
692
|
+
outputProjectPath: z.string().optional().describe('输出项目路径,默认等于 projectPath'),
|
|
693
|
+
className: z.string().optional().describe('可选,指定生成类名'),
|
|
694
|
+
componentName: z.string().optional().describe('可选,指定生成组件名'),
|
|
695
|
+
reportDir: z.string().optional().describe('可选,报告目录,默认 migration-report'),
|
|
696
|
+
mode: z.enum(['apply', 'dry-run']).optional().default('apply').describe('apply: 生成文件;dry-run: 仅分析'),
|
|
697
|
+
overwrite: z.boolean().optional().default(false).describe('是否覆盖已存在文件,默认 false')
|
|
698
|
+
})
|
|
699
|
+
},
|
|
700
|
+
jspMigratorHandler.splitJspToCloudcc
|
|
701
|
+
);
|
|
702
|
+
|
|
631
703
|
module.exports = mcpServer;
|
package/src/mcp/readme.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* 检查当前环境的开发者密钥是否配置正确
|
|
15
15
|
* 指导如何获取密钥,以及如何配置
|
|
16
16
|
|
|
17
|
-
### 4:创建应用程序Tool - App Creator
|
|
17
|
+
### 4:创建应用程序Tool - App Creator ✅
|
|
18
18
|
* 创建一个应用程序
|
|
19
19
|
|
|
20
20
|
### 5:查询应用列表 - App List Retriever
|
|
@@ -131,7 +131,10 @@
|
|
|
131
131
|
* 这是开始 CloudCC 开发前必须查看的工具
|
|
132
132
|
* 需要使用知识库
|
|
133
133
|
|
|
134
|
-
### 42:审批Tool - Approval
|
|
134
|
+
### 42:审批Tool - Approval ✅
|
|
135
135
|
* 拉取所有的待审批的记录
|
|
136
136
|
* 通过id审批通过记录
|
|
137
|
-
* 通过id拒绝审批通过记录
|
|
137
|
+
* 通过id拒绝审批通过记录
|
|
138
|
+
|
|
139
|
+
### 43:菜单Tool - Menu ✅
|
|
140
|
+
* 创建自定义对象菜单
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Creator Handler
|
|
3
|
+
* 提供创建应用(Application)的 MCP 工具实现
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { runCcCommand, buildRunDetail } = require('../../cliRunner');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 创建应用
|
|
11
|
+
* @param {{
|
|
12
|
+
* appName: string,
|
|
13
|
+
* appCode: string,
|
|
14
|
+
* menuIds?: string,
|
|
15
|
+
* projectPath?: string
|
|
16
|
+
* }} params
|
|
17
|
+
*/
|
|
18
|
+
async function createApplicationTool(params = {}) {
|
|
19
|
+
try {
|
|
20
|
+
const { appName, appCode, menuIds, projectPath } = params;
|
|
21
|
+
|
|
22
|
+
// 验证必需参数
|
|
23
|
+
if (!appName || !appCode) {
|
|
24
|
+
return {
|
|
25
|
+
content: [{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: '✗ 参数缺失: appName (应用名称) 和 appCode (应用代码) 必须提供\n\n参数说明:\n- appName: 应用的显示名称\n- appCode: 应用的代码标识\n- menuIds: 菜单ID列表(可选,多个时用逗号分隔,默认包含 acf000001)\n- projectPath: 项目路径(可选,默认为当前工作目录)'
|
|
28
|
+
}]
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const resolvedPath = path.resolve(projectPath || '.');
|
|
33
|
+
|
|
34
|
+
// 构建参数数组,格式: ['create', 'application', path, p1, p2, duel1]
|
|
35
|
+
// 注意:argvs[2] 是 path,argvs[3] 是 p1,argvs[4] 是 p2,argvs[5] 是 duel1
|
|
36
|
+
const args = [
|
|
37
|
+
'create',
|
|
38
|
+
'application',
|
|
39
|
+
resolvedPath,
|
|
40
|
+
appName,
|
|
41
|
+
appCode
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// 如果提供了 menuIds,添加到参数中
|
|
45
|
+
if (menuIds) {
|
|
46
|
+
args.push(menuIds);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const runResult = runCcCommand(args, { cwd: resolvedPath });
|
|
50
|
+
|
|
51
|
+
if (runResult.success) {
|
|
52
|
+
return {
|
|
53
|
+
content: [{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: `✓ 应用创建成功!\n\n应用名称: ${appName}\n应用代码: ${appCode}\n项目目录: ${resolvedPath}\n菜单ID: ${menuIds || 'acf000001(默认)'}\n\n应用已成功创建并配置到 CloudCC 系统中。`
|
|
56
|
+
}]
|
|
57
|
+
};
|
|
58
|
+
} else {
|
|
59
|
+
return {
|
|
60
|
+
content: [{
|
|
61
|
+
type: 'text',
|
|
62
|
+
text: `⚠ 应用创建遇到问题\n\n${buildRunDetail(runResult) || 'cc 命令执行失败'}\n\n请检查:\n1. 应用名称和应用代码是否符合规范\n2. CloudCC服务器连接是否正常\n3. 项目配置是否正确\n4. 是否有足够的权限创建应用\n5. 菜单ID是否正确`
|
|
63
|
+
}]
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
return {
|
|
68
|
+
content: [{
|
|
69
|
+
type: 'text',
|
|
70
|
+
text: `✗ 应用创建失败: ${error.message}\n\n错误详情:\n${error.stack || '无详细信息'}\n\n请检查:\n1. 应用名称和应用代码是否正确\n2. 项目路径是否正确\n3. CloudCC服务器连接是否正常\n4. 项目配置文件是否存在\n5. 菜单ID格式是否正确(多个时用逗号分隔)`
|
|
71
|
+
}]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
createApplicationTool
|
|
78
|
+
};
|
|
@@ -1,151 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Approval 工具处理器
|
|
3
|
-
* 提供审批相关的功能:拉取待审批记录、审批通过、拒绝审批
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
const { z } = require('zod');
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const service = axios.create({
|
|
10
|
-
timeout: 60000,
|
|
11
|
-
headers: {
|
|
12
|
-
'Content-Type': 'application/json; charset=utf-8',
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const postClass = (url, data = {}, accessToken) => {
|
|
17
|
-
if (accessToken) {
|
|
18
|
-
return service({
|
|
19
|
-
url,
|
|
20
|
-
method: 'post',
|
|
21
|
-
headers: { accessToken },
|
|
22
|
-
data
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
console.error();
|
|
26
|
-
console.error('Failed: \nOpenAPI Token is null. \nPlease provide token via参数.');
|
|
27
|
-
console.error();
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// 统一校验 token 与 apiSvc,完全依赖入参便于迁移
|
|
31
|
-
async function loadConfig(token, apiSvcOverride) {
|
|
32
|
-
const apiSvc = apiSvcOverride;
|
|
33
|
-
const accessToken = token;
|
|
34
|
-
if (!apiSvc) {
|
|
35
|
-
throw new Error('缺少 apiSvc,请通过参数传入接口域名');
|
|
36
|
-
}
|
|
37
|
-
if (!accessToken) {
|
|
38
|
-
throw new Error('缺少访问 token,请通过参数传入');
|
|
39
|
-
}
|
|
40
|
-
return { accessToken, apiSvc };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function requestPendingApprovals(queryParams, token, apiSvcOverride) {
|
|
44
|
-
const { accessToken, apiSvc } = await loadConfig(token, apiSvcOverride);
|
|
45
|
-
const requestBody = {
|
|
46
|
-
approvalProjectType: queryParams.approvalProjectType || "0",
|
|
47
|
-
approvalProcessStatus: queryParams.approvalProcessStatus || "",
|
|
48
|
-
startTime: queryParams.startTime || "",
|
|
49
|
-
endTime: queryParams.endTime || "",
|
|
50
|
-
actor: queryParams.actor || "",
|
|
51
|
-
related: queryParams.related || "",
|
|
52
|
-
type: queryParams.type || "",
|
|
53
|
-
pageNum: queryParams.pageNum || 1,
|
|
54
|
-
pageSize: queryParams.pageSize || 10
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const url = `${apiSvc}/api/approval/getAllApprovalHistoryPendingList`;
|
|
58
|
-
const response = await postClass(url, requestBody, accessToken);
|
|
59
|
-
|
|
60
|
-
if (response.result) {
|
|
61
|
-
const { list = [], zylist = [], allpage } = response.data;
|
|
62
|
-
const zhaiyaoMap = {};
|
|
63
|
-
zylist.forEach(item => {
|
|
64
|
-
zhaiyaoMap[item.id] = item.zhaiyao;
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const enrichedList = list.map(record => ({
|
|
68
|
-
...record,
|
|
69
|
-
zhaiyao: zhaiyaoMap[record.workItemid] || null
|
|
70
|
-
}));
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
list: enrichedList,
|
|
74
|
-
allpage,
|
|
75
|
-
total: list.length
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
throw new Error('获取待审批记录失败: ' + (response.returnInfo || response.message || '未知错误'));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async function approveRequest(approvalParams, token, apiSvcOverride) {
|
|
83
|
-
const { accessToken, apiSvc } = await loadConfig(token, apiSvcOverride);
|
|
84
|
-
const { relatedId, workItemId } = approvalParams;
|
|
85
|
-
|
|
86
|
-
const getPermissionById = await postClass(
|
|
87
|
-
`${apiSvc}/api/objectdetail/getPermissionById`,
|
|
88
|
-
{ id: relatedId },
|
|
89
|
-
accessToken
|
|
90
|
-
);
|
|
91
|
-
const { objectApi } = getPermissionById.data;
|
|
92
|
-
|
|
93
|
-
const requestBody = {
|
|
94
|
-
data: JSON.stringify([{ id: relatedId }]),
|
|
95
|
-
relatedId,
|
|
96
|
-
comments: '',
|
|
97
|
-
workItemId,
|
|
98
|
-
actionType: 'Approved',
|
|
99
|
-
objectApiName: objectApi,
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const url = `${apiSvc}/api/approval/updateApprovalProcessOperation`;
|
|
103
|
-
const response = await postClass(url, requestBody, accessToken);
|
|
104
|
-
|
|
105
|
-
if (response.result) {
|
|
106
|
-
return {
|
|
107
|
-
success: true,
|
|
108
|
-
message: response.returnInfo || '审批通过成功',
|
|
109
|
-
data: response.data
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
throw new Error('审批通过失败: ' + (response.returnInfo || response.message || '未知错误'));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function rejectRequest(approvalParams, token, apiSvcOverride) {
|
|
117
|
-
const { accessToken, apiSvc } = await loadConfig(token, apiSvcOverride);
|
|
118
|
-
const { relatedId, workItemId, comments } = approvalParams;
|
|
119
|
-
|
|
120
|
-
const getPermissionById = await postClass(
|
|
121
|
-
`${apiSvc}/api/objectdetail/getPermissionById`,
|
|
122
|
-
{ id: relatedId },
|
|
123
|
-
accessToken
|
|
124
|
-
);
|
|
125
|
-
const { objectApi } = getPermissionById.data;
|
|
126
|
-
|
|
127
|
-
const requestBody = {
|
|
128
|
-
data: JSON.stringify([{ id: relatedId }]),
|
|
129
|
-
relatedId,
|
|
130
|
-
comments,
|
|
131
|
-
workItemId,
|
|
132
|
-
actionType: 'Rejected',
|
|
133
|
-
objectApiName: objectApi,
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const url = `${apiSvc}/api/approval/updateApprovalProcessOperation`;
|
|
137
|
-
const response = await postClass(url, requestBody, accessToken);
|
|
138
|
-
|
|
139
|
-
if (response.result) {
|
|
140
|
-
return {
|
|
141
|
-
success: true,
|
|
142
|
-
message: response.returnInfo || '审批拒绝成功',
|
|
143
|
-
data: response.data
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
throw new Error('审批拒绝失败: ' + (response.returnInfo || response.message || '未知错误'));
|
|
148
|
-
}
|
|
2
|
+
const { runCcJsonCommand } = require('../../cliRunner');
|
|
149
3
|
|
|
150
4
|
/**
|
|
151
5
|
* 拉取所有的待审批的记录
|
|
@@ -186,11 +40,19 @@ async function getPendingApprovals({
|
|
|
186
40
|
pageNum,
|
|
187
41
|
pageSize
|
|
188
42
|
};
|
|
189
|
-
const
|
|
43
|
+
const encoded = encodeURI(JSON.stringify(queryParams));
|
|
44
|
+
const run = runCcJsonCommand(['get', 'approval', process.cwd(), encoded]);
|
|
45
|
+
if (!run.success) {
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: 'text', text: `✗ 拉取待审批记录失败: ${run.detail || 'cc 命令执行失败'}` }]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const result = run.data || {};
|
|
51
|
+
const warn = (token || apiSvc) ? '\n\n提示: 当前已切换为 CLI 调用,token/apiSvc 参数不会覆盖本地配置。' : '';
|
|
190
52
|
|
|
191
53
|
return {
|
|
192
54
|
content: [
|
|
193
|
-
{ type: 'text', text: "将以下结果转换为markdown表格的模式展示:" + JSON.stringify(result, null, 2) }
|
|
55
|
+
{ type: 'text', text: "将以下结果转换为markdown表格的模式展示:" + JSON.stringify(result, null, 2) + warn }
|
|
194
56
|
]
|
|
195
57
|
};
|
|
196
58
|
} catch (error) {
|
|
@@ -211,6 +73,7 @@ async function approveRecord({
|
|
|
211
73
|
confirm,
|
|
212
74
|
objid,
|
|
213
75
|
workItemId,
|
|
76
|
+
token = '',
|
|
214
77
|
apiSvc = ''
|
|
215
78
|
}) {
|
|
216
79
|
try {
|
|
@@ -233,7 +96,17 @@ async function approveRecord({
|
|
|
233
96
|
relatedId: objid,
|
|
234
97
|
workItemId,
|
|
235
98
|
};
|
|
236
|
-
const
|
|
99
|
+
const encoded = encodeURI(JSON.stringify(approvalParams));
|
|
100
|
+
const run = runCcJsonCommand(['approve', 'approval', process.cwd(), encoded]);
|
|
101
|
+
if (!run.success) {
|
|
102
|
+
return {
|
|
103
|
+
content: [{ type: 'text', text: `✗ 审批通过失败: ${run.detail || 'cc 命令执行失败'}` }]
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const result = run.data || { success: true };
|
|
107
|
+
if (token || apiSvc) {
|
|
108
|
+
result.warning = '当前已切换为 CLI 调用,token/apiSvc 参数不会覆盖本地配置。';
|
|
109
|
+
}
|
|
237
110
|
|
|
238
111
|
return {
|
|
239
112
|
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
|
|
@@ -276,7 +149,17 @@ async function rejectRecord({ confirm, objid, comment = '', workItemId, token =
|
|
|
276
149
|
workItemId,
|
|
277
150
|
comments: comment
|
|
278
151
|
};
|
|
279
|
-
const
|
|
152
|
+
const encoded = encodeURI(JSON.stringify(approvalParams));
|
|
153
|
+
const run = runCcJsonCommand(['reject', 'approval', process.cwd(), encoded]);
|
|
154
|
+
if (!run.success) {
|
|
155
|
+
return {
|
|
156
|
+
content: [{ type: 'text', text: `✗ 拒绝审批失败: ${run.detail || 'cc 命令执行失败'}` }]
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const result = run.data || { success: true };
|
|
160
|
+
if (token || apiSvc) {
|
|
161
|
+
result.warning = '当前已切换为 CLI 调用,token/apiSvc 参数不会覆盖本地配置。';
|
|
162
|
+
}
|
|
280
163
|
|
|
281
164
|
return {
|
|
282
165
|
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
|
|
@@ -4,29 +4,32 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const
|
|
7
|
+
const { runCcCommand } = require('../../cliRunner');
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* 创建自定义类
|
|
11
11
|
*/
|
|
12
12
|
async function createClass({ className, projectPath = process.cwd() }) {
|
|
13
13
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
if (!className || !className.trim()) {
|
|
15
|
+
return { content: [{ type: 'text', text: '✗ 参数缺失: className 必须提供' }] };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const resolvedPath = path.resolve(projectPath);
|
|
19
|
+
const runResult = runCcCommand(['create', 'classes', className], { cwd: resolvedPath });
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
content: [{
|
|
23
|
-
type: 'text',
|
|
24
|
-
text: `✓ 创建成功!\n\n类路径: ${classPath}\n生成的文件:\n - ${className}.java (主类文件)\n - ${className}Test.java (测试类文件)\n - config.json (配置文件)`
|
|
25
|
-
}]
|
|
26
|
-
};
|
|
27
|
-
} finally {
|
|
28
|
-
process.chdir(originalCwd);
|
|
21
|
+
if (!runResult.success) {
|
|
22
|
+
const detail = [runResult.error, runResult.stderr, runResult.stdout].filter(Boolean).join('\n');
|
|
23
|
+
return { content: [{ type: 'text', text: `✗ 创建失败: ${detail || 'cc 命令执行失败'}` }] };
|
|
29
24
|
}
|
|
25
|
+
|
|
26
|
+
const classPath = path.join(resolvedPath, `classes/${className}`);
|
|
27
|
+
return {
|
|
28
|
+
content: [{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: `✓ 创建成功!\n\n调用命令: cc create classes ${className}\n执行目录: ${resolvedPath}\n类路径: ${classPath}\n生成的文件:\n - ${className}.java (主类文件)\n - ${className}Test.java (测试类文件)\n - config.json (配置文件)`
|
|
31
|
+
}]
|
|
32
|
+
};
|
|
30
33
|
} catch (error) {
|
|
31
34
|
return { content: [{ type: 'text', text: `✗ 创建失败: ${error.message}` }] };
|
|
32
35
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* 获取自定义类的详细信息
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { runCcJsonCommand } = require('../../cliRunner');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* 获取类详细信息
|
|
@@ -14,15 +15,13 @@ const detailModule = require('../../../classes/detail');
|
|
|
14
15
|
*/
|
|
15
16
|
async function getClassDetail({ className, classId, projectPath = process.cwd() }) {
|
|
16
17
|
try {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return { content: [{ type: 'text', text: JSON.stringify(detail, null, 2) }] };
|
|
23
|
-
} finally {
|
|
24
|
-
process.chdir(originalCwd);
|
|
18
|
+
const resolvedPath = path.resolve(projectPath);
|
|
19
|
+
const args = ['detail', 'classes', className || '', classId || ''];
|
|
20
|
+
const run = runCcJsonCommand(args, { cwd: resolvedPath });
|
|
21
|
+
if (!run.success) {
|
|
22
|
+
return { content: [{ type: 'text', text: `✗ 获取失败: ${run.detail || 'cc 命令执行失败'}` }] };
|
|
25
23
|
}
|
|
24
|
+
return { content: [{ type: 'text', text: JSON.stringify(run.data, null, 2) }] };
|
|
26
25
|
} catch (error) {
|
|
27
26
|
return { content: [{ type: 'text', text: `✗ 获取失败: ${error.message}` }] };
|
|
28
27
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* 2. 需要详细信息时再查询具体API类
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const { runCcCommand, buildRunDetail } = require('../../cliRunner');
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 获取编辑指南
|
|
@@ -27,34 +27,20 @@ const prompt = require('./prompt');
|
|
|
27
27
|
*/
|
|
28
28
|
async function editClass({ topic = 'overview' } = {}) {
|
|
29
29
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'overview', // 规范 + 最佳实践 + API概要
|
|
33
|
-
'ccservice', // CCService 详细文档
|
|
34
|
-
'object', // CCObject 详细文档
|
|
35
|
-
'email', // SendEmail 详细文档
|
|
36
|
-
'time', // TimeUtil 详细文档
|
|
37
|
-
'user', // UserInfo 详细文档
|
|
38
|
-
'logger', // DevLogger 详细文档
|
|
39
|
-
'scenarios' // 常见场景
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
if (topic && !validTopics.includes(topic)) {
|
|
30
|
+
const run = runCcCommand(['doc', 'classes', topic]);
|
|
31
|
+
if (!run.success) {
|
|
43
32
|
return {
|
|
44
33
|
content: [{
|
|
45
34
|
type: 'text',
|
|
46
|
-
text: `✗
|
|
35
|
+
text: `✗ 获取编辑指南失败: ${buildRunDetail(run) || 'cc 命令执行失败'}`
|
|
47
36
|
}]
|
|
48
37
|
};
|
|
49
38
|
}
|
|
50
39
|
|
|
51
|
-
// 获取指定主题的编辑指南
|
|
52
|
-
const result = prompt.getEditGuide(topic);
|
|
53
|
-
|
|
54
40
|
return {
|
|
55
41
|
content: [{
|
|
56
42
|
type: 'text',
|
|
57
|
-
text:
|
|
43
|
+
text: run.stdout || ''
|
|
58
44
|
}]
|
|
59
45
|
};
|
|
60
46
|
} catch (error) {
|