huaweicloud-devkit 0.1.21-dev.0 → 0.1.23

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/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  帮助 AI 编码助手安全、准确地使用华为云——技能引导、KooCLI 工具、安全策略一站式集成。
7
7
 
8
- HuaweiCloud DevKit 为 AI 编码助手提供操作华为云所需的知识、工具和安全护栏,支持 OpenCode、Codex、Claude Code、Cursor 等主流 Agent。
8
+ HuaweiCloud DevKit 为 AI 编码助手提供操作华为云所需的知识、工具和安全护栏,支持 OpenCode、Codex、Claude Code、Cursor、码道(CodeArts Agent)等主流 Agent。
9
9
 
10
10
  ## 快速开始
11
11
 
@@ -42,6 +42,27 @@ npx --yes huaweicloud-devkit install --target codex
42
42
  /plugin install huaweicloud-core@huaweicloud-devkit
43
43
  ```
44
44
 
45
+ ### CodeArts Agent(码道)
46
+
47
+ 码道没有插件市场,通过技能 + MCP 机制适配:
48
+
49
+ ```bash
50
+ npx --yes huaweicloud-devkit install --target codearts
51
+ ```
52
+
53
+ 自动安装 27 个技能到 `~/.codeartsdoer/skills/` 与项目级 `.codeartsdoer/skills/`,MCP 服务器注册到用户级与项目级 `.codeartsdoer/mcp/mcp_settings.json`。若本机已存在 KooCLI(`~/hcloud/hcloud.exe`),会自动将 `HCLOUD_BIN` 注入 MCP 配置。安装后**重启会话**使 MCP 工具生效。
54
+
55
+ ```bash
56
+ npx --yes huaweicloud-devkit install-hcloud # 安装 KooCLI(自动接受隐私协议)
57
+ npx --yes huaweicloud-devkit doctor # 自检:hcloud、MCP、技能、沙箱模式
58
+ npx --yes huaweicloud-devkit status --target codearts # 查看码道安装状态
59
+ npx --yes huaweicloud-devkit uninstall --target codearts # 卸载
60
+ ```
61
+
62
+ > **沙箱模式**:码道默认 `bash_mode: sandbox` 会阻止 KooCLI 写入配置目录(如 `~/.hcloud/root`),导致隐私协议无法持久化、KooCLI 无法运行。`install-hcloud` 会自动检测沙箱模式并给出明确指引——请在**码道外终端**安装使用 KooCLI,或在码道设置中关闭沙箱模式(设置 → 权限 → Bash 模式)后重试。
63
+ >
64
+ > **认证**:KooCLI 就绪后,还需在码道外终端执行 `hcloud configure init` 配置 AK/SK 与区域,然后即可在码道中描述你的华为云任务。
65
+
45
66
  ### Cursor
46
67
 
47
68
  通过 **设置 → 插件 → 团队市场 → 添加市场 → 从仓库导入**,指向 `huaweicloud-mate/huaweicloud-devkit`。
package/package.json CHANGED
@@ -1,43 +1,43 @@
1
1
  {
2
- "name": "huaweicloud-devkit",
3
- "version": "0.1.21-dev.0",
4
- "description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
5
- "type": "module",
6
- "files": [
7
- "bin",
8
- ".agents",
9
- "plugins/huaweicloud-core",
10
- "integrations/opencode"
11
- ],
12
- "bin": {
13
- "huaweicloud-devkit": "./bin/setup.cjs"
14
- },
15
- "repository": {
16
- "type": "git",
17
- "url": "https://github.com/huaweicloud-mate/huaweicloud-devkit.git"
18
- },
19
- "scripts": {
20
- "test": "node --test",
21
- "lint:md": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#.git\" \"#test/**\" \"#docs/**\"",
22
- "lint": "npm run lint:md",
23
- "validate": "node ./scripts/validate-package.mjs",
24
- "postinstall": "node -e \"console.log('\\nHuaweiCloud DevKit installed. Run: npx huaweicloud-devkit install\\n')\""
25
- },
26
- "devDependencies": {
27
- "markdownlint-cli2": "^0.23.2"
28
- },
29
- "keywords": [
30
- "huaweicloud",
31
- "huawei-cloud",
32
- "agent",
33
- "codex",
34
- "opencode",
35
- "mcp",
36
- "koocli",
37
- "hcloud"
38
- ],
39
- "license": "Apache-2.0",
40
- "engines": {
41
- "node": ">=20"
42
- }
43
- }
2
+ "name": "huaweicloud-devkit",
3
+ "version": "0.1.23",
4
+ "description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
5
+ "type": "module",
6
+ "files": [
7
+ "bin",
8
+ ".agents",
9
+ "plugins/huaweicloud-core",
10
+ "integrations/opencode"
11
+ ],
12
+ "bin": {
13
+ "huaweicloud-devkit": "./bin/setup.cjs"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/huaweicloud-mate/huaweicloud-devkit.git"
18
+ },
19
+ "scripts": {
20
+ "test": "node --test",
21
+ "lint:md": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#.git\" \"#test/**\" \"#docs/**\"",
22
+ "lint": "npm run lint:md",
23
+ "validate": "node ./scripts/validate-package.mjs",
24
+ "postinstall": "node -e \"console.log(\u0027\\nHuaweiCloud DevKit installed. Run: npx huaweicloud-devkit install\\n\u0027)\""
25
+ },
26
+ "devDependencies": {
27
+ "markdownlint-cli2": "^0.23.2"
28
+ },
29
+ "keywords": [
30
+ "huaweicloud",
31
+ "huawei-cloud",
32
+ "agent",
33
+ "codex",
34
+ "opencode",
35
+ "mcp",
36
+ "koocli",
37
+ "hcloud"
38
+ ],
39
+ "license": "Apache-2.0",
40
+ "engines": {
41
+ "node": "\u003e=20"
42
+ }
43
+ }
@@ -1,44 +1,44 @@
1
1
  {
2
- "interface": {
3
- "displayName": "HuaweiCloud Devkit",
4
- "shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
5
- "longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
6
- "developerName": "HuaweiCloud Mate",
7
- "category": "Cloud",
8
- "capabilities": [
9
- "Read",
10
- "Interactive"
11
- ],
12
- "websiteURL": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
13
- "brandColor": "#C7000B",
14
- "defaultPrompt": [
15
- "Help me choose the right Huawei Cloud capability.",
16
- "Check my Huawei Cloud CLI setup safely.",
17
- "Plan this Huawei Cloud API or SDK task."
18
- ]
19
- },
20
- "mcpServers": "./.mcp.json",
21
- "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
22
- "skills": "./skills/",
23
- "version": "0.1.19",
24
- "author": {
25
- "name": "HuaweiCloud Mate",
26
- "url": "https://github.com/huaweicloud-mate"
27
- },
28
- "hooks": "./hooks/",
29
- "name": "huaweicloud-core",
30
- "homepage": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
31
- "repository": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
32
- "license": "Apache-2.0",
33
- "keywords": [
34
- "huaweicloud",
35
- "huawei-cloud",
36
- "koocli",
37
- "hcloud",
38
- "agent",
39
- "mcp",
40
- "api",
41
- "sdk",
42
- "skills"
43
- ]
44
- }
2
+ "interface": {
3
+ "displayName": "HuaweiCloud Devkit",
4
+ "shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
5
+ "longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
6
+ "developerName": "HuaweiCloud Mate",
7
+ "category": "Cloud",
8
+ "capabilities": [
9
+ "Read",
10
+ "Interactive"
11
+ ],
12
+ "websiteURL": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
13
+ "brandColor": "#C7000B",
14
+ "defaultPrompt": [
15
+ "Help me choose the right Huawei Cloud capability.",
16
+ "Check my Huawei Cloud CLI setup safely.",
17
+ "Plan this Huawei Cloud API or SDK task."
18
+ ]
19
+ },
20
+ "mcpServers": "./.mcp.json",
21
+ "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
22
+ "skills": "./skills/",
23
+ "version": "0.1.23",
24
+ "author": {
25
+ "name": "HuaweiCloud Mate",
26
+ "url": "https://github.com/huaweicloud-mate"
27
+ },
28
+ "hooks": "./hooks/",
29
+ "name": "huaweicloud-core",
30
+ "homepage": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
31
+ "repository": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
32
+ "license": "Apache-2.0",
33
+ "keywords": [
34
+ "huaweicloud",
35
+ "huawei-cloud",
36
+ "koocli",
37
+ "hcloud",
38
+ "agent",
39
+ "mcp",
40
+ "api",
41
+ "sdk",
42
+ "skills"
43
+ ]
44
+ }
@@ -1,43 +1,43 @@
1
1
  {
2
- "name": "huaweicloud-core",
3
- "version": "0.1.19",
4
- "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
5
- "author": {
6
- "name": "HuaweiCloud Mate",
7
- "url": "https://github.com/huaweicloud-mate"
8
- },
9
- "homepage": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
10
- "repository": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
11
- "license": "Apache-2.0",
12
- "keywords": [
13
- "huaweicloud",
14
- "huawei-cloud",
15
- "koocli",
16
- "hcloud",
17
- "agent",
18
- "mcp",
19
- "api",
20
- "sdk",
21
- "skills"
22
- ],
23
- "skills": "./skills/",
24
- "mcpServers": "./.mcp.json",
25
- "interface": {
26
- "displayName": "HuaweiCloud Devkit",
27
- "shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
28
- "longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
29
- "developerName": "HuaweiCloud Mate",
30
- "category": "Cloud",
31
- "capabilities": [
32
- "Read",
33
- "Interactive"
34
- ],
35
- "websiteURL": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
36
- "brandColor": "#C7000B",
37
- "defaultPrompt": [
38
- "Help me choose the right Huawei Cloud capability.",
39
- "Check my Huawei Cloud CLI setup safely.",
40
- "Plan this Huawei Cloud API or SDK task."
41
- ]
42
- }
43
- }
2
+ "name": "huaweicloud-core",
3
+ "version": "0.1.23",
4
+ "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
5
+ "author": {
6
+ "name": "HuaweiCloud Mate",
7
+ "url": "https://github.com/huaweicloud-mate"
8
+ },
9
+ "homepage": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
10
+ "repository": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
11
+ "license": "Apache-2.0",
12
+ "keywords": [
13
+ "huaweicloud",
14
+ "huawei-cloud",
15
+ "koocli",
16
+ "hcloud",
17
+ "agent",
18
+ "mcp",
19
+ "api",
20
+ "sdk",
21
+ "skills"
22
+ ],
23
+ "skills": "./skills/",
24
+ "mcpServers": "./.mcp.json",
25
+ "interface": {
26
+ "displayName": "HuaweiCloud Devkit",
27
+ "shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
28
+ "longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
29
+ "developerName": "HuaweiCloud Mate",
30
+ "category": "Cloud",
31
+ "capabilities": [
32
+ "Read",
33
+ "Interactive"
34
+ ],
35
+ "websiteURL": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
36
+ "brandColor": "#C7000B",
37
+ "defaultPrompt": [
38
+ "Help me choose the right Huawei Cloud capability.",
39
+ "Check my Huawei Cloud CLI setup safely.",
40
+ "Plan this Huawei Cloud API or SDK task."
41
+ ]
42
+ }
43
+ }
@@ -1,44 +1,44 @@
1
1
  {
2
- "interface": {
3
- "displayName": "HuaweiCloud Devkit",
4
- "shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
5
- "longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
6
- "developerName": "HuaweiCloud Mate",
7
- "category": "Cloud",
8
- "capabilities": [
9
- "Read",
10
- "Interactive"
11
- ],
12
- "websiteURL": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
13
- "brandColor": "#C7000B",
14
- "defaultPrompt": [
15
- "Help me choose the right Huawei Cloud capability.",
16
- "Check my Huawei Cloud CLI setup safely.",
17
- "Plan this Huawei Cloud API or SDK task."
18
- ]
19
- },
20
- "mcpServers": "./.mcp.json",
21
- "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
22
- "skills": "./skills/",
23
- "version": "0.1.19",
24
- "author": {
25
- "name": "HuaweiCloud Mate",
26
- "url": "https://github.com/huaweicloud-mate"
27
- },
28
- "hooks": "./hooks/",
29
- "name": "huaweicloud-core",
30
- "homepage": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
31
- "repository": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
32
- "license": "Apache-2.0",
33
- "keywords": [
34
- "huaweicloud",
35
- "huawei-cloud",
36
- "koocli",
37
- "hcloud",
38
- "agent",
39
- "mcp",
40
- "api",
41
- "sdk",
42
- "skills"
43
- ]
44
- }
2
+ "interface": {
3
+ "displayName": "HuaweiCloud Devkit",
4
+ "shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
5
+ "longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
6
+ "developerName": "HuaweiCloud Mate",
7
+ "category": "Cloud",
8
+ "capabilities": [
9
+ "Read",
10
+ "Interactive"
11
+ ],
12
+ "websiteURL": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
13
+ "brandColor": "#C7000B",
14
+ "defaultPrompt": [
15
+ "Help me choose the right Huawei Cloud capability.",
16
+ "Check my Huawei Cloud CLI setup safely.",
17
+ "Plan this Huawei Cloud API or SDK task."
18
+ ]
19
+ },
20
+ "mcpServers": "./.mcp.json",
21
+ "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
22
+ "skills": "./skills/",
23
+ "version": "0.1.23",
24
+ "author": {
25
+ "name": "HuaweiCloud Mate",
26
+ "url": "https://github.com/huaweicloud-mate"
27
+ },
28
+ "hooks": "./hooks/",
29
+ "name": "huaweicloud-core",
30
+ "homepage": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
31
+ "repository": "https://github.com/huaweicloud-mate/huaweicloud-devkit",
32
+ "license": "Apache-2.0",
33
+ "keywords": [
34
+ "huaweicloud",
35
+ "huawei-cloud",
36
+ "koocli",
37
+ "hcloud",
38
+ "agent",
39
+ "mcp",
40
+ "api",
41
+ "sdk",
42
+ "skills"
43
+ ]
44
+ }
@@ -37,6 +37,63 @@ function codexDesktopCommandsDir() { return join(homedir(), '.agents', 'commands
37
37
  function codexDesktopPluginsDir() { return join(homedir(), '.agents', 'huaweicloud-plugins'); }
38
38
  function codexDesktopConfigFile() { return join(homedir(), '.agents', 'opencode.json'); }
39
39
 
40
+ function codeartsSkillsDir() { return join(homedir(), '.codeartsdoer', 'skills'); }
41
+ function codeartsMcpSettingsDir() { return join(homedir(), '.codeartsdoer', 'mcp'); }
42
+ function codeartsMcpSettingsFile() { return join(codeartsMcpSettingsDir(), 'mcp_settings.json'); }
43
+ function codeartsProjectDir() { return join(process.cwd(), '.codeartsdoer'); }
44
+ function codeartsProjectSkillsDir() { return join(codeartsProjectDir(), 'skills'); }
45
+ function codeartsProjectMcpSettingsFile() { return join(codeartsProjectDir(), 'mcp', 'mcp_settings.json'); }
46
+ function codeartsPluginsDir() { return join(homedir(), '.codeartsdoer', 'huaweicloud-plugins'); }
47
+
48
+ // Detect CodeArts sandbox mode (bash_mode in permission config).
49
+ function detectCodeartsSandbox() {
50
+ try {
51
+ const configPath = join(homedir(), '.codeartsdoer', 'codearts-data', 'storage', 'permission', 'config.json');
52
+ if (!existsSync(configPath)) return null;
53
+ const config = JSON.parse(readFileSync(configPath, 'utf8'));
54
+ return typeof config.bash_mode === 'string' ? config.bash_mode : null;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ // Locate an existing hcloud executable (HCLOUD_BIN, ~/hcloud on Windows, ~/.local/bin elsewhere).
61
+ function findHcloudBin() {
62
+ if (process.env.HCLOUD_BIN && existsSync(process.env.HCLOUD_BIN)) return process.env.HCLOUD_BIN;
63
+ const isWin = platform() === 'win32';
64
+ const candidates = isWin
65
+ ? [join(homedir(), 'hcloud', 'hcloud.exe')]
66
+ : [join(homedir(), '.local', 'bin', 'hcloud'), join(homedir(), 'hcloud', 'hcloud'), join(homedir(), 'hcloud', 'hcloud.exe')];
67
+ for (const c of candidates) {
68
+ if (existsSync(c)) return c;
69
+ }
70
+ return null;
71
+ }
72
+
73
+ function printSandboxWarning(reason) {
74
+ console.log(`\n\x1b[1m\x1b[31m⚠ 检测到码道沙箱模式 (bash_mode: sandbox)\x1b[0m`);
75
+ console.log(`\x1b[31m ${reason}\x1b[0m`);
76
+ console.log(`\x1b[31m 请任选其一继续:\x1b[0m`);
77
+ console.log(`\x1b[31m A. 在码道外的终端安装并使用 KooCLI (推荐):`);
78
+ console.log(`\x1b[31m https://support.huaweicloud.com/qs-hcli/hcli_02_003.html`);
79
+ console.log(`\x1b[31m B. 在码道设置中关闭沙箱模式后重试 (设置 → 权限 → Bash 模式)`);
80
+ console.log(`\x1b[31m 关闭沙箱后重新运行: npx huaweicloud-devkit install-hcloud\x1b[0m`);
81
+ }
82
+
83
+ // Try to auto-accept the KooCLI privacy agreement by answering 'y' on stdin.
84
+ // Returns true when hcloud runs without re-prompting for the agreement.
85
+ function acceptKooCliPrivacy(hcloudBin) {
86
+ const run = () => spawnSync(hcloudBin, ['version'], {
87
+ encoding: 'utf8', timeout: 10000, windowsHide: true, input: 'y\n',
88
+ });
89
+ const first = run();
90
+ const out = (first.stdout || '') + (first.stderr || '');
91
+ if (!/同意并继续使用|agree/i.test(out)) return first.status === 0;
92
+ const second = run();
93
+ const out2 = (second.stdout || '') + (second.stderr || '');
94
+ return second.status === 0 && !/同意并继续使用/.test(out2);
95
+ }
96
+
40
97
  function checkNode() {
41
98
  const v = process.versions.node.split('.').map(Number);
42
99
  if (v[0] < 20) {
@@ -103,8 +160,10 @@ function hasCodexCLI() {
103
160
  }
104
161
 
105
162
  function checkHcloud() {
106
- const r = spawnSync('hcloud version', [], { shell: true, windowsHide: true, stdio: 'pipe', timeout: 5000 });
107
- return r.status === 0 && /KooCLI|Current.*version/i.test(r.stdout ? r.stdout.toString() : '');
163
+ const bin = findHcloudBin() || (process.env.HCLOUD_BIN || 'hcloud');
164
+ const r = spawnSync(`"${bin}" version`, [], { shell: true, windowsHide: true, stdio: 'pipe', timeout: 5000, input: 'y\n' });
165
+ const out = (r.stdout ? r.stdout.toString() : '') + (r.stderr ? r.stderr.toString() : '');
166
+ return r.status === 0 && /KooCLI|Current.*version|当前KooCLI/i.test(out);
108
167
  }
109
168
 
110
169
  function getMarketplaceName() {
@@ -274,6 +333,96 @@ function uninstallCodexDesktop() {
274
333
  }
275
334
  }
276
335
 
336
+ function registerCodeartsMcp(configPath) {
337
+ const mcpPath = join(codeartsPluginsDir(), 'src', 'mcp-server.mjs').replace(/\\/g, '/');
338
+ let config = {};
339
+ if (existsSync(configPath)) {
340
+ try { config = JSON.parse(readFileSync(configPath, 'utf8')); } catch {}
341
+ }
342
+ config.mcpServers = config.mcpServers || {};
343
+ const env = { HUAWEICLOUD_AGENT_TOOLKIT_MODE: 'local' };
344
+ const hcloudBin = findHcloudBin();
345
+ if (hcloudBin) env.HCLOUD_BIN = hcloudBin.replace(/\\/g, '/');
346
+ config.mcpServers.huaweicloud = {
347
+ command: 'node',
348
+ args: [mcpPath],
349
+ env,
350
+ enabled: true,
351
+ };
352
+ mkdirSync(dirname(configPath), { recursive: true });
353
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
354
+ console.log(` MCP config updated: ${configPath}`);
355
+ }
356
+
357
+ async function installCodeArts() {
358
+ const skillsSrc = join(PLUGIN_ROOT, 'skills');
359
+ const srcDir = join(PLUGIN_ROOT, 'src');
360
+ const safetyDir = join(PLUGIN_ROOT, 'safety');
361
+
362
+ copyDir(skillsSrc, codeartsSkillsDir());
363
+ console.log(` Skills -> ${codeartsSkillsDir()}`);
364
+ copyDir(skillsSrc, codeartsProjectSkillsDir());
365
+ console.log(` Skills -> ${codeartsProjectSkillsDir()}`);
366
+
367
+ const pluginDest = codeartsPluginsDir();
368
+ copyDir(srcDir, join(pluginDest, 'src'));
369
+ console.log(` MCP Server -> ${join(pluginDest, 'src')}`);
370
+ copyDir(safetyDir, join(pluginDest, 'safety'));
371
+ console.log(` Safety Policy -> ${join(pluginDest, 'safety')}`);
372
+
373
+ registerCodeartsMcp(codeartsMcpSettingsFile());
374
+ registerCodeartsMcp(codeartsProjectMcpSettingsFile());
375
+ }
376
+
377
+ function uninstallCodeArts() {
378
+ let removed = 0;
379
+ for (const skillsDir of [codeartsSkillsDir(), codeartsProjectSkillsDir()]) {
380
+ if (!existsSync(skillsDir)) continue;
381
+ for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
382
+ if (entry.name.startsWith('huawei')) {
383
+ removeIfExists(join(skillsDir, entry.name));
384
+ removed++;
385
+ }
386
+ }
387
+ }
388
+ if (removed > 0) console.log(` Removed ${removed} skills`);
389
+
390
+ if (removeIfExists(codeartsPluginsDir())) {
391
+ console.log(' Removed MCP server and safety policy');
392
+ }
393
+ for (const configPath of [codeartsMcpSettingsFile(), codeartsProjectMcpSettingsFile()]) {
394
+ if (!existsSync(configPath)) continue;
395
+ let config = {};
396
+ try { config = JSON.parse(readFileSync(configPath, 'utf8')); } catch {}
397
+ if (config.mcpServers?.huaweicloud) {
398
+ delete config.mcpServers.huaweicloud;
399
+ if (Object.keys(config.mcpServers).length === 0) delete config.mcpServers;
400
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
401
+ console.log(` Config cleaned: ${configPath}`);
402
+ }
403
+ }
404
+ }
405
+
406
+ function codeartsStatus() {
407
+ const pluginDir = codeartsPluginsDir();
408
+ console.log(` MCP Server: ${existsSync(join(pluginDir, 'src', 'mcp-server.mjs')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`);
409
+ console.log(` Safety Policy: ${existsSync(join(pluginDir, 'safety', 'policy.json')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`);
410
+ let skillCount = 0;
411
+ if (existsSync(codeartsSkillsDir())) {
412
+ skillCount = readdirSync(codeartsSkillsDir(), { withFileTypes: true })
413
+ .filter((d) => d.isDirectory() && d.name.startsWith('huawei')).length;
414
+ }
415
+ console.log(` Skills: ${skillCount > 0 ? `\x1b[32m${skillCount} installed\x1b[0m` : '\x1b[31mNot installed\x1b[0m'}`);
416
+ if (existsSync(codeartsMcpSettingsFile())) {
417
+ try {
418
+ const config = JSON.parse(readFileSync(codeartsMcpSettingsFile(), 'utf8'));
419
+ console.log(` MCP config: ${config.mcpServers?.huaweicloud ? '\x1b[32mConfigured\x1b[0m' : '\x1b[31mNot configured\x1b[0m'}`);
420
+ } catch {
421
+ console.log(` MCP config: \x1b[31mInvalid\x1b[0m`);
422
+ }
423
+ }
424
+ }
425
+
277
426
  function opencodeStatus() {
278
427
  const pluginDir = opencodePluginsDir();
279
428
  const skillsDir = opencodeSkillsDir();
@@ -302,6 +451,7 @@ function parseTarget() {
302
451
  const val = (process.argv[idx + 1] || '').toLowerCase();
303
452
  if (val === 'codex') return 'codex';
304
453
  if (val === 'codex-desktop') return 'codex-desktop';
454
+ if (val === 'codearts') return 'codearts';
305
455
  if (val === 'all') return 'all';
306
456
  return 'opencode';
307
457
  }
@@ -320,6 +470,10 @@ async function cmdInstall() {
320
470
  console.log('\n[Codex Desktop]');
321
471
  await installCodexDesktop();
322
472
  }
473
+ if (target === 'codearts' || target === 'all') {
474
+ console.log('\n[CodeArts]');
475
+ await installCodeArts();
476
+ }
323
477
  if (target === 'codex' || target === 'all') {
324
478
  console.log('\n[Codex]');
325
479
  if (!hasCodexCLI()) {
@@ -336,8 +490,12 @@ async function cmdInstall() {
336
490
  }
337
491
 
338
492
  console.log(`\n\x1b[32mInstallation complete!\x1b[0m`);
493
+ const appName = target === 'codearts' ? 'CodeArts'
494
+ : target === 'codex-desktop' ? 'Codex Desktop'
495
+ : target === 'codex' ? 'Codex' : 'OpenCode';
496
+ const pad = ' '.repeat(24 - appName.length);
339
497
  console.log(`\n\x1b[1m\x1b[33m╔══════════════════════════════════════════════════════╗`);
340
- console.log(`\x1b[1m\x1b[33m║ MCP 工具在重启 OpenCode 会话后才生效 ║`);
498
+ console.log(`\x1b[1m\x1b[33m║ MCP 工具在重启 ${appName} 会话后才生效${pad}║`);
341
499
  console.log(`\x1b[1m\x1b[33m║ 关闭当前会话 → 重新打开,直接描述华为云任务即可 ║`);
342
500
  console.log(`\x1b[1m\x1b[33m║ 重启前请勿执行 hcloud 命令,避免 AK/SK 泄露 ║`);
343
501
  console.log(`\x1b[1m\x1b[33m╚══════════════════════════════════════════════════════╝\x1b[0m`);
@@ -353,10 +511,14 @@ async function cmdInstall() {
353
511
  console.log(`\nAfter restart + hcloud setup, run: npx huaweicloud-devkit doctor`);
354
512
 
355
513
  // Write install marker for doctor to detect
356
- writeFileSync(join(opencodePluginsDir(), '.installed'), new Date().toISOString());
514
+ const markerDir = target === 'codearts' ? codeartsPluginsDir() : opencodePluginsDir();
515
+ writeFileSync(join(markerDir, '.installed'), new Date().toISOString());
357
516
  if (target === 'opencode' || target === 'all') {
358
517
  console.log('Or describe your Huawei Cloud task in OpenCode');
359
518
  }
519
+ if (target === 'codearts' || target === 'all') {
520
+ console.log('Or describe your Huawei Cloud task in CodeArts');
521
+ }
360
522
  if (target === 'codex' || target === 'all') {
361
523
  console.log('Or mention @huaweicloud-core in Codex');
362
524
  }
@@ -371,6 +533,10 @@ async function cmdUninstall() {
371
533
  console.log('[OpenCode]');
372
534
  await uninstallOpenCode();
373
535
  }
536
+ if (target === 'codearts' || target === 'all') {
537
+ console.log('\n[CodeArts]');
538
+ uninstallCodeArts();
539
+ }
374
540
  if (target === 'codex' || target === 'all') {
375
541
  console.log('\n[Codex]');
376
542
  uninstallCodexDesktop();
@@ -392,6 +558,10 @@ async function cmdStatus() {
392
558
  console.log('[OpenCode]');
393
559
  opencodeStatus();
394
560
  }
561
+ if (target === 'codearts' || target === 'all') {
562
+ console.log('\n[CodeArts]');
563
+ codeartsStatus();
564
+ }
395
565
  if (target === 'codex' || target === 'all') {
396
566
  console.log('\n[Codex]');
397
567
  if (!hasCodexCLI()) {
@@ -449,11 +619,21 @@ async function cmdDoctor() {
449
619
  check('OpenCode MCP configured', mcpConfigured, `Add MCP to ${opencodeCfg} — run: npx huaweicloud-devkit-test install`);
450
620
 
451
621
  // hcloud CLI
452
- const hcloudBin = process.env.HCLOUD_BIN || 'hcloud';
453
- const hcloudCheck = spawnSync(`"${hcloudBin}" version`, [], { shell: true, windowsHide: true, stdio: 'pipe', timeout: 5000 });
454
- const hcloudOk = hcloudCheck.status === 0 && hcloudCheck.stdout.toString().includes('KooCLI');
622
+ const hcloudBin = findHcloudBin() || (process.env.HCLOUD_BIN || 'hcloud');
623
+ const hcloudCheck = spawnSync(`"${hcloudBin}" version`, [], { shell: true, windowsHide: true, stdio: 'pipe', timeout: 5000, input: 'y\n' });
624
+ const hcloudOut = (hcloudCheck.stdout || '').toString() + (hcloudCheck.stderr || '').toString();
625
+ const hcloudOk = hcloudCheck.status === 0 && /KooCLI|Current.*version|当前KooCLI/i.test(hcloudOut);
455
626
  check('hcloud CLI installed', hcloudOk, 'Run: npx huaweicloud-devkit install-hcloud');
456
627
 
628
+ // CodeArts sandbox mode warning
629
+ const sandboxMode = detectCodeartsSandbox();
630
+ if (sandboxMode === 'sandbox') {
631
+ console.log(` \x1b[33m[WARN]\x1b[0m CodeArts sandbox mode active (bash_mode: sandbox)`);
632
+ console.log(` KooCLI may fail to write config in ~/.hcloud/ and hang on the privacy agreement.`);
633
+ console.log(` Fix: disable sandbox (Settings → Permissions) or use a terminal outside CodeArts.`);
634
+ warn++;
635
+ }
636
+
457
637
  if (hcloudOk) {
458
638
  const ver = (hcloudCheck.stdout.toString().match(/(\d+\.\d+\.\d+)/) || [])[1] || 'unknown';
459
639
  console.log(` Version: ${ver}`);
@@ -465,7 +645,7 @@ async function cmdDoctor() {
465
645
  }
466
646
 
467
647
  // Skills
468
- const skillsOptions = [opencodeSkillsDir(), codexDesktopSkillsDir()];
648
+ const skillsOptions = [opencodeSkillsDir(), codexDesktopSkillsDir(), codeartsSkillsDir()];
469
649
  let skillCount = 0, skillsDir = '';
470
650
  for (const dir of skillsOptions) {
471
651
  if (!existsSync(dir)) continue;
@@ -561,11 +741,14 @@ async function cmdInstallHcloud() {
561
741
  // Download
562
742
  console.log(` Downloading ${url}...`);
563
743
  const psCmd = `[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '${url}' -OutFile '${zipPath}' -UseBasicParsing`;
564
- spawnSync('powershell', ['-NoProfile', '-Command', psCmd], { stdio: 'inherit', windowsHide: true });
744
+ const dl = spawnSync('powershell', ['-NoProfile', '-Command', psCmd], { stdio: 'inherit', windowsHide: true, timeout: 180000 });
745
+ if (dl.status !== 0) throw new Error(`下载失败 (PowerShell exit ${dl.status})`);
565
746
 
566
747
  // Extract
567
748
  console.log(' Extracting...');
568
- spawnSync('powershell', ['-NoProfile', '-Command', `Expand-Archive -Path '${zipPath}' -DestinationPath '${installDir}' -Force`], { stdio: 'inherit', windowsHide: true });
749
+ const ex = spawnSync('powershell', ['-NoProfile', '-Command', `Expand-Archive -Path '${zipPath}' -DestinationPath '${installDir}' -Force`], { stdio: 'inherit', windowsHide: true, timeout: 60000 });
750
+ if (ex.status !== 0) throw new Error(`解压失败 (PowerShell exit ${ex.status})`);
751
+ if (!existsSync(join(installDir, 'hcloud.exe'))) throw new Error('hcloud.exe 未生成,可能已被安全软件拦截');
569
752
 
570
753
  // Clean up zip
571
754
  rmSync(zipPath, { force: true });
@@ -576,11 +759,29 @@ async function cmdInstallHcloud() {
576
759
 
577
760
  console.log(`\n\x1b[32mInstall complete.\x1b[0m`);
578
761
  console.log(` Verify: ${join(installDir, 'hcloud.exe')} version`);
762
+
763
+ // Auto-accept the KooCLI privacy agreement so first run does not hang
764
+ console.log('\n Accepting KooCLI privacy agreement...');
765
+ const hcloudBin = join(installDir, 'hcloud.exe');
766
+ if (acceptKooCliPrivacy(hcloudBin)) {
767
+ console.log(' \x1b[32mPrivacy agreement accepted. KooCLI ready.\x1b[0m');
768
+ } else {
769
+ console.log(' \x1b[33m无法自动接受隐私协议(可能因沙箱阻止写入配置目录)。\x1b[0m');
770
+ if (detectCodeartsSandbox() === 'sandbox') {
771
+ printSandboxWarning('KooCLI 需要写入配置目录 (如 ~/.hcloud/root) 以保存隐私协议同意状态,但沙箱模式阻止了写入。');
772
+ } else {
773
+ console.log(' 请在码道外终端运行一次: hcloud version 并按提示输入 y');
774
+ }
775
+ }
776
+
579
777
  console.log(' Or restart terminal and: hcloud version');
580
778
  } catch (e) {
581
779
  console.log(`\n\x1b[33mAuto-install failed: ${e.message}\x1b[0m`);
582
780
  console.log(` Manual: download ${url}, unzip to ${installDir}, add to PATH`);
583
781
  console.log(` Guide: https://support.huaweicloud.com/qs-hcli/hcli_02_003_01.html`);
782
+ if (detectCodeartsSandbox() === 'sandbox') {
783
+ printSandboxWarning('沙箱模式拦截了 KooCLI 自动安装(无法创建/写入安装目录)。');
784
+ }
584
785
  }
585
786
  } else if (os === 'linux') {
586
787
  console.log('[Linux] One-liner install:');
@@ -646,7 +847,7 @@ async function main() {
646
847
  case '-h':
647
848
  default:
648
849
  console.log(BANNER);
649
- console.log('Usage: npx huaweicloud-devkit <command> [--target <opencode|codex|all>]\n');
850
+ console.log('Usage: npx huaweicloud-devkit <command> [--target <opencode|codex|codearts|all>]\n');
650
851
  console.log('Commands:');
651
852
  console.log(' install Install skills, MCP server, safety policy');
652
853
  console.log(' uninstall Remove installed files');
@@ -657,10 +858,11 @@ async function main() {
657
858
  console.log(' install-hcloud Show KooCLI install commands for your OS');
658
859
  console.log(' help Show this help');
659
860
  console.log('\nOptions:');
660
- console.log(' --target Target agent: opencode (default), codex, all');
861
+ console.log(' --target Target agent: opencode (default), codex, codearts, all');
661
862
  console.log('\nExamples:');
662
863
  console.log(' npx huaweicloud-devkit install');
663
864
  console.log(' npx huaweicloud-devkit install --target codex');
865
+ console.log(' npx huaweicloud-devkit install --target codearts');
664
866
  console.log(' npx huaweicloud-devkit install --target all');
665
867
  break;
666
868
  }
@@ -12,8 +12,13 @@ function opencodeSkillsDir() {
12
12
  const home = homedir();
13
13
  return join(home, '.config', 'opencode', 'skills');
14
14
  }
15
+ function codeartsSkillsDir() {
16
+ const home = homedir();
17
+ return join(home, '.codeartsdoer', 'skills');
18
+ }
15
19
  function resolveSkillsRoot() {
16
20
  if (existsSync(SKILLS_ROOT_DEV)) return SKILLS_ROOT_DEV;
21
+ if (existsSync(codeartsSkillsDir())) return codeartsSkillsDir();
17
22
  if (existsSync(opencodeSkillsDir())) return opencodeSkillsDir();
18
23
  return SKILLS_ROOT_DEV;
19
24
  }