cloudcc-cli 2.2.7 → 2.2.8

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version_check": {
3
- "timestamp": 1773815782543
3
+ "timestamp": 1773991959371
4
4
  },
5
5
  "Je6yZ0TRyQFtpcH1gVKctqNhL": {
6
6
  "username": "admin@testuat.com",
@@ -30,9 +30,9 @@
30
30
  "safetyMark": "QVOllKTKhnm5oHp49tCsSHvHg",
31
31
  "buildVersion": "v2",
32
32
  "apiSvc": "https://yundong.lightning.cloudcc.cn/ccdomaingateway/apisvc",
33
- "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJjbG91ZGNjIiwibG9naW5OYW1lIjoiYXBwc3RvcmVAY2xvdWRjYy5jbiIsImJpbmRpbmciOiJjYjhhZTY5MS0yNjJhLTRiMmEtOTVmNS05ODY3ZGIxYTNlYTEiLCJDbGllbnRJZCI6ImJJQTFJWFJIbDI4aEJrYVFkaXdRNjNoWloiLCJleHAiOjE3NzM5OTA4NzksIm9yZ0lkIjoib3JnOTY5Nzg4MjMyMGRjNzFmMjgifQ.lbROZu-5HCTHgOlqrWqWbR_oVIV7uTjh8sqiPGGkmis",
33
+ "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJjbG91ZGNjIiwibG9naW5OYW1lIjoiYXBwc3RvcmVAY2xvdWRjYy5jbiIsImJpbmRpbmciOiJhZDRmYWE4Ny0yNzZkLTRkNjQtYTcxZi0yZjdmZWUwNmExYTIiLCJDbGllbnRJZCI6ImJJQTFJWFJIbDI4aEJrYVFkaXdRNjNoWloiLCJleHAiOjE3NzQxNjQ3NjEsIm9yZ0lkIjoib3JnOTY5Nzg4MjMyMGRjNzFmMjgifQ.x2NLnkbHtx9J1qKMBG04PWVjoplNJFR6dpDNZLz28m0",
34
34
  "secretKey": "d99313b4298544bc8ca1ee7459227b",
35
- "pluginToken": "unified2026546fe51ba",
36
- "timestamp": 1773818080344
35
+ "pluginToken": "unified2026624c45632",
36
+ "timestamp": 1773991961909
37
37
  }
38
38
  }
package/README.md CHANGED
@@ -22,6 +22,18 @@ sudo npm i -g cloudcc-cli
22
22
  }
