cloudcc-cli 2.4.0 → 2.4.2

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.
Files changed (49) hide show
  1. package/README.md +60 -0
  2. package/bin/index.js +5 -0
  3. package/cloudcc-dev-skill/SKILL.md +6 -12
  4. package/cloudcc-dev-skill/config.json +2 -2
  5. package/mcp/index.js +9 -4
  6. package/mcp/tools/Trigger List Retriever/handler.js +24 -8
  7. package/package.json +2 -2
  8. package/src/classes/create.js +1 -1
  9. package/src/classes/docs/devguide.md +138 -25
  10. package/src/config/use.js +20 -5
  11. package/src/dupeCatcher/create.js +76 -0
  12. package/src/dupeCatcher/delete.js +69 -0
  13. package/src/dupeCatcher/detail.js +57 -0
  14. package/src/dupeCatcher/doc.js +11 -0
  15. package/src/dupeCatcher/docs/devguide.md +125 -0
  16. package/src/dupeCatcher/docs/introduction.md +21 -0
  17. package/src/dupeCatcher/get.js +88 -0
  18. package/src/dupeCatcher/index.js +14 -0
  19. package/src/html/doc.js +35 -0
  20. package/src/html/docs/devguide.md +67 -0
  21. package/src/html/docs/introduction.md +4 -0
  22. package/src/html/index.js +11 -0
  23. package/src/openapi/cloudcc-openapi-sdk.js +1085 -0
  24. package/src/openapi/doc.js +30 -0
  25. package/src/openapi/docs/devguide.md +65 -0
  26. package/src/openapi/docs/introduction.md +43 -0
  27. package/src/openapi/get.js +45 -0
  28. package/src/openapi/index.js +12 -0
  29. package/src/plugin/publish1.js +1 -1
  30. package/src/plugin/pull.js +2 -2
  31. package/src/script/docs/devguide.md +22 -2
  32. package/src/sharingRule/doc.js +46 -0
  33. package/src/sharingRule/docs/devguide.md +28 -0
  34. package/src/sharingRule/docs/introduction.md +7 -0
  35. package/src/sharingRule/get.js +48 -0
  36. package/src/sharingRule/index.js +9 -0
  37. package/src/site/doc.js +35 -0
  38. package/src/site/docs/devguide.md +209 -0
  39. package/src/site/docs/introduction.md +4 -0
  40. package/src/site/index.js +11 -0
  41. package/src/timer/docs/devguide.md +218 -29
  42. package/src/triggers/docs/devguide.md +247 -127
  43. package/src/triggers/get.js +7 -0
  44. package/src/version/doctor.js +11 -4
  45. package/src/version/listModuleCommands.js +20 -0
  46. package/template/index.js +2 -2
  47. package/utils/config.js +129 -21
  48. package/cloudcc-dev-skill/cloudcc-dev-html.md +0 -42
  49. package/template/cloudcc-cli.configjs +0 -7
package/README.md CHANGED
@@ -71,6 +71,66 @@ Resolve the script path on macOS/Linux with:
71
71
  echo "$(npm root -g)/cloudcc-cli/bin/mcp.js"
