huaweicloud-devkit 1.1.0-next.14 → 1.1.0-next.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-devkit",
3
- "version": "1.1.0-next.14",
3
+ "version": "1.1.0-next.15",
4
4
  "description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
5
5
  "type": "module",
6
6
  "files": [
@@ -17,7 +17,7 @@
17
17
  "mcpServers": "./.mcp.json",
18
18
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
19
19
  "skills": "./skills/",
20
- "version": "1.1.0-next.14",
20
+ "version": "1.1.0-next.15",
21
21
  "author": {
22
22
  "name": "HuaweiCloud Mate",
23
23
  "url": "https://github.com/huaweicloud"
@@ -20,7 +20,7 @@
20
20
  "mcpServers": "./.mcp.json",
21
21
  "description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
22
22
  "skills": "./skills/",
23
- "version": "1.1.0-next.14",
23
+ "version": "1.1.0-next.15",
24
24
  "author": {
25
25
  "name": "HuaweiCloud Mate",
26
26
  "url": "https://github.com/huaweicloud"
@@ -17,7 +17,7 @@
17
17
  "mcpServers": "./.mcp.json",
18
18
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
19
19
  "skills": "./skills/",
20
- "version": "1.1.0-next.14",
20
+ "version": "1.1.0-next.15",
21
21
  "author": {
22
22
  "name": "HuaweiCloud Mate",
23
23
  "url": "https://github.com/huaweicloud"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-devkit",
3
- "version": "1.1.0-next.14",
3
+ "version": "1.1.0-next.15",
4
4
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
5
5
  "author": {
6
6
  "name": "HuaweiCloud Mate",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-devkit",
3
- "version": "1.1.0-next.14",
3
+ "version": "1.1.0-next.15",
4
4
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
5
5
  "author": {
6
6
  "name": "HuaweiCloud Mate",
@@ -2,7 +2,7 @@
2
2
  "name": "huaweicloud-devkit",
3
3
  "id": "huaweicloud-devkit",
4
4
  "displayName": "HuaweiCloud DevKit",
5
- "version": "1.1.0-next.14",
5
+ "version": "1.1.0-next.15",
6
6
  "family": "bundle-plugin",
7
7
  "bundleFormat": "codex",
8
8
  "description": "Guide coding agents to use Huawei Cloud safely — KooCLI, APIs, SDKs, 28 MCP tools, skills, and safety guardrails.",
@@ -9,6 +9,7 @@ export const SUPPORTED_AGENT_TARGETS = [
9
9
  'codex',
10
10
  'codex-desktop',
11
11
  'codearts',
12
+ 'codearts-work',
12
13
  'workbuddy',
13
14
  'dsh',
14
15
  'officeace',
@@ -78,6 +79,12 @@ function codeartsRegistered() {
78
79
  });
79
80
  }
80
81
 
82
+ function codeartsWorkRegistered() {
83
+ const path = join(baseHome(), '.codeartswork', 'mcp', 'mcp_settings.json');
84
+ const cfg = readJsonSafe(path);
85
+ return Boolean(cfg?.mcpServers?.['huaweicloud-devkit']);
86
+ }
87
+
81
88
  function workbuddyRegistered() {
82
89
  const cfg = readJsonSafe(join(baseHome(), '.workbuddy', 'mcp.json'));
83
90
  return Boolean(cfg?.mcpServers?.['huaweicloud-devkit']);
@@ -208,6 +215,7 @@ export function getAgentRegistrationStatuses(target = 'all') {
208
215
  if (agent === 'codex-desktop') configured = codexDesktopRegistered();
209
216
  if (agent === 'codex') configured = codexCliRegistered();
210
217
  if (agent === 'codearts') configured = codeartsRegistered();
218
+ if (agent === 'codearts-work') configured = codeartsWorkRegistered();
211
219
  if (agent === 'workbuddy') configured = workbuddyRegistered();
212
220
  if (agent === 'dsh') configured = dshRegistered();
213
221
  if (agent === 'officeace') configured = officeaceRegistered();
@@ -123,7 +123,11 @@ export function getParentCwd() {
123
123
  }
124
124
 
125
125
  function isCodeArtsContext() {
126
- return existsSync(join(process.cwd(), '.codeartsdoer')) || existsSync(join(homedir(), '.codeartsdoer'));
126
+ return (
127
+ existsSync(join(process.cwd(), '.codeartsdoer')) ||
128
+ existsSync(join(homedir(), '.codeartsdoer')) ||
129
+ existsSync(join(homedir(), '.codeartswork'))
130
+ );
127
131
  }
128
132
 
129
133
  function readCodeArtsCredentials() {
@@ -154,6 +158,31 @@ function readCodeArtsCredentials() {
154
158
  }
155
159
  }
156
160
 
161
+ // CodeArts Work — user-level only
162
+ {
163
+ const path = join(homedir(), '.codeartswork', 'mcp', 'mcp_settings.json');
164
+ try {
165
+ if (existsSync(path)) {
166
+ const config = JSON.parse(readFileSync(path, 'utf8'));
167
+ const server = config?.mcpServers?.['huaweicloud-devkit'];
168
+ if (server?.env) {
169
+ const ak = server.env.HW_ACCESS_KEY;
170
+ const sk = server.env.HW_SECRET_KEY;
171
+ if (ak && sk) {
172
+ return {
173
+ ak,
174
+ sk,
175
+ securityToken: server.env.HW_SECURITY_TOKEN || '',
176
+ region: server.env.HW_REGION || server.env.HUAWEICLOUD_REGION || '',
177
+ };
178
+ }
179
+ }
180
+ }
181
+ } catch {
182
+ // mcp_settings.json missing or invalid — skip
183
+ }
184
+ }
185
+
157
186
  return null;
158
187
  }
159
188
 
@@ -820,7 +820,7 @@ fi`;
820
820
  const cmd = [
821
821
  resolveScript,
822
822
  `sudo mkdir -p /etc/nginx/conf.d`,
823
- `sudo tee /etc/nginx/conf.d/${configName || 'app'}.conf > /dev/null << 'NGINX_EOF'`,
823
+ `sudo tee /etc/nginx/conf.d/${configName || project}.conf > /dev/null << 'NGINX_EOF'`,
824
824
  config,
825
825
  `NGINX_EOF`,
826
826
  `# Resolve symlinks for chmod (chmod does not follow symlinks on Linux)`,
@@ -105,6 +105,17 @@ function codeartsPluginsDir() {
105
105
  return join(homedir(), '.codeartsdoer', 'huaweicloud-plugins');
106
106
  }
107
107
 
108
+ // CodeArts Work (CodeArts Space) — user-level only
109
+ function codeartsWorkSkillsDir() {
110
+ return join(homedir(), '.codeartswork', 'skills');
111
+ }
112
+ function codeartsWorkMcpSettingsFile() {
113
+ return join(homedir(), '.codeartswork', 'mcp', 'mcp_settings.json');
114
+ }
115
+ function codeartsWorkPluginsDir() {
116
+ return join(homedir(), '.codeartswork', 'huaweicloud-plugins');
117
+ }
118
+
108
119
  function workbuddySkillsDir() {
109
120
  return join(homedir(), '.workbuddy', 'skills');
110
121
  }
@@ -1248,6 +1259,146 @@ function codeartsStatus() {
1248
1259
  }
1249
1260
  }
1250
1261
 
1262
+ // --- CodeArts Work (CodeArts Space) ---
1263
+
1264
+ function registerCodeartsWorkMcp() {
1265
+ const configPath = codeartsWorkMcpSettingsFile();
1266
+ const mcpPath = join(codeartsWorkPluginsDir(), 'src', 'mcp-server.mjs').replace(/\\/g, '/');
1267
+ const env = { HUAWEICLOUD_AGENT_TOOLKIT_MODE: 'local' };
1268
+ const hcloudBin = findHcloudBin();
1269
+ if (hcloudBin) env.HCLOUD_BIN = hcloudBin.replace(/\\/g, '/');
1270
+ let config = {};
1271
+ if (existsSync(configPath)) {
1272
+ try {
1273
+ config = JSON.parse(readFileSync(configPath, 'utf8'));
1274
+ } catch {
1275
+ console.log(
1276
+ ` \x1b[33m[WARN]\x1b[0m Could not parse ${configPath}. Skipping MCP config write; ensure "mcpServers.huaweicloud-devkit" points to ${mcpPath}.`,
1277
+ );
1278
+ return;
1279
+ }
1280
+ const existing = config.mcpServers?.['huaweicloud-devkit'];
1281
+ if (
1282
+ existing &&
1283
+ existing.command === 'node' &&
1284
+ Array.isArray(existing.args) &&
1285
+ existing.args[0] === mcpPath &&
1286
+ existing.timeout === 300000
1287
+ ) {
1288
+ console.log(` MCP config unchanged: ${configPath}`);
1289
+ return;
1290
+ }
1291
+ }
1292
+ config.mcpServers = config.mcpServers || {};
1293
+ config.mcpServers['huaweicloud-devkit'] = {
1294
+ command: 'node',
1295
+ args: [mcpPath],
1296
+ env,
1297
+ enabled: true,
1298
+ timeout: 300000,
1299
+ };
1300
+ mkdirSync(dirname(configPath), { recursive: true });
1301
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
1302
+ console.log(` MCP config updated: ${configPath}`);
1303
+ }
1304
+
1305
+ async function installCodeArtsWork() {
1306
+ const skillsSrc = join(PLUGIN_ROOT, 'skills');
1307
+ const srcDir = join(PLUGIN_ROOT, 'src');
1308
+ const safetyDir = join(PLUGIN_ROOT, 'safety');
1309
+
1310
+ copyDir(skillsSrc, codeartsWorkSkillsDir());
1311
+ console.log(` Skills -> ${codeartsWorkSkillsDir()}`);
1312
+
1313
+ const pluginDest = codeartsWorkPluginsDir();
1314
+ copyDir(srcDir, join(pluginDest, 'src'));
1315
+ console.log(` MCP Server -> ${join(pluginDest, 'src')}`);
1316
+ copyDir(safetyDir, join(pluginDest, 'safety'));
1317
+ console.log(` Safety Policy -> ${join(pluginDest, 'safety')}`);
1318
+
1319
+ registerCodeartsWorkMcp();
1320
+ installRuntimeDeps(pluginDest);
1321
+ }
1322
+
1323
+ async function updateCodeArtsWork() {
1324
+ const skillsSrc = join(PLUGIN_ROOT, 'skills');
1325
+ const srcDir = join(PLUGIN_ROOT, 'src');
1326
+ const safetyDir = join(PLUGIN_ROOT, 'safety');
1327
+ const pluginDest = codeartsWorkPluginsDir();
1328
+
1329
+ copyDir(skillsSrc, codeartsWorkSkillsDir());
1330
+ console.log(` Skills updated -> ${codeartsWorkSkillsDir()}`);
1331
+ copyDir(srcDir, join(pluginDest, 'src'));
1332
+ console.log(` MCP Server updated -> ${join(pluginDest, 'src')}`);
1333
+ copyDir(safetyDir, join(pluginDest, 'safety'));
1334
+ console.log(` Safety Policy updated -> ${join(pluginDest, 'safety')}`);
1335
+ registerCodeartsWorkMcp();
1336
+ mkdirSync(pluginDest, { recursive: true });
1337
+ writeFileSync(join(pluginDest, '.installed'), new Date().toISOString());
1338
+ installRuntimeDeps(pluginDest);
1339
+ }
1340
+
1341
+ function uninstallCodeArtsWork() {
1342
+ const skillsDir = codeartsWorkSkillsDir();
1343
+ if (existsSync(skillsDir)) {
1344
+ let removed = 0;
1345
+ for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
1346
+ if (entry.name.startsWith('huawei')) {
1347
+ removeIfExists(join(skillsDir, entry.name));
1348
+ removed++;
1349
+ }
1350
+ }
1351
+ if (removed > 0) console.log(` Removed ${removed} skills`);
1352
+ }
1353
+
1354
+ if (removeIfExists(codeartsWorkPluginsDir())) {
1355
+ console.log(' Removed MCP server and safety policy');
1356
+ }
1357
+
1358
+ const configPath = codeartsWorkMcpSettingsFile();
1359
+ if (existsSync(configPath)) {
1360
+ let config = {};
1361
+ try {
1362
+ config = JSON.parse(readFileSync(configPath, 'utf8'));
1363
+ } catch {}
1364
+ if (config.mcpServers?.['huaweicloud-devkit']) {
1365
+ delete config.mcpServers['huaweicloud-devkit'];
1366
+ if (Object.keys(config.mcpServers).length === 0) delete config.mcpServers;
1367
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
1368
+ console.log(` Config cleaned: ${configPath}`);
1369
+ }
1370
+ }
1371
+ }
1372
+
1373
+ function codeartsWorkStatus() {
1374
+ const pluginDir = codeartsWorkPluginsDir();
1375
+ console.log(
1376
+ ` MCP Server: ${existsSync(join(pluginDir, 'src', 'mcp-server.mjs')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`,
1377
+ );
1378
+ console.log(
1379
+ ` Safety Policy: ${existsSync(join(pluginDir, 'safety', 'policy.json')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`,
1380
+ );
1381
+ let skillCount = 0;
1382
+ if (existsSync(codeartsWorkSkillsDir())) {
1383
+ skillCount = readdirSync(codeartsWorkSkillsDir(), { withFileTypes: true }).filter(
1384
+ (d) => d.isDirectory() && d.name.startsWith('huawei'),
1385
+ ).length;
1386
+ }
1387
+ console.log(
1388
+ ` Skills: ${skillCount > 0 ? `\x1b[32m${skillCount} installed\x1b[0m` : '\x1b[31mNot installed\x1b[0m'}`,
1389
+ );
1390
+ if (existsSync(codeartsWorkMcpSettingsFile())) {
1391
+ try {
1392
+ const config = JSON.parse(readFileSync(codeartsWorkMcpSettingsFile(), 'utf8'));
1393
+ console.log(
1394
+ ` MCP config: ${config.mcpServers?.['huaweicloud-devkit'] ? '\x1b[32mConfigured\x1b[0m' : '\x1b[31mNot configured\x1b[0m'}`,
1395
+ );
1396
+ } catch {
1397
+ console.log(` MCP config: \x1b[31mInvalid\x1b[0m`);
1398
+ }
1399
+ }
1400
+ }
1401
+
1251
1402
  // Returns true when the config file was written, false when it was already correct.
1252
1403
  function ensureWorkbuddyMcpConfig() {
1253
1404
  const configPath = workbuddyMcpConfigFile();
@@ -2307,6 +2458,7 @@ function autoDetectTarget() {
2307
2458
  ['opencode', () => existsSync(join(homedir(), '.config', 'opencode'))],
2308
2459
  ['codex-desktop', () => existsSync(join(homedir(), '.codex'))],
2309
2460
  ['codearts', () => existsSync(join(homedir(), '.codeartsdoer'))],
2461
+ ['codearts-work', () => existsSync(join(homedir(), '.codeartswork'))],
2310
2462
  ['workbuddy', () => existsSync(join(homedir(), '.workbuddy'))],
2311
2463
  [
2312
2464
  'dsh',
@@ -2359,6 +2511,10 @@ async function cmdInstall() {
2359
2511
  console.log('\n[CodeArts]');
2360
2512
  await installCodeArts();
2361
2513
  }
2514
+ if (target === 'codearts-work' || target === 'all') {
2515
+ console.log('\n[CodeArts Work]');
2516
+ await installCodeArtsWork();
2517
+ }
2362
2518
  if (target === 'workbuddy' || target === 'all') {
2363
2519
  console.log('\n[WorkBuddy]');
2364
2520
  await installWorkBuddy();
@@ -2410,23 +2566,25 @@ async function cmdInstall() {
2410
2566
  const appName =
2411
2567
  target === 'codearts'
2412
2568
  ? 'CodeArts'
2413
- : target === 'codex-desktop'
2414
- ? 'Codex Desktop'
2415
- : target === 'codex'
2416
- ? 'Codex'
2417
- : target === 'workbuddy'
2418
- ? 'WorkBuddy'
2419
- : target === 'dsh'
2420
- ? 'DSH'
2421
- : target === 'officeace'
2422
- ? 'OfficeAce'
2423
- : target === 'hermes'
2424
- ? 'Hermes Agent'
2425
- : target === 'openclaw'
2426
- ? 'OpenClaw'
2427
- : target === 'atomcode'
2428
- ? 'AtomCode'
2429
- : '当前 agent';
2569
+ : target === 'codearts-work'
2570
+ ? 'CodeArts Work'
2571
+ : target === 'codex-desktop'
2572
+ ? 'Codex Desktop'
2573
+ : target === 'codex'
2574
+ ? 'Codex'
2575
+ : target === 'workbuddy'
2576
+ ? 'WorkBuddy'
2577
+ : target === 'dsh'
2578
+ ? 'DSH'
2579
+ : target === 'officeace'
2580
+ ? 'OfficeAce'
2581
+ : target === 'hermes'
2582
+ ? 'Hermes Agent'
2583
+ : target === 'openclaw'
2584
+ ? 'OpenClaw'
2585
+ : target === 'atomcode'
2586
+ ? 'AtomCode'
2587
+ : '当前 agent';
2430
2588
  const pad = ' '.repeat(24 - appName.length);
2431
2589
  if (target === 'officeace') {
2432
2590
  console.log(`\n\x1b[1m\x1b[33m╔══════════════════════════════════════════════════════════╗`);
@@ -2480,17 +2638,19 @@ async function cmdInstall() {
2480
2638
  ? dshPluginsDir()
2481
2639
  : target === 'codearts'
2482
2640
  ? codeartsPluginsDir()
2483
- : target === 'workbuddy'
2484
- ? workbuddyPluginsDir()
2485
- : target === 'officeace'
2486
- ? officeacePluginsDir()
2487
- : target === 'openclaw'
2488
- ? codexDesktopPluginsDir()
2489
- : target === 'atomcode'
2490
- ? atomcodePluginsDir()
2491
- : target === 'codex-desktop'
2492
- ? codexDesktopPluginsDir()
2493
- : opencodePluginsDir();
2641
+ : target === 'codearts-work'
2642
+ ? codeartsWorkPluginsDir()
2643
+ : target === 'workbuddy'
2644
+ ? workbuddyPluginsDir()
2645
+ : target === 'officeace'
2646
+ ? officeacePluginsDir()
2647
+ : target === 'openclaw'
2648
+ ? codexDesktopPluginsDir()
2649
+ : target === 'atomcode'
2650
+ ? atomcodePluginsDir()
2651
+ : target === 'codex-desktop'
2652
+ ? codexDesktopPluginsDir()
2653
+ : opencodePluginsDir();
2494
2654
  mkdirSync(markerDir, { recursive: true });
2495
2655
  writeFileSync(join(markerDir, '.installed'), new Date().toISOString());
2496
2656
  if (target === 'opencode' || target === 'all') {
@@ -2499,6 +2659,9 @@ async function cmdInstall() {
2499
2659
  if (target === 'codearts' || target === 'all') {
2500
2660
  console.log('Or describe your Huawei Cloud task in CodeArts');
2501
2661
  }
2662
+ if (target === 'codearts-work' || target === 'all') {
2663
+ console.log('Or describe your Huawei Cloud task in CodeArts Work');
2664
+ }
2502
2665
  if (target === 'codex' || target === 'all') {
2503
2666
  console.log('Or mention @huaweicloud-core in Codex');
2504
2667
  }
@@ -2532,6 +2695,10 @@ async function cmdUninstall() {
2532
2695
  console.log('\n[CodeArts]');
2533
2696
  uninstallCodeArts();
2534
2697
  }
2698
+ if (target === 'codearts-work' || target === 'all') {
2699
+ console.log('\n[CodeArts Work]');
2700
+ uninstallCodeArtsWork();
2701
+ }
2535
2702
  if (target === 'workbuddy' || target === 'all') {
2536
2703
  console.log('\n[WorkBuddy]');
2537
2704
  uninstallWorkBuddy();
@@ -2596,6 +2763,10 @@ async function cmdStatus() {
2596
2763
  console.log('\n[CodeArts]');
2597
2764
  codeartsStatus();
2598
2765
  }
2766
+ if (target === 'codearts-work' || target === 'all') {
2767
+ console.log('\n[CodeArts Work]');
2768
+ codeartsWorkStatus();
2769
+ }
2599
2770
  if (target === 'workbuddy' || target === 'all') {
2600
2771
  console.log('\n[WorkBuddy]');
2601
2772
  workbuddyStatus();
@@ -2674,6 +2845,7 @@ async function cmdDoctor() {
2674
2845
  const opencodePluginDir = opencodePluginsDir();
2675
2846
  const codexPluginDir = codexDesktopPluginsDir();
2676
2847
  const codeartsPluginDir = codeartsPluginsDir();
2848
+ const codeartsWorkPluginDir = codeartsWorkPluginsDir();
2677
2849
  const workbuddyPluginDir = workbuddyPluginsDir();
2678
2850
  const dshPluginDir = dshPluginsDir();
2679
2851
  const officeacePluginDir = officeacePluginsDir();
@@ -2683,6 +2855,7 @@ async function cmdDoctor() {
2683
2855
  existsSync(join(opencodePluginDir, 'src', 'mcp-server.mjs')) ||
2684
2856
  existsSync(join(codexPluginDir, 'src', 'mcp-server.mjs')) ||
2685
2857
  existsSync(join(codeartsPluginDir, 'src', 'mcp-server.mjs')) ||
2858
+ existsSync(join(codeartsWorkPluginDir, 'src', 'mcp-server.mjs')) ||
2686
2859
  existsSync(join(workbuddyPluginDir, 'src', 'mcp-server.mjs')) ||
2687
2860
  existsSync(join(dshPluginDir, 'src', 'mcp-server.mjs')) ||
2688
2861
  existsSync(join(officeacePluginDir, 'src', 'mcp-server.mjs')) ||
@@ -2727,6 +2900,7 @@ async function cmdDoctor() {
2727
2900
  existsSync(join(opencodePluginDir, 'safety', 'policy.json')) ||
2728
2901
  existsSync(join(codexPluginDir, 'safety', 'policy.json')) ||
2729
2902
  existsSync(join(codeartsPluginDir, 'safety', 'policy.json')) ||
2903
+ existsSync(join(codeartsWorkPluginDir, 'safety', 'policy.json')) ||
2730
2904
  existsSync(join(workbuddyPluginDir, 'safety', 'policy.json')) ||
2731
2905
  existsSync(join(dshPluginDir, 'safety', 'policy.json')) ||
2732
2906
  existsSync(join(officeacePluginDir, 'safety', 'policy.json')) ||
@@ -2875,6 +3049,7 @@ async function cmdDoctor() {
2875
3049
  opencodeSkillsDir(),
2876
3050
  codexDesktopSkillsDir(),
2877
3051
  codeartsSkillsDir(),
3052
+ codeartsWorkSkillsDir(),
2878
3053
  workbuddySkillsDir(),
2879
3054
  dshSkillsDir(),
2880
3055
  officeaceSkillsDir(),
@@ -2934,6 +3109,7 @@ async function cmdDoctor() {
2934
3109
  { path: join(codexDesktopPluginsDir(), '.installed'), name: 'Codex Desktop' },
2935
3110
  { path: join(workbuddyPluginsDir(), '.installed'), name: 'WorkBuddy' },
2936
3111
  { path: join(codeartsPluginsDir(), '.installed'), name: 'CodeArts' },
3112
+ { path: join(codeartsWorkPluginsDir(), '.installed'), name: 'CodeArts Work' },
2937
3113
  { path: join(dshPluginsDir(), '.installed'), name: 'DSH' },
2938
3114
  { path: join(officeacePluginsDir(), '.installed'), name: 'OfficeAce' },
2939
3115
  { path: join(atomcodePluginsDir(), '.installed'), name: 'AtomCode' },
@@ -3006,6 +3182,18 @@ async function cmdUpdate() {
3006
3182
  return;
3007
3183
  }
3008
3184
 
3185
+ if (target === 'codearts-work') {
3186
+ if (!existsSync(join(codeartsWorkPluginsDir(), 'src', 'mcp-server.mjs'))) {
3187
+ console.log('\x1b[33mNot installed. Use "install" command first.\x1b[0m');
3188
+ return;
3189
+ }
3190
+ console.log('[CodeArts Work]');
3191
+ await updateCodeArtsWork();
3192
+ console.log(`\n\x1b[32mUpdate complete.\x1b[0m`);
3193
+ console.log(`\x1b[33mMCP 工具在重启 CodeArts Work 会话后才生效。\x1b[0m`);
3194
+ return;
3195
+ }
3196
+
3009
3197
  if (target === 'workbuddy') {
3010
3198
  if (!existsSync(join(workbuddyPluginsDir(), 'src', 'mcp-server.mjs'))) {
3011
3199
  console.log('\x1b[33mNot installed. Use "install" command first.\x1b[0m');
@@ -3095,6 +3283,11 @@ async function cmdUpdate() {
3095
3283
  await updateCodeArts();
3096
3284
  updatedAny = true;
3097
3285
  }
3286
+ if (existsSync(join(codeartsWorkPluginsDir(), 'src', 'mcp-server.mjs'))) {
3287
+ console.log('\n[CodeArts Work]');
3288
+ await updateCodeArtsWork();
3289
+ updatedAny = true;
3290
+ }
3098
3291
  if (existsSync(join(workbuddyPluginsDir(), 'src', 'mcp-server.mjs'))) {
3099
3292
  console.log('\n[WorkBuddy]');
3100
3293
  await updateWorkBuddy();
@@ -3620,7 +3813,7 @@ async function main() {
3620
3813
  default:
3621
3814
  console.log(BANNER);
3622
3815
  console.log(
3623
- 'Usage: npx huaweicloud-devkit <command> [--target <opencode|codex|codearts|workbuddy|dsh|officeace|hermes|openclaw|atomcode|all>]\n',
3816
+ 'Usage: npx huaweicloud-devkit <command> [--target <opencode|codex|codearts|codearts-work|workbuddy|dsh|officeace|hermes|openclaw|atomcode|all>]\n',
3624
3817
  );
3625
3818
  console.log('Commands:');
3626
3819
  console.log(' install Install skills, MCP server, safety policy');
@@ -3635,12 +3828,13 @@ async function main() {
3635
3828
  console.log(' help Show this help');
3636
3829
  console.log('\nOptions:');
3637
3830
  console.log(
3638
- ' --target Target agent: opencode (default), codex, codearts, workbuddy, dsh, officeace, hermes, openclaw, atomcode, all',
3831
+ ' --target Target agent: opencode (default), codex, codearts, codearts-work, workbuddy, dsh, officeace, hermes, openclaw, atomcode, all',
3639
3832
  );
3640
3833
  console.log('\nExamples:');
3641
3834
  console.log(' npx huaweicloud-devkit install');
3642
3835
  console.log(' npx huaweicloud-devkit install --target codex');
3643
3836
  console.log(' npx huaweicloud-devkit install --target codearts');
3837
+ console.log(' npx huaweicloud-devkit install --target codearts-work');
3644
3838
  console.log(' npx huaweicloud-devkit install --target workbuddy');
3645
3839
  console.log(' npx huaweicloud-devkit install --target dsh');
3646
3840
  console.log(' npx huaweicloud-devkit install --target officeace');
@@ -48,6 +48,10 @@ function codeartsSkillsDir() {
48
48
  const home = homedir();
49
49
  return join(home, '.codeartsdoer', 'skills');
50
50
  }
51
+ function codeartsWorkSkillsDir() {
52
+ const home = homedir();
53
+ return join(home, '.codeartswork', 'skills');
54
+ }
51
55
  function workbuddySkillsDir() {
52
56
  const home = homedir();
53
57
  return join(home, '.workbuddy', 'skills');
@@ -126,6 +130,7 @@ function resolveSkillsRoot() {
126
130
  SKILLS_ROOT_DEV,
127
131
  dshSkillsDir(),
128
132
  codeartsSkillsDir(),
133
+ codeartsWorkSkillsDir(),
129
134
  opencodeSkillsDir(),
130
135
  workbuddySkillsDir(),
131
136
  officeaceSkillsRoot(),
@@ -449,7 +454,7 @@ export const TOOL_DEFINITIONS = [
449
454
  target: {
450
455
  type: 'string',
451
456
  description:
452
- 'Agent target to check: opencode, codex, codex-desktop, codearts, workbuddy, dsh, officeace, hermes, openclaw, atomcode, or all (default).',
457
+ 'Agent target to check: opencode, codex, codex-desktop, codearts, codearts-work, workbuddy, dsh, officeace, hermes, openclaw, atomcode, or all (default).',
453
458
  },
454
459
  },
455
460
  },
@@ -464,7 +469,7 @@ export const TOOL_DEFINITIONS = [
464
469
  target: {
465
470
  type: 'string',
466
471
  description:
467
- 'Agent target to report after sync: opencode, codex, codex-desktop, codearts, workbuddy, dsh, officeace, hermes, or all (default).',
472
+ 'Agent target to report after sync: opencode, codex, codex-desktop, codearts, codearts-work, workbuddy, dsh, officeace, hermes, or all (default).',
468
473
  },
469
474
  },
470
475
  },
@@ -614,7 +619,7 @@ export const TOOL_DEFINITIONS = [
614
619
  config_name: {
615
620
  type: 'string',
616
621
  description:
617
- 'Config file name (without .conf suffix). Defaults to app. Use distinct names (e.g. admin, docs) for multi-app deployments to avoid config overwrites.',
622
+ 'Config file name (without .conf suffix). Defaults to the project name, ensuring each project gets its own config. Override with distinct names (e.g. admin, docs) for sub-app deployments.',
618
623
  },
619
624
  workspace_id: {
620
625
  type: 'string',