huaweicloud-devkit 1.1.0-next.7 → 1.1.0-next.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.
package/README.md CHANGED
@@ -114,6 +114,7 @@ npx --yes huaweicloud-devkit uninstall --target hermes
114
114
  ```
115
115
 
116
116
  > **Safety hooks**: The installer configures Hermes shell hooks (`config.yaml` → `hooks.pre_tool_call`) to intercept unsafe terminal commands such as credential file reads, environment variable dumps, and unapproved `hcloud` write operations. Hermes shows a consent prompt the first time; approve it or set `hooks_auto_accept: true` in `config.yaml` to auto-accept.
117
+ > **MCP Python SDK**: The installer automatically installs the `mcp` Python package required by Hermes for MCP tool discovery. If you see `[FAIL] Hermes MCP Python SDK` in `doctor`, run `pip3 install mcp` manually.
117
118
  > **Windows**: Hermes on Windows stores data under `%LOCALAPPDATA%\hermes` instead of `~/.hermes`. The installer detects this automatically.
118
119
 
119
120
  ### OpenClaw
package/README.zh-CN.md CHANGED
@@ -114,6 +114,7 @@ npx --yes huaweicloud-devkit uninstall --target hermes
114
114
  ```
115
115
 
116
116
  > **安全钩子(Safety hooks)**:安装器会在 `config.yaml` 中写入 shell hooks 配置(`hooks.pre_tool_call`),拦截不安全的终端命令,如读取凭据文件、导出环境变量、未审批的 `hcloud` 写操作。Hermes 首次使用时会弹出同意提示,可批准或设置 `hooks_auto_accept: true` 自动批准。
117
+ > **MCP Python SDK**:安装器会自动安装 Hermes 所需的 `mcp` Python 包。如果 doctor 显示 `[FAIL] Hermes MCP Python SDK`,手动执行 `pip3 install mcp`。
117
118
  > **Windows**:Hermes 在 Windows 上数据存储在 `%LOCALAPPDATA%\hermes` 而非 `~/.hermes`,安装器会自动检测适配。
118
119
 
119
120
  ### OpenClaw
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-devkit",
3
- "version": "1.1.0-next.7",
3
+ "version": "1.1.0-next.8",
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.7",
20
+ "version": "1.1.0-next.8",
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.7",
23
+ "version": "1.1.0-next.8",
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.7",
20
+ "version": "1.1.0-next.8",
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.7",
3
+ "version": "1.1.0-next.8",
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.7",
3
+ "version": "1.1.0-next.8",
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.7",
5
+ "version": "1.1.0-next.8",
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.",
@@ -299,14 +299,20 @@ async function createTarGz(localDir, exclude = []) {
299
299
  mkdirSync(archiveDir, { recursive: true });
300
300
  const archivePath = join(archiveDir, archiveName);
301
301
 
302
- const args = [
303
- ...exclude.flatMap((p) => ['--exclude', p]),
304
- '-czf',
305
- archivePath,
306
- '-C',
307
- dirname(localDir),
308
- basename(localDir),
309
- ];
302
+ const args = [];
303
+ for (const pattern of exclude) {
304
+ if (pattern.startsWith('**/')) {
305
+ const base = pattern.slice(3);
306
+ for (let depth = 0; depth <= 4; depth++) {
307
+ const prefix = depth === 0 ? '' : '*/'.repeat(depth);
308
+ args.push('--exclude', `${prefix}${base}`);
309
+ }
310
+ } else {
311
+ args.push('--exclude', pattern);
312
+ }
313
+ }
314
+ args.push('-czf', archivePath, '-C', dirname(localDir), basename(localDir));
315
+
310
316
  await execFileAsync('tar', args);
311
317
  return archivePath;
312
318
  }
@@ -2098,6 +2098,41 @@ function removeHermesHooksConfigBlock() {
2098
2098
  console.log(' Hooks config cleaned');
2099
2099
  }
2100
2100
 