72
72
  ```
73
73
 
74
+ # ReleaseV2.4.2
75
+
76
+ #### Release Date: 2026-4-9
77
+
78
+ #### Release Scope: Full
79
+
80
+ #### Release Content
81
+
82
+ - Config resilience
83
+ - Fixed `utils/config.js` fallback flow so commands no longer throw `ENOENT` when `package.json` is missing in the current working directory
84
+ - Added safe existence check and parse guard for legacy `devConsoleConfig` loading to continue with cache/v3/v2 config sources
85
+ - Release maintenance
86
+ - Bumped package version to `2.4.2` and synchronized lockfile root version metadata
87
+ - Dupe Catcher module
88
+ - Added a new `dupeCatcher` resource with `get`, `detail`, `create`, `delete`, and `doc` actions for filter/rule management
89
+ - Added `src/dupeCatcher/docs/devguide.md` with command contracts and payload guidance
90
+ - Sharing Rule module
91
+ - Added a new `sharingRule` resource focused on object-based rule query via `cloudcc get sharingRule <objid> [projectPath]`
92
+ - Integrated sharing rule docs (`introduction` and `devguide`) aligned to the query-only workflow
93
+ - CLI discovery and routing
94
+ - Registered `dupeCatcher` and `sharingRule` in `bin/index.js` and help metadata (`src/version/listModuleCommands.js`) so `cloudcc --help` and `cloudcc get -h` can discover both modules
95
+ - HTML docs module
96
+ - Added a new `html` resource with `cloudcc doc html <introduction|devguide>` for single-file HTML component guidance
97
+ - Added `src/html/docs/introduction.md` and `src/html/docs/devguide.md`, including static-resource referencing guidance for JS/CSS/image assets
98
+ - Skill alignment
99
+ - Updated `cloudcc-dev-skill/SKILL.md` to route HTML component guidance through `cloudcc doc html introduction|devguide`
100
+ - Site docs module
101
+ - Added a new `site` resource with `cloudcc doc site <introduction|devguide>` to provide standalone site development guidance
102
+ - Added `src/site/docs/introduction.md`, `src/site/docs/devguide.md`, and frontend aesthetics references under `src/site/docs/frontend_aesthetics/`
103
+ - OpenAPI browser SDK module
104
+ - Added a new `openapi` resource with `cloudcc get openapi [targetDir] [outputFileName]` to copy browser SDK files into standalone site projects
105
+ - Added `cloudcc doc openapi <introduction|devguide>` and module docs for account/password login and object API access from independent sites
106
+ - CLI help and routing updates
107
+ - Registered `site` and `openapi` in routing/help metadata so `cloudcc --help` and `cloudcc get -h` can discover the new resources
108
+ - Skill package cleanup
109
+ - Removed deprecated `cloudcc-dev-html` skill file and aligned `cloudcc-dev-skill` version metadata for consolidated site guidance
110
+ - Project configuration (JSON)
111
+ - Added `cloudcc-cli.config.json` support via `getPackageJson4` in `utils/config.js` so projects with `package.json` `"type":"module"` are not blocked by CommonJS `require` on `.js` config
112
+ - `getPackageJson` now resolves JSON after cache and before legacy JS loaders (`getPackageJson3` / `getPackageJson2`); `loadCloudccConfigRootSync` and `resolveCloudccConfigFile` prefer JSON when both `.json` and `.js` exist
113
+ - `cloudcc create project` scaffolds `cloudcc-cli.config.json` (replaces the former `template/cloudcc-cli.configjs` template)
114
+ - Updated `config use`, `doctor`, plugin pull/publish ignore lists, `.npmignore`, and `classes` error text to recognize the new config filename
115
+
116
+ # ReleaseV2.4.1
117
+
118
+ #### Release Date: 2026-4-9
119
+
120
+ #### Release Scope: Full
121
+
122
+ #### Release Content
123
+
124
+ - Docs alignment
125
+ - Refined `devguide` structure for `classes`, `timer`, and `triggers` to focus on implementation rules and avoid duplicated concept sections covered by `introduction`
126
+ - Added complete CLI command and argument sections in `classes` and `triggers` devguides, aligned with actual module handlers
127
+ - Expanded `timer` devguide command/argument coverage for all supported actions (`create`, `publish`, `pull`, `get`, `detail`, `pullList`, `delete`, `doc`)
128
+ - Query parameter documentation
129
+ - Added trigger list query field documentation in trigger devguide, including `fid`/`objId` semantics
130
+ - Clarified script list query docs: `condition.objName` is the query field and its value should be object **label** (not API name)
131
+ - MCP consistency
132
+ - Extended trigger list MCP schema and handler parameters (`objId`, paging, filter, sort) and aligned descriptions with CLI query body usage
133
+
74
134
  # ReleaseV2.4.0
75
135
 
76
136
  #### Release Date: 2026-4-8
package/bin/index.js CHANGED
@@ -11,6 +11,8 @@ const modules = {
11
11
  triggers: require("../src/triggers/index"),
12
12
  timer: require("../src/timer/index"),
13
13
  script: require("../src/script/index"),
14
+ html: require("../src/html/index"),
15
+ site: require("../src/site/index"),
14
16
  jsp: require("../src/jsp/index"),
15
17
  token: require("../src/token/index"),
16
18
  object: require("../src/object/index"),
@@ -29,7 +31,10 @@ const modules = {
29
31
  singleSignOn: require("../src/singleSignOn/index"),
30
32
  pagelayout: require("../src/pagelayout/index"),
31
33
  validationRule: require("../src/validationRule/index"),
34
+ dupeCatcher: require("../src/dupeCatcher/index"),
35
+ sharingRule: require("../src/sharingRule/index"),
32
36
  permission: require("../src/permission/index"),
37
+ openapi: require("../src/openapi/index"),
33
38
  };
34
39
 
35
40
  /**
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: cloudcc-dev-skill
3
- description: 用于 CloudCC CRM 二次开发设计与实施。优先通过 `cloudcc doc <module> introduction|devguide` 获取官方模块文档,再给出方案与代码。用户提到 CloudCC、cloudcc-cli、模块文档、对象/字段、权限、触发器、类、组件、页面、脚本、JSP迁移、静态资源、菜单、应用、单点登录、身份提供方、校验规则时应优先使用。
3
+ description: 用于 CloudCC CRM 二次开发设计与实施。优先通过 `cloudcc doc <module> introduction|devguide` 获取官方模块文档,再给出方案与代码。用户提到 CloudCC、cloudcc-cli、模块文档、对象/字段、权限、触发器、类、组件、页面、脚本、JSP 迁移、静态资源、菜单、应用、单点登录、身份提供方、校验规则、查重过滤器(Dupe Catcher)、重复/去重、共享规则时应优先使用。
4
4
  ---
5
5
 
6
6
  # CloudCC CRM 二开技能
@@ -34,7 +34,9 @@ description: 用于 CloudCC CRM 二次开发设计与实施。优先通过 `clou
34
34
  - 全局选项:`cloudcc doc globalSelectList introduction`、`cloudcc doc globalSelectList devguide`