23
23
  ```
24
24
 
25
+ # ReleaseV2.2.8
26
+
27
+ #### Release Date: 2026-3-24
28
+
29
+ #### Release Scope: Full
30
+
31
+ #### Release Content
32
+
33
+ - Optimization
34
+ - Adjusted custom component `publish` and `pull`
35
+ - Fixed the issue where publishing components writes back the ID
36
+
25
37
  # ReleaseV2.2.7
26
38
 
27
39
  #### Release Date: 2026-3-20
@@ -31,8 +43,8 @@ sudo npm i -g cloudcc-cli
31
43
  #### Release Content
32
44
 
33
45
  - Optimization
34
- - 规范mcp使用,必须调用cc命令
35
- - 提供了skill,用于访问cc命令
46
+ - Standardized MCP usage: the `cc` command must be used
47
+ - Added a skill for accessing the `cc` command
36
48
 
37
49
  # ReleaseV2.2.6
38
50
 
@@ -5,6 +5,12 @@ description: CloudCC CRM 二次开发 CLI 助手。用于需求拆解与方案
5
5
 
6
6
  # CloudCC CLI Development Skill
7
7
 
8
+ ## cloudcc-cli
9
+ - 需要检查全局是否安装了cloudcc-cli npm包,如果没有请先安装。
10
+
11
+ ## 工作目录
12
+ - 在openclaw环境中,需要在agent的workspace中创建code文件夹,然后在code文件中使用cc create project xxx,创建一个模版项目。
13
+
8
14
  ## 使用方式(AI 必须遵循)
9
15
 
10
16
  - 先阅读 `REQUIREMENTS_BREAKDOWN.md`,输出需求拆解与交付物清单,再进入落地步骤。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcc-cli",
3
- "version": "2.2.7",
3
+ "version": "2.2.8",
4
4
  "description": "cloudcc-cli",
5
5
  "author": "cloudcc",
6
6
  "license": "ISC",
package/src/plugin/get.js CHANGED
@@ -9,7 +9,6 @@ async function get(argvs, isMcp = false) {
9
9
  const projectPath = argvs[2];
10
10
  try {
11
11
  const devConsoleConfig = await getPackageJson(projectPath);
12
- console.error("devConsoleConfig.accessToken", devConsoleConfig);
13
12
  if (!devConsoleConfig) {
14
13
  throw new Error('Configuration not found');
15
14
  }
@@ -19,6 +19,7 @@ class Builder {
19
19
 
20
20
  }
21
21
  }
22
+ this.pluginConfigPath = ""
22
23
  this.plugin = process.argv.splice(2)[0]
23
24
  }
24
25
  async publish(argvs) {
@@ -27,7 +28,8 @@ class Builder {
27
28
  if (!res) {
28
29
  this.options.devConsoleConfig = await getPackageJson();
29
30
  this.options.devConsoleConfig.CloudCCDev = "";
30
- this.options.pluginConfig = JSON.parse(fs.readFileSync(path.join(process.cwd(), `plugins/${name}/config.json`), 'utf8'));
31
+ this.pluginConfigPath = path.join(process.cwd(), `plugins/${name}/config.json`);
32
+ this.options.pluginConfig = JSON.parse(fs.readFileSync(this.pluginConfigPath, 'utf8'));
31
33
  let config = this.options.devConsoleConfig
32
34
  if ("private" != this.options.devConsoleConfig.version) {
33
35
  config = { "accessToken": this.options.devConsoleConfig.pluginToken || await this.getToken(config) };
@@ -42,14 +44,14 @@ class Builder {
42
44
  let obj = this.getVueValue(item);
43
45
  if (obj) {
44
46
  this.initPluginFile(item, obj, "plginTemp" + i);
45
- this.build(obj, config, "plginTemp" + i)
47
+ await this.build(obj, config, "plginTemp" + i)
46
48
  }
47
49
  }
48
50
  } else {
49
51
  let obj = this.getVueValue(answers.buildFileName);
50
52
  if (obj) {
51
53
  this.initPluginFile(answers.buildFileName, obj, "plginTemp");
52
- this.build(obj, config, "plginTemp")
54
+ await this.build(obj, config, "plginTemp")
53
55
  }
54
56
  }
55
57
  }
@@ -188,13 +190,12 @@ class Builder {
188
190
  }
189
191
  vueData = JSON.stringify(data);
190
192
 
191
- // 收集所有依赖文件
192
- const baseDir = path.join(process.cwd(), 'plugins');
193
- const entryFile = path.join(baseDir, buildFileName);
194
- const allDependencies = collectDependenciesWithTree(entryFile, baseDir);
193
+ // 收集所有依赖文件(相对路径以项目根为基准,便于线上还原为 plugins/...、utils/...)
194
+ const rootDir = process.cwd();
195
+ const entryFile = path.join(rootDir, 'plugins', buildFileName);
196
+ const allDependencies = collectDependenciesWithTree(entryFile, rootDir);
195
197
 
196
198
  // 收集根目录下的配置文件
197
- const rootDir = process.cwd();
198
199
  const configFiles = ['package.json', 'cloudcc-cli.config.js'];
199
200
 
200
201
  for (const configFile of configFiles) {
@@ -277,18 +278,26 @@ class Builder {
277
278
 
278
279
  build(obj, config, plginTemp) {
279
280
  console.error(chalk.green('Compiling, Please Wait...'));
280
- exec('npx vue-cli-service build --target lib --name ' + obj.component + ` --dest build plugins/${plginTemp}.js`, async (error, stdout, stderr) => {
281
- if (error) {
282
- console.error('Compilation Failed:', error);
283
- console.error(chalk.red('Compilation Failed:' + stdout));
284
- return;
285
- } else {
286
- console.error(chalk.green('Compilation Successful!'));
287
- console.error();
288
- await this.upload(obj, config)
289
- fs.unlinkSync(`plugins/${plginTemp}.js`);
290
- }
291
- })
281
+ return new Promise((resolve, reject) => {
282
+ exec('npx vue-cli-service build --target lib --name ' + obj.component + ` --dest build plugins/${plginTemp}.js`, async (error, stdout) => {
283
+ if (error) {
284
+ console.error('Compilation Failed:', error);
285
+ console.error(chalk.red('Compilation Failed:' + stdout));
286
+ reject(error);
287
+ return;
288
+ }
289
+
290
+ try {
291
+ console.error(chalk.green('Compilation Successful!'));
292
+ console.error();
293
+ await this.upload(obj, config)
294
+ fs.unlinkSync(`plugins/${plginTemp}.js`);
295
+ resolve();
296
+ } catch (uploadError) {
297
+ reject(uploadError);
298
+ }
299
+ })
300
+ });
292
301
  }
293
302
 
294
303
  async upload(obj, header) {
@@ -323,6 +332,11 @@ class Builder {
323
332
  let res = await post(`${this.options.devConsoleConfig.baseUrl || BaseUrl}${devSvcDispatch}/custom/pc/1.0/post/insertCustomComp`,
324
333
  body, header);
325
334
  if (res.returnCode == 200) {
335
+ const returnedId = res?.data?.id || res?.data;
336
+ if (!this.options.pluginConfig.id && returnedId && this.pluginConfigPath) {
337
+ this.options.pluginConfig.id = returnedId;
338
+ fs.writeFileSync(this.pluginConfigPath, JSON.stringify(this.options.pluginConfig, null, 2), 'utf8');
339
+ }
326
340
  console.error(chalk.green(`Success!`));
327
341
  console.error();
328
342
  } else {
@@ -5,6 +5,66 @@ const { getPackageJson } = require("../../utils/config");
5
5
  const { post } = require("../../utils/http");
6
6
  const BaseUrl = "https://developer.apis.cloudcc.cn";
7
7
 
8
+ /**
9
+ * 反复去掉路径开头的插件目录名,避免 plugins/foo/foo/foo.vue 这类重复嵌套
10
+ */
11
+ function stripLeadingPluginSegments(rest, pluginNames) {
12
+ const names = [...new Set(pluginNames.filter(Boolean))];
13
+ let guard = 0;
14
+ while (guard++ < 64) {
15
+ let stripped = false;
16
+ for (const n of names) {
17
+ const p = n + '/';
18
+ if (rest.startsWith(p)) {
19
+ rest = rest.slice(p.length);
20
+ stripped = true;
21
+ break;
22
+ }
23
+ }
24
+ if (!stripped) break;
25
+ }
26
+ return rest;
27
+ }
28
+
29
+ /**
30
+ * 根据服务端键解析本地绝对路径(与 publish 侧「项目根相对路径」一致)
31
+ */
32
+ function resolvePullFileFullPath(filePath, projectPath, pluginPath, normalizedPluginName, pluginName) {
33
+ const normalized = filePath.replace(/\\/g, '/').replace(/^\.\//, '');
34
+ const pluginNames = [normalizedPluginName, pluginName].filter(Boolean);
35
+
36
+ // 旧版发布:依赖键相对 plugins 目录为 ../utils/...
37
+ if (normalized.startsWith('../')) {
38
+ const trimmed = normalized.replace(/^\.\.\/+/, '');
39
+ return path.join(projectPath, trimmed);
40
+ }
41
+
42
+ // 键本身就在项目根下(无 plugins/ 前缀),如 utils/http.js
43
+ if (!normalized.startsWith('plugins/')) {
44
+ if (normalized.startsWith('utils/') || normalized.startsWith('src/') || normalized.startsWith('lib/')) {
45
+ return path.join(projectPath, normalized);
46
+ }
47
+ }
48
+
49
+ let rest = normalized;
50
+ if (rest.startsWith('plugins/')) {
51
+ rest = rest.slice('plugins/'.length);
52
+ }
53
+
54
+ rest = stripLeadingPluginSegments(rest, pluginNames);
55
+
56
+ // 仅文件名 http.js 落在插件根时,按工程惯例放到 utils/http.js(对应 import ../../utils/http)
57
+ if (rest === 'http.js') {
58
+ return path.join(projectPath, 'utils', 'http.js');
59
+ }
60
+
61
+ if (!rest || rest === '.') {
62
+ return pluginPath;
63
+ }
64
+
65
+ return path.join(pluginPath, rest);
66
+ }
67
+
8
68
  /**
9
69
  * 从服务器拉取自定义组件到本地
10
70
  * 支持通过组件名或ID拉取:
@@ -100,45 +160,23 @@ async function pullById(pluginId, projectPath) {
100
160
 
101
161
  // 遍历所有文件并保存
102
162
  Object.entries(contentMap).forEach(([filePath, content]) => {
103
- // 统一路径分隔符(服务端可能返回 Windows 风格的反斜杠)
104
- filePath = filePath.replace(/\\/g, '/');
163
+ const normalizedPath = filePath.replace(/\\/g, '/');
105
164
 
106
165
  // 获取文件名(不包含路径)
107
- const fileName = path.basename(filePath);
166
+ const fileName = path.basename(normalizedPath);
108
167
 
109
168
  // 跳过排除的文件
110
169
  if (excludedFiles.includes(fileName)) {
111
170
  return;
112
171
  }
113
172
 
114
- // 处理文件路径:去掉组件名称前缀
115
- // 例如:cc-ttt/cc-ttt.vue -> cc-ttt.vue
116
- // cc-ttt/components/HelloWorld.vue -> components/HelloWorld.vue
117
- // cc-demo/cc-demo.vue -> cc-demo.vue (当组件名是 component-cc-demo-cc 时)
118
- let relativePath = filePath;
119
-
120
- // 提取文件路径的第一个目录名
121
- const firstDir = filePath.split('/')[0];
122
-
123
- // 尝试匹配并移除前缀
124
- // 优先级:1. normalizedPluginName 2. pluginName 3. 第一个目录名(如果路径包含多个部分)
125
- let prefixToRemove = '';
126
- if (filePath.startsWith(`${normalizedPluginName}/`)) {
127
- prefixToRemove = `${normalizedPluginName}/`;
128
- } else if (filePath.startsWith(`${pluginName}/`)) {
129
- prefixToRemove = `${pluginName}/`;
130
- } else if (firstDir && filePath.includes('/')) {
131
- // 如果路径包含斜杠,说明有目录结构,移除第一个目录
132
- // 例如:cc-demo/cc-demo.vue -> cc-demo.vue
133
- prefixToRemove = `${firstDir}/`;
134
- }
135
-
136
- if (prefixToRemove) {
137
- relativePath = filePath.substring(prefixToRemove.length);
138
- }
139
-
140
- // 构建完整路径并写入文件
141
- const fullPath = path.join(pluginPath, relativePath);
173
+ const fullPath = resolvePullFileFullPath(
174
+ normalizedPath,
175
+ projectPath,
176
+ pluginPath,
177
+ normalizedPluginName,
178
+ pluginName
179
+ );
142
180
  const dir = path.dirname(fullPath);
143
181
 
144
182
  // 确保目录存在(recursive: true 会自动处理已存在的情况)
Binary file
@@ -0,0 +1,3 @@
1
+ artifactId=ccopenapi
2
+ groupId=com.cloudcc.core
3
+ version=0.0.4
@@ -0,0 +1,20 @@
1
+ com/cloudcc/core/CCObject.class
2
+ com/cloudcc/core/TriggerTimeEnum.class
3
+ com/cloudcc/core/UserInfo.class
4
+ com/cloudcc/core/SendEmail.class
5
+ com/cloudcc/core/BusiException.class
6
+ com/cloudcc/core/PeakInterf.class
7
+ com/cloudcc/core/TimeUtil.class
8
+ com/cloudcc/core/CCTriggerHandler.class
9
+ com/cloudcc/core/Tool.class
10
+ com/cloudcc/core/TriggerInvoker.class
11
+ com/cloudcc/core/CCSchedule.class
12
+ com/cloudcc/core/BaseException.class
13
+ com/cloudcc/core/OperatationEnum.class
14
+ com/cloudcc/core/TriggerMethod.class
15
+ com/cloudcc/core/ServiceResult.class
16
+ com/cloudcc/core/StringUtils.class
17
+ com/cloudcc/core/DevLogger.class
18
+ com/cloudcc/core/CCService.class
19
+ com/cloudcc/core/CCTrigger.class
20
+ com/cloudcc/core/Tool$1.class
@@ -0,0 +1,19 @@
1
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/ServiceResult.java
2
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/TriggerInvoker.java
3
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/UserInfo.java
4
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/Tool.java
5
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/CCService.java
6
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/CCSchedule.java
7
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/SendEmail.java
8
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/OperatationEnum.java
9
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/BaseException.java
10
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/CCTriggerHandler.java
11
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/TriggerMethod.java
12
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/TriggerTimeEnum.java
13
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/CCTrigger.java
14
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/StringUtils.java
15
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/BusiException.java
16
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/DevLogger.java
17
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/PeakInterf.java
18
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/TimeUtil.java
19
+ /Users/xuhm/Documents/cloudcc-cli/java/com/cloudcc/core/CCObject.java
File without changes
File without changes