2101
+ function ensureHermesMcpSdk() {
2102
+ const pythonBin = process.platform === 'win32' ? 'python' : 'python3';
2103
+ try {
2104
+ const r = spawnSync(pythonBin, ['-c', 'import mcp; print("ok")'], { encoding: 'utf8', timeout: 5000 });
2105
+ if (r.status === 0 && r.stdout.trim() === 'ok') {
2106
+ console.log(' MCP Python SDK: \x1b[32mAlready installed\x1b[0m');
2107
+ return true;
2108
+ }
2109
+ } catch {}
2110
+ console.log(' Installing Hermes MCP Python SDK...');
2111
+ try {
2112
+ const pip = spawnSync(pythonBin, ['-m', 'pip', 'install', 'mcp', '--quiet'], { encoding: 'utf8', timeout: 60000 });
2113
+ if (pip.status === 0) {
2114
+ console.log(' MCP Python SDK: \x1b[32mInstalled\x1b[0m');
2115
+ return true;
2116
+ }
2117
+ console.log(` MCP Python SDK: \x1b[33mInstall failed\x1b[0m`);
2118
+ console.log(` \x1b[33m Run manually: ${pythonBin} -m pip install mcp\x1b[0m`);
2119
+ } catch (error) {
2120
+ console.log(` MCP Python SDK: \x1b[33m${error.message}\x1b[0m`);
2121
+ console.log(` \x1b[33m Run manually: ${pythonBin} -m pip install mcp\x1b[0m`);
2122
+ }
2123
+ return false;
2124
+ }
2125
+
2126
+ function hermesMcpSdkOk() {
2127
+ const pythonBin = process.platform === 'win32' ? 'python' : 'python3';
2128
+ try {
2129
+ const r = spawnSync(pythonBin, ['-c', 'import mcp; print("ok")'], { encoding: 'utf8', timeout: 5000 });
2130
+ return r.status === 0 && r.stdout.trim() === 'ok';
2131
+ } catch {
2132
+ return false;
2133
+ }
2134
+ }
2135
+
2101
2136
  async function installHermes() {
2102
2137
  const skillsSrc = join(PLUGIN_ROOT, 'skills');
2103
2138
  const srcDir = join(PLUGIN_ROOT, 'src');
@@ -2121,6 +2156,7 @@ async function installHermes() {
2121
2156
  if (!skipMcp) ensureHermesMcpConfig();
2122
2157
  ensureHermesHooksConfig();
2123
2158
  if (!skipMcp) installRuntimeDeps(pluginDest);
2159
+ if (!skipMcp) ensureHermesMcpSdk();
2124
2160
  }
2125
2161
 
2126
2162
  async function updateHermes() {
@@ -2141,6 +2177,7 @@ async function updateHermes() {
2141
2177
  console.log(` Safety Hooks updated -> ${join(pluginDest, 'hooks')}`);
2142
2178
  ensureHermesMcpConfig();
2143
2179
  ensureHermesHooksConfig();
2180
+ ensureHermesMcpSdk();
2144
2181
  mkdirSync(pluginDest, { recursive: true });
2145
2182
  writeFileSync(join(pluginDest, '.installed'), new Date().toISOString());
2146
2183
  installRuntimeDeps(pluginDest);
@@ -2184,6 +2221,7 @@ function hermesStatus() {
2184
2221
  console.log(
2185
2222
  ` Safety Hooks: ${existsSync(join(pluginDir, 'hooks', 'huaweicloud-safety.py')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`,
2186
2223
  );
2224
+ console.log(` MCP Python SDK: ${hermesMcpSdkOk() ? '\x1b[32mReady\x1b[0m' : '\x1b[31mMissing\x1b[0m'}`);
2187
2225
  let skillCount = 0;
2188
2226
  if (existsSync(skillsDir)) {
2189
2227
  skillCount = readdirSync(skillsDir, { withFileTypes: true }).filter(
@@ -2766,6 +2804,14 @@ async function cmdDoctor() {
2766
2804
  mcpCfgTarget ? `Found in ${mcpCfgTarget} config` : 'Run: npx huaweicloud-devkit install',
2767
2805
  );
2768
2806
 
2807
+ // Hermes MCP Python SDK (only checked when Hermes config is found)
2808
+ if (
2809
+ mcpCfgTarget === 'Hermes Agent' ||
2810
+ (existsSync(hermesConfigFile()) && readFileSync(hermesConfigFile(), 'utf8').includes('mcp_servers'))
2811
+ ) {
2812
+ check('Hermes MCP Python SDK', hermesMcpSdkOk(), 'Run: pip3 install mcp');
2813
+ }
2814
+
2769
2815
  // hcloud CLI
2770
2816
  const hcloudBin = findHcloudBin() || process.env.HCLOUD_BIN || 'hcloud';
2771
2817
  const hcloudCheck = spawnSync(`"${hcloudBin}" version`, [], {