35
35
  - 按钮:`cloudcc doc button introduction`、`cloudcc doc button devguide`
36
36
  - 页面布局:`cloudcc doc pagelayout introduction`、`cloudcc doc pagelayout devguide`
37
- - 校验规则:`cloudcc doc validationRule introduction`、`cloudcc doc validationRule devguide`
37
+ - 验证规则:`cloudcc doc validationRule introduction`、`cloudcc doc validationRule devguide`
38
+ - 查重过滤器(dupeCatcher):`cloudcc doc dupeCatcher introduction`、`cloudcc doc dupeCatcher devguide`
39
+ - 共享规则(sharingRule):`cloudcc doc sharingRule introduction`、`cloudcc doc sharingRule devguide`
38
40
 
39
41
  ### 组织与权限
40
42
 
@@ -53,7 +55,8 @@ description: 用于 CloudCC CRM 二次开发设计与实施。优先通过 `clou
53
55
  ### 前端扩展
54
56
 
55
57
  - 自定义Vue组件:`cloudcc doc plugin introduction`、`cloudcc doc plugin devguide`
56
- - 自定义Html组件:`./cloudcc-dev-html.md`
58
+ - 自定义 HTML 组件:`cloudcc doc html introduction`、`cloudcc doc html devguide`
59
+ - Site 开发规范:`cloudcc doc site introduction`、`cloudcc doc site devguide`
57
60
  - 自定义页面:`cloudcc doc customPage introduction`、`cloudcc doc customPage devguide`
58
61
  - 客户端脚本:`cloudcc doc script introduction`、`cloudcc doc script devguide`
59
62
  - 静态资源:`cloudcc doc staticResource introduction`、`cloudcc doc staticResource devguide`
@@ -90,12 +93,3 @@ description: 用于 CloudCC CRM 二次开发设计与实施。优先通过 `clou
90
93
  - **发布日志/Release Notes 规则(强制)**:凡是更新发布记录、版本日志、README 中
91
94
  `Release`/`Release Notes`
92
95
  区块,内容必须使用英文(标题、日期标签、条目描述均不得使用中文)。
93
-
94
- ## 快速规则
95
-
96
- - 先确认 CLI 可用:优先检查 `cloudcc --version`。
97
- - 若未安装,执行:`npm i -g cloudcc-cli@latest`。
98
- - 当进行 CloudCC 方案设计时,必须读取所有模块的`introduction`文档后,再设计
99
- - 当进行 CloudCC 方案开发时,需要读取,对应模块的`devguide`信息后,再开发
100
- - 命令统一格式:`cloudcc doc <module> <introduction|devguide>`。
101
- - 特例:`config` 仅支持 `devguide`,不支持 `introduction`。
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "1.0.3",
3
- "releaseDate": "2026-04-07"
2
+ "version": "1.0.6",
3
+ "releaseDate": "2026-04-09"
4
4
  }
