cloudcc-cli 2.2.4 → 2.2.6
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 +34 -0
- package/README.md +1428 -520
- package/bin/cc.js +0 -2
- package/bin/index.js +4 -0
- package/package.json +1 -1
- package/src/application/create.js +114 -0
- package/src/application/get.js +13 -0
- package/src/application/index.js +8 -0
- package/src/classes/create.js +66 -0
- package/src/classes/detail.js +78 -0
- package/src/classes/get.js +24 -0
- package/src/classes/index.js +12 -0
- package/src/classes/publish.js +51 -0
- package/src/classes/pull.js +55 -0
- package/src/classes/pullList.js +46 -0
- package/src/mcp/index.js +43 -9
- package/src/mcp/readme.md +6 -3
- package/src/mcp/tools/Application Creator/handler.js +80 -0
- package/src/mcp/tools/CloudCC Development Overview/prompt.js +4 -3
- package/src/mcp/tools/Menu Creator/handler.js +109 -0
- package/src/mcp/tools/Trigger Editor Guide/handler.js +4 -4
- 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/pull.js +3 -0
- package/target/classes/com/cloudcc/core/CCObject.class +0 -0
- package/target/classes/com/cloudcc/core/CCSchedule.class +0 -0
- package/target/classes/com/cloudcc/core/CCService.class +0 -0
- package/target/classes/com/cloudcc/core/CCTrigger.class +0 -0
- package/target/classes/com/cloudcc/core/CCTriggerHandler.class +0 -0
- package/target/classes/com/cloudcc/core/DevLogger.class +0 -0
- package/target/classes/com/cloudcc/core/OperatationEnum.class +0 -0
- package/target/classes/com/cloudcc/core/PeakInterf.class +0 -0
- package/target/classes/com/cloudcc/core/SendEmail.class +0 -0
- package/target/classes/com/cloudcc/core/ServiceResult.class +0 -0
- package/target/classes/com/cloudcc/core/TimeUtil.class +0 -0
- package/target/classes/com/cloudcc/core/Tool$1.class +0 -0
- package/target/classes/com/cloudcc/core/Tool.class +0 -0
- package/target/classes/com/cloudcc/core/TriggerInvoker.class +0 -0
- package/target/classes/com/cloudcc/core/TriggerMethod.class +0 -0
- package/target/classes/com/cloudcc/core/TriggerTimeEnum.class +0 -0
- package/target/classes/com/cloudcc/core/UserInfo.class +0 -0
package/bin/cc.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
const chalk = require("chalk")
|
|
3
3
|
|
|
4
4
|
let argvs = process.argv.splice(2);
|
|
5
|
-
|
|
6
5
|
let action = argvs[0]
|
|
7
6
|
// 处理版本查询命令
|
|
8
7
|
if (action === '-version' || action === '-v' || action === '--version' || action === '--v') {
|
|
@@ -27,7 +26,6 @@ if (!type) {
|
|
|
27
26
|
return;
|
|
28
27
|
}
|
|
29
28
|
const cc = require("./index")
|
|
30
|
-
|
|
31
29
|
try {
|
|
32
30
|
cc[argvs[1]](argvs[0], argvs);
|
|
33
31
|
} catch (e) {
|
package/bin/index.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const { postClass } = require("../../utils/http")
|
|
2
|
+
const { getPackageJson } = require("../../utils/config");
|
|
3
|
+
const briefGet = require("../brief/get");
|
|
4
|
+
const chalk = require('chalk')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 创建应用(Application)
|
|
8
|
+
* @param {Array} argvs - 命令行参数数组
|
|
9
|
+
* @returns {Promise<Object>} 创建结果
|
|
10
|
+
*/
|
|
11
|
+
async function create(argvs) {
|
|
12
|
+
try {
|
|
13
|
+
// 命令行参数格式:cc create application <path> <p1> <p2> [duel1]
|
|
14
|
+
// argvs: ['application', 'create', path, p1, p2, duel1]
|
|
15
|
+
let path = argvs[2];
|
|
16
|
+
let p1 = argvs[3]; // 应用名称
|
|
17
|
+
let p2 = argvs[4]; // 应用代码
|
|
18
|
+
let duel1 = argvs[5]; // 菜单ID,多个时用逗号分隔,可选,默认为 "acf000001"
|
|
19
|
+
|
|
20
|
+
// 验证必需参数
|
|
21
|
+
if (!p1 || !p2) {
|
|
22
|
+
console.error();
|
|
23
|
+
console.error(chalk.red('Error: 缺少必需参数'));
|
|
24
|
+
console.error('用法: cc create application <path> <p1> <p2> [duel1]');
|
|
25
|
+
console.error(' path: 项目路径');
|
|
26
|
+
console.error(' p1: 应用名称');
|
|
27
|
+
console.error(' p2: 应用代码');
|
|
28
|
+
console.error(' duel1: 菜单ID(可选,多个时用逗号分隔,默认: acf000001)');
|
|
29
|
+
console.error();
|
|
30
|
+
throw new Error('缺少必需参数: p1 和 p2');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 处理 duel1,确保始终包含 acf000001
|
|
34
|
+
const REQUIRED_MENU_ID = "acf000001";
|
|
35
|
+
if (!duel1) {
|
|
36
|
+
// 如果没有传入,使用默认值
|
|
37
|
+
duel1 = REQUIRED_MENU_ID;
|
|
38
|
+
} else {
|
|
39
|
+
// 如果传入了,确保 acf000001 在列表中
|
|
40
|
+
const menuIds = duel1.split(',').map(id => id.trim()).filter(id => id);
|
|
41
|
+
if (!menuIds.includes(REQUIRED_MENU_ID)) {
|
|
42
|
+
// 如果列表中没有 acf000001,添加到列表开头
|
|
43
|
+
menuIds.unshift(REQUIRED_MENU_ID);
|
|
44
|
+
}
|
|
45
|
+
duel1 = menuIds.join(',');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let config = await getPackageJson(path);
|
|
49
|
+
|
|
50
|
+
// 从 brief/get 获取角色ID列表(仍使用原始 argv 参数: path 位于 argvs[2])
|
|
51
|
+
// 注意:brief/get 的接口返回是 { success, data } 的格式
|
|
52
|
+
let briefData = await briefGet(argvs);
|
|
53
|
+
|
|
54
|
+
if (!briefData.success) {
|
|
55
|
+
console.error("获取角色列表失败:", briefData.message);
|
|
56
|
+
throw new Error("获取角色列表失败");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 提取所有角色的 ID 列表,用逗号连接
|
|
60
|
+
const profileIdList = briefData.data.map(profile => profile.id);
|
|
61
|
+
const p12 = profileIdList.join(',');
|
|
62
|
+
|
|
63
|
+
// 构建请求体,使用用户提供的参数结构
|
|
64
|
+
const requestBody = {
|
|
65
|
+
"visited_0": "1",
|
|
66
|
+
"visited_1": "1",
|
|
67
|
+
"setupid": "TabSet",
|
|
68
|
+
"apptype": "app",
|
|
69
|
+
"p1": p1,
|
|
70
|
+
"p2": p2,
|
|
71
|
+
"p3": "",
|
|
72
|
+
"navigationStyle": "1",
|
|
73
|
+
"jump": "1",
|
|
74
|
+
"p4": "",
|
|
75
|
+
"appstyle": 21,
|
|
76
|
+
"p8": "home",
|
|
77
|
+
"duel1": duel1,
|
|
78
|
+
"visited_2": "1",
|
|
79
|
+
"visited_3": "1",
|
|
80
|
+
"p12": p12
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// 显示创建进度
|
|
84
|
+
console.error();
|
|
85
|
+
console.error(chalk.green('Creating application, please wait...'));
|
|
86
|
+
console.error();
|
|
87
|
+
|
|
88
|
+
// 发送请求到服务器
|
|
89
|
+
const result = await postClass(
|
|
90
|
+
config.setupSvc + "/api/appProgram/tabSetDone",
|
|
91
|
+
requestBody,
|
|
92
|
+
config.accessToken
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// API 返回结构中, result 字段决定调用是否成功
|
|
96
|
+
if (result && result.result) {
|
|
97
|
+
console.error();
|
|
98
|
+
console.error(chalk.green('Success!'));
|
|
99
|
+
console.error();
|
|
100
|
+
return result;
|
|
101
|
+
} else {
|
|
102
|
+
const msg = result && result.returnInfo ? result.returnInfo : 'Unknown error';
|
|
103
|
+
console.error();
|
|
104
|
+
console.error(chalk.red('Error:' + msg));
|
|
105
|
+
throw new Error('Create Application Failed: ' + msg);
|
|
106
|
+
}
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error();
|
|
109
|
+
console.error(chalk.red("应用创建失败:"), error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = create;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { postClass } = require("../../utils/http")
|
|
2
|
+
const { getPackageJson } = require("../../utils/config")
|
|
3
|
+
|
|
4
|
+
async function get(argvs, isMcp = false) {
|
|
5
|
+
// TODO: 实现获取应用列表的功能
|
|
6
|
+
let res = [];
|
|
7
|
+
if (!isMcp) {
|
|
8
|
+
console.log(JSON.stringify(res));
|
|
9
|
+
}
|
|
10
|
+
return res
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = get;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const { checkUpdate } = require("../../utils/checkVersion")
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path")
|
|
4
|
+
const chalk = require("chalk")
|
|
5
|
+
const { getPackageJson } = require("../../utils/config.js")
|
|
6
|
+
|
|
7
|
+
async function create(name) {
|
|
8
|
+
let res = await checkUpdate();
|
|
9
|
+
if (!res) {
|
|
10
|
+
let config = await getPackageJson();
|
|
11
|
+
const classesPath = path.join(process.cwd(), "classes/" + name);
|
|
12
|
+
try {
|
|
13
|
+
fs.mkdirSync(classesPath, { recursive: true })
|
|
14
|
+
const javaTmp =
|
|
15
|
+
`package classes.${name};
|
|
16
|
+
|
|
17
|
+
import com.cloudcc.core.*;
|
|
18
|
+
// @SOURCE_CONTENT_START
|
|
19
|
+
public class ${name}{
|
|
20
|
+
private UserInfo userInfo;
|
|
21
|
+
private CCService cs;
|
|
22
|
+
|
|
23
|
+
public ${name}(UserInfo userInfo){
|
|
24
|
+
this(userInfo,new CCService(userInfo));
|
|
25
|
+
}
|
|
26
|
+
public ${name}(UserInfo userInfo,CCService cs){
|
|
27
|
+
this.userInfo = userInfo;
|
|
28
|
+
this.cs=cs;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public String getName(String str){
|
|
32
|
+
str = "demo";
|
|
33
|
+
return str;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// @SOURCE_CONTENT_END
|
|
37
|
+
`
|
|
38
|
+
const javaTestTmp =
|
|
39
|
+
`package classes.${name};
|
|
40
|
+
|
|
41
|
+
import com.cloudcc.core.*;
|
|
42
|
+
|
|
43
|
+
public class ${name}Test {
|
|
44
|
+
public static void main(String[] args) {
|
|
45
|
+
${name} obj = new ${name}(new UserInfo());
|
|
46
|
+
String name = obj.getName("test");
|
|
47
|
+
System.out.println("name:" + name);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`
|
|
51
|
+
fs.writeFileSync(path.join(classesPath, name + ".java"), javaTmp)
|
|
52
|
+
fs.writeFileSync(path.join(classesPath, name + "Test.java"), javaTestTmp)
|
|
53
|
+
fs.writeFileSync(path.join(classesPath, "config.json"), `{"name":"${name}","version":"${config.extandVersion || '2'}"}`)
|
|
54
|
+
console.error()
|
|
55
|
+
console.error(chalk.green("Successfully Created:" + name))
|
|
56
|
+
console.error()
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error()
|
|
59
|
+
console.error(chalk.red("Creation Class Failed:" + e))
|
|
60
|
+
console.error()
|
|
61
|
+
throw new Error("Creation Class Failed: " + e);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = create;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path")
|
|
3
|
+
|
|
4
|
+
const { getPackageJson } = require("../../utils/config")
|
|
5
|
+
const { postClass } = require("../../utils/http")
|
|
6
|
+
|
|
7
|
+
async function detail(name, id) {
|
|
8
|
+
// 如果有 name,优先查询本地
|
|
9
|
+
if (name && name !== '') {
|
|
10
|
+
const classPath = path.join(process.cwd(), `classes/${name}/`);
|
|
11
|
+
const configPath = classPath + "config.json";
|
|
12
|
+
const javaFilePath = classPath + `${name}.java`;
|
|
13
|
+
|
|
14
|
+
// 先尝试从本地文件获取详情
|
|
15
|
+
if (fs.existsSync(configPath) && fs.existsSync(javaFilePath)) {
|
|
16
|
+
let configContent = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
17
|
+
let javaContent = fs.readFileSync(javaFilePath, 'utf8');
|
|
18
|
+
return {
|
|
19
|
+
name: configContent.name,
|
|
20
|
+
version: configContent.version,
|
|
21
|
+
id: configContent.id || null,
|
|
22
|
+
source: javaContent,
|
|
23
|
+
published: !!configContent.id,
|
|
24
|
+
fromLocal: true
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 本地文件不完整,从服务器拉取
|
|
29
|
+
if (!fs.existsSync(configPath)) {
|
|
30
|
+
throw new Error('Class not found in local directory: ' + classPath);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let configContent = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
34
|
+
|
|
35
|
+
if (!configContent.id) {
|
|
36
|
+
throw new Error('Class has not been published. Please publish first to fetch details from server.');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 使用本地 config 中的 id 从服务器获取详细信息
|
|
40
|
+
let body = {
|
|
41
|
+
"id": configContent.id,
|
|
42
|
+
}
|
|
43
|
+
let config = await getPackageJson();
|
|
44
|
+
let res = await postClass(config.setupSvc + "/api/ccfag/detail", body, config.accessToken)
|
|
45
|
+
|
|
46
|
+
if (res.result) {
|
|
47
|
+
return {
|
|
48
|
+
...res.data.trigger,
|
|
49
|
+
fromLocal: false
|
|
50
|
+
};
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error('Get Class Details Failed: ' + res.returnInfo);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 如果没有 name,用 id 从服务器查询
|
|
57
|
+
if (id && id !== '') {
|
|
58
|
+
let body = {
|
|
59
|
+
"id": id,
|
|
60
|
+
}
|
|
61
|
+
let config = await getPackageJson();
|
|
62
|
+
let res = await postClass(config.setupSvc + "/api/ccfag/detail", body, config.accessToken)
|
|
63
|
+
|
|
64
|
+
if (res.result) {
|
|
65
|
+
return {
|
|
66
|
+
...res.data.trigger,
|
|
67
|
+
fromLocal: false
|
|
68
|
+
};
|
|
69
|
+
} else {
|
|
70
|
+
throw new Error('Get Class Details Failed: ' + res.returnInfo);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 既没有 name 也没有 id,报错
|
|
75
|
+
throw new Error('Either class name or id must be provided');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = detail;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const { getPackageJson } = require("../../utils/config")
|
|
2
|
+
const { postClass } = require("../../utils/http")
|
|
3
|
+
|
|
4
|
+
async function get(arg, path, isMcp = false) {
|
|
5
|
+
let body = arg != null && arg != '' ? JSON.parse(decodeURI(arg)) : { shownum: "2000", showpage: "1", fid: "", sname: '', rptcond: '', rptorder: '' }
|
|
6
|
+
let config = await getPackageJson(path);
|
|
7
|
+
let res = await postClass(config.setupSvc + "/api/ccfag/list", body, config.accessToken)
|
|
8
|
+
if (res.result) {
|
|
9
|
+
const simpleList = (res.data.list || []).map(item => ({
|
|
10
|
+
apiname: item.apiname,
|
|
11
|
+
id: item.id,
|
|
12
|
+
name: item.name
|
|
13
|
+
}))
|
|
14
|
+
if (!isMcp) {
|
|
15
|
+
console.log(JSON.stringify(simpleList))
|
|
16
|
+
}
|
|
17
|
+
return res.data.list
|
|
18
|
+
} else {
|
|
19
|
+
console.error('error:', res.message);
|
|
20
|
+
throw new Error('Get Class Failed: ' + res.message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = get;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const cc = {}
|
|
2
|
+
cc.create = require("./create")
|
|
3
|
+
cc.publish = require("./publish")
|
|
4
|
+
cc.pull = require("./pull")
|
|
5
|
+
cc.get = require("./get")
|
|
6
|
+
cc.pullList = require("./pullList")
|
|
7
|
+
cc.detail = require("./detail")
|
|
8
|
+
function Classes(action, argvs) {
|
|
9
|
+
cc[action](argvs[2], argvs[3])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = Classes;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { checkUpdate } = require("../../utils/checkVersion")
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path")
|
|
4
|
+
const chalk = require("chalk")
|
|
5
|
+
const { postClass } = require("../../utils/http")
|
|
6
|
+
|
|
7
|
+
const { javaContentRegular } = require("../../utils/utils")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const { getPackageJson } = require("../../utils/config")
|
|
11
|
+
|
|
12
|
+
async function publish(name) {
|
|
13
|
+
let res = await checkUpdate();
|
|
14
|
+
if (!res) {
|
|
15
|
+
console.error();
|
|
16
|
+
const now = new Date();
|
|
17
|
+
const timeStr = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0') + ' ' + String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0');
|
|
18
|
+
console.error(chalk.green(timeStr));
|
|
19
|
+
console.error(chalk.green('Posting, please wait...'));
|
|
20
|
+
console.error();
|
|
21
|
+
const classPath = path.join(process.cwd(), `classes/${name}/`);
|
|
22
|
+
let fullContent = fs.readFileSync(classPath + `${name}.java`, 'utf8');
|
|
23
|
+
|
|
24
|
+
const sourceMatch = fullContent.match(javaContentRegular);
|
|
25
|
+
let classContent = sourceMatch ? sourceMatch[1] : fullContent;
|
|
26
|
+
let configContent = JSON.parse(fs.readFileSync(classPath + "config.json", 'utf8'));
|
|
27
|
+
|
|
28
|
+
let body = {
|
|
29
|
+
"id": configContent.id,
|
|
30
|
+
"name": name,
|
|
31
|
+
"source": encodeURIComponent(classContent.trim()),
|
|
32
|
+
"version": configContent.version || "2",
|
|
33
|
+
"folderId": "wgd"
|
|
34
|
+
}
|
|
35
|
+
let config = await getPackageJson();
|
|
36
|
+
let res = await postClass(config.setupSvc + "/api/ccfag/save", body, config.accessToken)
|
|
37
|
+
if (res.result) {
|
|
38
|
+
console.error(chalk.green('Success!'));
|
|
39
|
+
console.error();
|
|
40
|
+
|
|
41
|
+
if (!configContent.id) {
|
|
42
|
+
configContent.id = res.data
|
|
43
|
+
fs.writeFileSync(path.join(classPath, "config.json"), JSON.stringify(configContent))
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
console.error(chalk.red('Publish Class Failed:' + res.returnInfo));
|
|
47
|
+
throw new Error('Publish Class Failed: ' + res.returnInfo);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
module.exports = publish;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const { checkUpdate } = require("../../utils/checkVersion")
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path")
|
|
4
|
+
const chalk = require("chalk")
|
|
5
|
+
|
|
6
|
+
const { javaContentRegular } = require("../../utils/utils")
|
|
7
|
+
|
|
8
|
+
const { getPackageJson } = require("../../utils/config")
|
|
9
|
+
const { postClass } = require("../../utils/http")
|
|
10
|
+
|
|
11
|
+
async function pull(name) {
|
|
12
|
+
let res = await checkUpdate();
|
|
13
|
+
if (!res) {
|
|
14
|
+
console.error();
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const timeStr = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0') + ' ' + String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0');
|
|
17
|
+
console.error(chalk.green(timeStr));
|
|
18
|
+
console.error(chalk.green('Pulling, please wait...'));
|
|
19
|
+
console.error();
|
|
20
|
+
const classPath = path.join(process.cwd(), `classes/${name}/`);
|
|
21
|
+
let configContent = JSON.parse(fs.readFileSync(classPath + "config.json", 'utf8'));
|
|
22
|
+
if (!configContent.id) {
|
|
23
|
+
console.error(chalk.red('Class ID is not exist, please publish first!'));
|
|
24
|
+
throw new Error('Class ID is not exist, please publish first!');
|
|
25
|
+
}
|
|
26
|
+
let body = {
|
|
27
|
+
"id": configContent.id,
|
|
28
|
+
}
|
|
29
|
+
let config = await getPackageJson();
|
|
30
|
+
let res = await postClass(config.setupSvc + "/api/ccfag/detail", body, config.accessToken)
|
|
31
|
+
if (res.result) {
|
|
32
|
+
console.error(chalk.green('Success!'));
|
|
33
|
+
console.error();
|
|
34
|
+
|
|
35
|
+
let fullContent = fs.readFileSync(classPath + `${name}.java`, 'utf8');
|
|
36
|
+
|
|
37
|
+
let newContent = '';
|
|
38
|
+
if (fullContent.includes("@SOURCE_CONTENT_START")) {
|
|
39
|
+
newContent = fullContent.replace(
|
|
40
|
+
javaContentRegular,
|
|
41
|
+
`// @SOURCE_CONTENT_START\n${res.data.trigger.source}\n// @SOURCE_CONTENT_END`
|
|
42
|
+
);
|
|
43
|
+
} else {
|
|
44
|
+
newContent = res.data.trigger.source;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fs.writeFileSync(classPath + `${name}.java`, newContent, 'utf8');
|
|
48
|
+
|
|
49
|
+
} else {
|
|
50
|
+
console.error(chalk.red('Pull Class Failed:' + res.returnInfo));
|
|
51
|
+
throw new Error('Pull Class Failed: ' + res.returnInfo);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
module.exports = pull;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path")
|
|
3
|
+
const { getPackageJson } = require("../../utils/config");
|
|
4
|
+
const { postClass } = require("../../utils/http");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Batch pull class details and generate local files
|
|
8
|
+
* @param class id
|
|
9
|
+
*/
|
|
10
|
+
async function pullList(id, url, isMcp = false) {
|
|
11
|
+
let config = await getPackageJson(url);
|
|
12
|
+
const body = { id };
|
|
13
|
+
const res = await postClass(config.setupSvc + "/api/ccfag/detail", body, config.accessToken);
|
|
14
|
+
try {
|
|
15
|
+
const data = res.data;
|
|
16
|
+
const trigger = data.trigger;
|
|
17
|
+
const className = trigger.name;
|
|
18
|
+
const folderPath = path.join(url, `classes/${trigger.name}`);
|
|
19
|
+
// 3. Check and create folder
|
|
20
|
+
if (!fs.existsSync(folderPath)) {
|
|
21
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
// 4. Create class file
|
|
24
|
+
const javaFile = path.join(folderPath, `${className}.java`);
|
|
25
|
+
const javaContent = `package classes.${className};\n\nimport com.cloudcc.core.*;\n// @SOURCE_CONTENT_START\n${trigger.source}\n// @SOURCE_CONTENT_END\n`;
|
|
26
|
+
fs.writeFileSync(javaFile, javaContent, "utf8");
|
|
27
|
+
// 5. Create config.json
|
|
28
|
+
const configJson = {
|
|
29
|
+
name: trigger.name,
|
|
30
|
+
version: "2",
|
|
31
|
+
id: trigger.id || id
|
|
32
|
+
};
|
|
33
|
+
fs.writeFileSync(path.join(folderPath, "config.json"), JSON.stringify(configJson, null, 4), "utf8");
|
|
34
|
+
// 6. Create test class
|
|
35
|
+
const testClassName = `${className}Test`;
|
|
36
|
+
const testContent = `package classes.${className};\n\nimport com.cloudcc.core.*;\n\npublic class ${testClassName} {\n public static void main(String[] args) {\n System.out.println(\"name:\");\n }\n}\n`;
|
|
37
|
+
fs.writeFileSync(path.join(folderPath, `${testClassName}.java`), testContent, "utf8");
|
|
38
|
+
if (!isMcp) {
|
|
39
|
+
console.log("true");
|
|
40
|
+
}
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.error(`Error occurred while processing class id: ${id}, message: ${e.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = pullList;
|
package/src/mcp/index.js
CHANGED
|
@@ -20,6 +20,10 @@ const customObjectHandler = require('./tools/Object Creator/handler.js');
|
|
|
20
20
|
const objectListHandler = require('./tools/Object List Retriever/handler.js');
|
|
21
21
|
const objectFieldsHandler = require('./tools/Object Fields Retriever/handler.js');
|
|
22
22
|
const fieldCreatorHandler = require('./tools/Object Fields Creator/handler.js');
|
|
23
|
+
// 菜单相关工具处理器
|
|
24
|
+
const menuCreatorHandler = require('./tools/Menu Creator/handler.js');
|
|
25
|
+
// 应用相关工具处理器
|
|
26
|
+
const applicationCreatorHandler = require('./tools/Application Creator/handler.js');
|
|
23
27
|
// 自定义类工具处理器
|
|
24
28
|
const classesHandler = require("./tools/Class List Retriever/handler.js");
|
|
25
29
|
const classCreatorHandler = require('./tools/Class Creator/handler.js');
|
|
@@ -58,7 +62,7 @@ const clientScriptPublisherHandler = require('./tools/Client Script Publisher/ha
|
|
|
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',
|
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
|
+
* 创建自定义对象菜单
|