package/mcp/index.js CHANGED
@@ -394,10 +394,15 @@ mcpServer.registerTool(
394
394
  mcpServer.registerTool(
395
395
  'get_trigger_list',
396
396
  {
397
- description: '获取 CloudCC CRM 服务器上的触发器列表,可选筛选条件',
398
- inputSchema: z.object({
399
- triggerName: z.string().optional().describe('可选,触发器名称(用于筛选)'),
400
- targetObjectId: z.string().optional().describe('可选,目标对象ID(用于筛选)'),
397
+ description: '获取 CloudCC CRM 服务器上的触发器列表。支持按触发器名称、对象ID筛选,并支持分页/扩展过滤/排序参数。',
398
+ inputSchema: z.object({
399
+ triggerName: z.string().optional().describe('可选,触发器名称(映射到查询字段 sname)'),
400
+ targetObjectId: z.string().optional().describe('可选,目标对象ID(映射到查询字段 fid)'),
401
+ objId: z.string().optional().describe('可选,目标对象ID语义化别名(会映射到 fid)'),
402
+ shownum: z.union([z.string(), z.number()]).optional().describe('可选,每页条数(默认 2000)'),
403
+ showpage: z.union([z.string(), z.number()]).optional().describe('可选,页码(默认 1)'),
404
+ rptcond: z.string().optional().describe('可选,扩展过滤条件(默认空字符串)'),
405
+ rptorder: z.string().optional().describe('可选,排序条件(默认空字符串)'),
401
406
  projectPath: z.string().describe('项目根目录路径,默认为当前工作目录')
402
407
  })
403
408
  },
@@ -9,20 +9,36 @@ const { runCcJsonCommand } = require('../../cliRunner');
9
9
  /**
10
10
  * 获取触发器列表
11
11
  * @param {Object} params - 参数对象
12
- * @param {string} params.triggerName - 可选,触发器名称(用于筛选)
13
- * @param {string} params.targetObjectId - 可选,目标对象ID(用于筛选)
12
+ * @param {string} params.triggerName - 可选,触发器名称(映射到 sname)
13
+ * @param {string} params.targetObjectId - 可选,目标对象ID(映射到 fid)
14
+ * @param {string} params.objId - 可选,目标对象ID(语义化别名,映射到 fid)
15
+ * @param {string|number} params.shownum - 可选,每页条数,默认 2000
16
+ * @param {string|number} params.showpage - 可选,页码,默认 1
17
+ * @param {string} params.rptcond - 可选,扩展过滤条件
18
+ * @param {string} params.rptorder - 可选,排序条件
14
19
  * @param {string} params.projectPath - 项目路径(可选,默认为当前工作目录)
15
20
  */
16
- async function listTriggers({ triggerName = '', targetObjectId = '', projectPath = process.cwd() }) {
21
+ async function listTriggers({
22
+ triggerName = '',
23
+ targetObjectId = '',
24
+ objId = '',
25
+ shownum = '2000',
26
+ showpage = '1',
27
+ rptcond = '',
28
+ rptorder = '',
29
+ projectPath = process.cwd()
30
+ }) {
17
31
  try {
18
32
  // 构造查询条件
33
+ const objectId = targetObjectId || objId || "";
19
34
  const queryBody = {
20
- shownum: "2000",
21
- showpage: "1",
22
- fid: targetObjectId || "",
35
+ shownum: String(shownum),
36
+ showpage: String(showpage),
37
+ fid: objectId,
23
38
  sname: triggerName || "",
24
- rptcond: '',
25
- rptorder: ''
39
+ rptcond: rptcond || '',
40
+ rptorder: rptorder || '',
41
+ objId: objectId
26
42
  };
27
43
 
28
44
  const resolvedPath = path.resolve(projectPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcc-cli",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "cloudcc-cli",
5
5
  "author": "cloudcc",
6
6
  "license": "ISC",
@@ -52,4 +52,4 @@
52
52
  "sass": "^1.98.0",
53
53
  "sass-loader": "^16.0.7"
54
54
  }
55
- }
55
+ }
@@ -17,7 +17,7 @@ async function create(argvs) {
17
17
  console.error()
18
18
  console.error(
19
19
  chalk.yellow(
20
- "No valid cloudcc-cli config for this project. Create or fix cloudcc-cli.config.js (see cloudcc doc project devguide)."
20
+ "No valid cloudcc-cli config for this project. Create or fix cloudcc-cli.config.json (or .js) (see cloudcc doc project devguide)."
21
21
  )
22
22
  )
23
23
  console.error()
@@ -25,39 +25,152 @@
25
25
 
26
26
  - CloudCC 官方后端 SDK 参考:`CCObject`、`UserInfo`、`CCService`、`SendEmail`、`DevLogger`、`TimeUtil`
27
27
 
28
- ## 3. AI 的总体职责
28
+ ## 3. introduction 的分工(避免重复)
29
29
 
30
- AI 在编写 CloudCC 自定义类时,应把自己视为“服务端业务能力设计者”,而不是“只补一段能跑代码的脚本工具”。
30
+ 为避免与 `classes introduction` 内容重复,本 `devguide` 只保留“开发落地规范”:
31
31
 
32
- AI 需要同时满足以下目标:
32
+ - 命令与入参(可直接执行)
33
+ - 目录与文件约束(可直接检查)
34
+ - SDK 用法与边界(可直接编码)
35
+ - 代码结构、禁止事项与自检清单(可直接评审)
33
36
 
34
- - 功能正确
35
- - 结构清晰
36
- - 可复用
37
- - 易排错
38
- - 易发布
37
+ “自定义类是什么、适用/不适用场景、能力边界、与其他实现方式差异”等概念说明,统一以 `cloudcc doc classes introduction` 为准。
39
38
 
40
- ## 4. 什么时候应该使用自定义类
39
+ ## 4. classes 模块支持的 CLI 命令总览(重点:入参)
41
40
 
42
- 满足以下任一情况时,AI 应优先选择自定义类实现:
41
+ 说明:
43
42
 
44
- - 逻辑需要在服务端执行
45
- - 一个动作会影响多个对象
46
- - 逻辑会被多个入口复用
47
- - 需要复杂规则计算
48
- - 需要流程状态推进
49
- - 需要调用外部系统
50
- - 需要处理附件、文件、目录
51
- - 需要统一日志、异常、时间处理
52
- - 需要自动通知、提醒、待办协同
53
- - 需要接入 AI 或分析能力
43
+ - 下文命令中的资源名使用 `classes`。
44
+ - `projectPath` 未传时,默认使用当前工作目录。
54
45
 
55
- 以下场景不要优先上自定义类:
46
+ #### 1) 创建自定义类
56
47
 
57
- - 只是简单展示
58
- - 只是轻量页面交互
59
- - 只是简单字段联动
60
- - 标准配置即可完成
48
+ 命令:
49
+
50
+ ```bash
51
+ cloudcc create classes <name>
52
+ ```
53
+
54
+ 参数:
55
+
56
+ | 参数 | 必填 | 类型 | 说明 |
57
+ | --- | --- | --- | --- |
58
+ | `name` | 是 | `string` | 类名(同时作为目录名、Java 主类名) |
59
+
60
+ #### 2) 发布自定义类
61
+
62
+ 命令:
63
+
64
+ ```bash
65
+ cloudcc publish classes <name>
66
+ ```
67
+
68
+ 参数:
69
+
70
+ | 参数 | 必填 | 类型 | 说明 |
71
+ | --- | --- | --- | --- |
72
+ | `name` | 是 | `string` | 本地 `classes/<name>/` 目录名 |
73
+
74
+ #### 3) 拉取自定义类(按本地名称)
75
+
76
+ 命令:
77
+
78
+ ```bash
79
+ cloudcc pull classes <name>
80
+ ```
81
+
82
+ 参数:
83
+
84
+ | 参数 | 必填 | 类型 | 说明 |
85
+ | --- | --- | --- | --- |
86
+ | `name` | 是 | `string` | 本地 `classes/<name>/` 目录名;会读取该目录 `config.json` 中的 `id` 拉取 |
87
+
88
+ #### 4) 查询自定义类列表(支持条件查询)
89
+
90
+ 命令:
91
+
92
+ ```bash
93
+ cloudcc get classes [listQueryJson] [projectPath]
94
+ ```
95
+
96
+ `listQueryJson` 推荐结构:
97
+
98
+ ```json
99
+ {
100
+ "shownum": 2000,
101
+ "showpage": 1,
102
+ "sname": ""
103
+ }
104
+ ```
105
+
106
+ 字段说明:
107
+
108
+ | 字段 | 类型 | 必填 | 说明 |
109
+ | --- | --- | --- | --- |
110
+ | `shownum` | `number|string` | 否 | 每页条数,默认 `2000` |
111
+ | `showpage` | `number|string` | 否 | 页码,默认 `1` |
112
+ | `sname` | `string` | 否 | 名称筛选关键字,模糊查询 |
113
+
114
+ #### 5) 查看自定义类详情
115
+
116
+ 命令:
117
+
118
+ ```bash
119
+ cloudcc detail classes <name> <id>
120
+ ```
121
+
122
+ 参数规则(实现口径):
123
+
124
+ | 参数 | 必填 | 类型 | 说明 |
125
+ | --- | --- | --- | --- |
126
+ | `name` | 条件必填 | `string` | 传 `name` 时优先查本地;本地不完整时再走线上 |
127
+ | `id` | 条件必填 | `string` | 当 `name` 为空时,必须传 `id` 走线上查询 |
128
+
129
+ 等价理解:`name` 与 `id` 至少传一个,优先使用 `name` 路径。
130
+
131
+ #### 6) 按 ID 拉取并落地到本地目录
132
+
133
+ 命令:
134
+
135
+ ```bash
136
+ cloudcc pullList classes <id> <projectPath>
137
+ ```
138
+
139
+ 参数:
140
+
141
+ | 参数 | 必填 | 类型 | 说明 |
142
+ | --- | --- | --- | --- |
143
+ | `id` | 是 | `string` | 线上自定义类 ID |
144
+ | `projectPath` | 是 | `string` | 项目根目录;会写入到 `<projectPath>/classes/<name>/` |
145
+
146
+ #### 7) 删除自定义类
147
+
148
+ 命令:
149
+
150
+ ```bash
151
+ cloudcc delete classes <nameOrId> [projectPath]
152
+ ```
153
+
154
+ 参数规则:
155
+
156
+ | 参数 | 必填 | 类型 | 说明 |
157
+ | --- | --- | --- | --- |
158
+ | `nameOrId` | 是 | `string` | 可传本地目录名或线上 ID;若本地 `classes/<nameOrId>/config.json` 存在且带 `id`,优先使用其中 `id` 删除 |
159
+ | `projectPath` | 否 | `string` | 项目根目录,默认当前目录 |
160
+
161
+ #### 8) 文档命令
162
+
163
+ 命令:
164
+
165
+ ```bash
166
+ cloudcc doc classes <introduction|devguide>
167
+ ```
168
+
169
+ 参数:
170
+
171
+ | 参数 | 必填 | 类型 | 说明 |
172
+ | --- | --- | --- | --- |
173
+ | `introduction|devguide` | 是 | `string` | `introduction` 返回概念文档;`devguide` 返回开发规范(并附 SDK 速查) |
61
174
 
62
175
  ## 5. AI 必须遵守的硬规则
63
176
 
package/src/config/use.js CHANGED
@@ -1,14 +1,29 @@
1
1
  const path = require("path")
2
2
  const fs = require("fs")
3
+ const { resolveCloudccConfigFile } = require("../../utils/config.js")
3
4
 
4
5
  function use(env, projectPath = process.cwd()) {
5
- let config = require(path.join(projectPath, "cloudcc-cli.config.js"));
6
- config.use = env;
7
- fs.writeFileSync(path.join(projectPath, "cloudcc-cli.config.js"),
6
+ const resolved = resolveCloudccConfigFile(projectPath)
7
+ if (!resolved) {
8
+ throw new Error("No cloudcc-cli.config.json or cloudcc-cli.config.js found")
9
+ }
10
+ if (resolved.kind === "json") {
11
+ const config = JSON.parse(fs.readFileSync(resolved.filePath, "utf8"))
12
+ config.use = env
13
+ fs.writeFileSync(resolved.filePath, JSON.stringify(config, null, 4) + "\n", "utf8")
14
+ return
15
+ }
16
+ const jsPath = resolved.filePath
17
+ delete require.cache[require.resolve(jsPath)]
18
+ const config = require(jsPath)
19
+ config.use = env
20
+ fs.writeFileSync(
21
+ jsPath,
8
22
  `module.exports =
9
23
  ${JSON.stringify(config)}
10
- `
11
- , 'utf8');
24
+ `,
25
+ "utf8"
26
+ )
12
27
  }
13
28
 
14
29
  module.exports = use;
@@ -0,0 +1,76 @@
1
+ const chalk = require("chalk")
2
+ const { getPackageJson } = require("../../utils/config")
3
+ const { postClass } = require("../../utils/http")
4
+
5
+ /**
6
+ * Supported:
7
+ * - cloudcc create dupeCatcher filter <encodedBodyJson> [projectPath]
8
+ * -> /api/duplication/saveFilter
9
+ *
10
+ * - cloudcc create dupeCatcher rule <encodedBodyJson> [projectPath]
11
+ * -> /api/duplication/nsaverule
12
+ */
13
+ function isPathLikeToken(v) {
14
+ if (typeof v !== "string" || !v) return false
15
+ return v === "." || v === ".." || /[\\/]/.test(v) || /:/.test(v)
16
+ }
17
+
18
+ async function request(projectPath, apiPath, body) {
19
+ const config = await getPackageJson(projectPath)
20
+ return await postClass(config.setupSvc + apiPath, body || {}, config.accessToken)
21
+ }
22
+
23
+ async function create(projectPath = process.cwd(), kind, encoded, isMcp = false) {
24
+ // compatibility: cloudcc create dupeCatcher filter <encoded> [projectPath]
25
+ if (!isPathLikeToken(projectPath)) {
26
+ encoded = kind
27
+ kind = projectPath
28
+ projectPath = process.cwd()
29
+ }
30
+
31
+ if (!kind || !encoded) {
32
+ throw new Error(
33
+ "Usage:\n" +
34
+ "- cloudcc create dupeCatcher filter <encodedBodyJson> [projectPath]\n" +
35
+ "- cloudcc create dupeCatcher rule <encodedBodyJson> [projectPath]"
36
+ )
37
+ }
38
+
39
+ let body
40
+ try {
41
+ body = JSON.parse(decodeURI(encoded))
42
+ } catch (e) {
43
+ throw new Error("Invalid encodedBodyJson (must be encodeURI(JSON.stringify(obj))). " + e.message)
44
+ }
45
+
46
+ if (kind === "filter") {
47
+ console.error()
48
+ console.error(chalk.green("Saving dupe catcher filter, please wait..."))
49
+ console.error()
50
+ const res = await request(projectPath, "/api/duplication/saveFilter", body)
51
+ if (res && res.result) {
52
+ const data = res.data || res
53
+ if (!isMcp) console.log(JSON.stringify(data))
54
+ return data
55
+ }
56
+ throw new Error("Create/Update DupeCatcher filter failed: " + (res?.returnInfo || res?.message || "Unknown error"))
57
+ }
58
+
59
+ if (kind === "rule") {
60
+ console.error()
61
+ console.error(chalk.green("Saving dupe catcher rule, please wait..."))
62
+ console.error()
63
+ const res = await request(projectPath, "/api/duplication/nsaverule", body)
64
+ if (res && res.result) {
65
+ const data = res.data || res
66
+ if (!isMcp) console.log(JSON.stringify(data))
67
+ return data
68
+ }
69
+ throw new Error("Create/Update DupeCatcher rule failed: " + (res?.returnInfo || res?.message || "Unknown error"))
70
+ }
71
+
72
+ throw new Error(`Unknown kind for create dupeCatcher: ${kind}. Expected 'filter' or 'rule'.`)
73
+ }
74
+
75
+ module.exports = create
76
+
@@ -0,0 +1,69 @@
1
+ const chalk = require("chalk")
2
+ const { getPackageJson } = require("../../utils/config")
3
+ const { postClass } = require("../../utils/http")
4
+
5
+ /**
6
+ * Supported:
7
+ * - cloudcc delete dupeCatcher filter <filterid> [projectPath]
8
+ * -> /api/duplication/deletefilter
9
+ *
10
+ * - cloudcc delete dupeCatcher rule <ruleid> [projectPath]
11
+ * -> /api/duplication/deleterule
12
+ */
13
+ function isPathLikeToken(v) {
14
+ if (typeof v !== "string" || !v) return false
15
+ return v === "." || v === ".." || /[\\/]/.test(v) || /:/.test(v)
16
+ }
17
+
18
+ async function request(projectPath, apiPath, body) {
19
+ const config = await getPackageJson(projectPath)
20
+ return await postClass(config.setupSvc + apiPath, body || {}, config.accessToken)
21
+ }
22
+
23
+ async function del(projectPath = process.cwd(), kind, id, isMcp = false) {
24
+ // compatibility: cloudcc delete dupeCatcher filter <id> [projectPath]
25
+ if (!isPathLikeToken(projectPath)) {
26
+ id = kind
27
+ kind = projectPath
28
+ projectPath = process.cwd()
29
+ }
30
+
31
+ if (!kind || !id) {
32
+ throw new Error(
33
+ "Usage:\n" +
34
+ "- cloudcc delete dupeCatcher filter <filterid> [projectPath]\n" +
35
+ "- cloudcc delete dupeCatcher rule <ruleid> [projectPath]"
36
+ )
37
+ }
38
+
39
+ if (kind === "filter") {
40
+ console.error()
41
+ console.error(chalk.green(`Deleting dupe catcher filter (${id}), please wait...`))
42
+ console.error()
43
+ const res = await request(projectPath, "/api/duplication/deletefilter", { filterid: id })
44
+ if (res && res.result) {
45
+ const data = res.data || res
46
+ if (!isMcp) console.log(JSON.stringify(data))
47
+ return data
48
+ }
49
+ throw new Error("Delete DupeCatcher filter failed: " + (res?.returnInfo || res?.message || "Unknown error"))
50
+ }
51
+
52
+ if (kind === "rule") {
53
+ console.error()
54
+ console.error(chalk.green(`Deleting dupe catcher rule (${id}), please wait...`))
55
+ console.error()
56
+ const res = await request(projectPath, "/api/duplication/deleterule", { ruleid: id })
57
+ if (res && res.result) {
58
+ const data = res.data || res
59
+ if (!isMcp) console.log(JSON.stringify(data))
60
+ return data
61
+ }
62
+ throw new Error("Delete DupeCatcher rule failed: " + (res?.returnInfo || res?.message || "Unknown error"))
63
+ }
64
+
65
+ throw new Error(`Unknown kind for delete dupeCatcher: ${kind}. Expected 'filter' or 'rule'.`)
66
+ }
67
+
68
+ module.exports = del
69
+
@@ -0,0 +1,57 @@
1
+ const { getPackageJson } = require("../../utils/config")
2
+ const { postClass } = require("../../utils/http")
3
+
4
+ /**
5
+ * Supported:
6
+ * - cloudcc detail dupeCatcher <filterid> [projectPath]
7
+ * -> /api/duplication/detailfilter
8
+ *
9
+ * - cloudcc detail dupeCatcher rule <ruleid> [projectPath]
10
+ * -> /api/duplication/updateNewrule
11
+ */
12
+ function isPathLikeToken(v) {
13
+ if (typeof v !== "string" || !v) return false
14
+ return v === "." || v === ".." || /[\\/]/.test(v) || /:/.test(v)
15
+ }
16
+
17
+ async function request(projectPath, apiPath, body) {
18
+ const config = await getPackageJson(projectPath)
19
+ return await postClass(config.setupSvc + apiPath, body || {}, config.accessToken)
20
+ }
21
+
22
+ async function detail(projectPath = process.cwd(), kindOrId, maybeId, isMcp = false) {
23
+ // compatibility: cloudcc detail dupeCatcher <filterid> [projectPath]
24
+ if (!isPathLikeToken(projectPath)) {
25
+ maybeId = kindOrId
26
+ kindOrId = projectPath
27
+ projectPath = process.cwd()
28
+ }
29
+
30
+ if (!kindOrId) {
31
+ throw new Error("Missing id. Usage: cloudcc detail dupeCatcher <filterid> [projectPath]")
32
+ }
33
+
34
+ if (kindOrId === "rule") {
35
+ const ruleid = maybeId
36
+ if (!ruleid) throw new Error("Missing ruleid. Usage: cloudcc detail dupeCatcher rule <ruleid> [projectPath]")
37
+ const res = await request(projectPath, "/api/duplication/updateNewrule", { ruleid })
38
+ if (res && res.result) {
39
+ const data = res.data || res
40
+ if (!isMcp) console.log(JSON.stringify(data))
41
+ return data
42
+ }
43
+ throw new Error("Detail DupeCatcher rule failed: " + (res?.returnInfo || res?.message || "Unknown error"))
44
+ }
45
+
46
+ const filterid = kindOrId
47
+ const res = await request(projectPath, "/api/duplication/detailfilter", { filterid })
48
+ if (res && res.result) {
49
+ const data = res.data || res
50
+ if (!isMcp) console.log(JSON.stringify(data))
51
+ return data
52
+ }
53
+ throw new Error("Detail DupeCatcher filter failed: " + (res?.returnInfo || res?.message || "Unknown error"))
54
+ }
55
+
56
+ module.exports = detail
57
+
@@ -0,0 +1,11 @@
1
+ const fs = require("fs")
2
+ const path = require("path")
3
+
4
+ function doc() {
5
+ const p = path.join(__dirname, "docs", "devguide.md")
6
+ const content = fs.readFileSync(p, "utf8")
7
+ console.log(content)
8
+ }
9
+
10
+ module.exports = doc
11
+