huaweicloud-devkit 1.1.9 → 1.1.10-next.0
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/plugins/huaweicloud-core/.claude-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.codex-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.cursor-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.hermes-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.workbuddy-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/openclaw.plugin.json +1 -1
- package/plugins/huaweicloud-core/safety/rules/cloud-risk-rules.json +1 -1
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/create-instance.md +26 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/hc-activity.md +16 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/troubleshooting.md +51 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/windows-ssh.md +24 -0
- package/plugins/huaweicloud-core/skills/huawei-iac/SKILL.md +38 -36
- package/plugins/huaweicloud-core/skills/huawei-iam/SKILL.md +35 -16
- package/plugins/huaweicloud-core/skills/huawei-iam/references/quick-ref.md +35 -0
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +8 -1
- package/plugins/huaweicloud-core/src/account-type.mjs +135 -0
- package/plugins/huaweicloud-core/src/hcloud-cli.mjs +15 -1
- package/plugins/huaweicloud-core/src/safety-policy.mjs +36 -5
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +172 -21
- package/plugins/huaweicloud-core/src/tools.mjs +55 -5
|
@@ -9,6 +9,7 @@ import { createHmac, createHash } from 'node:crypto';
|
|
|
9
9
|
import { evaluateArtifacts, evaluateCommandRisk, evaluateDeployPlan } from './risk-rule-engine.mjs';
|
|
10
10
|
import { classifyTextCommand, redactSecrets } from './safety-policy.mjs';
|
|
11
11
|
import { planHcloudCommand, runHcloud, consumeApprovalToken, inspectApprovalToken, hashArgs } from './hcloud-cli.mjs';
|
|
12
|
+
import { checkAccountType } from './account-type.mjs';
|
|
12
13
|
import { searchMarketplace } from './search-market.mjs';
|
|
13
14
|
import { getServiceIcon } from './icon-library.mjs';
|
|
14
15
|
import { detectFramework } from './detect-framework.mjs';
|
|
@@ -420,6 +421,21 @@ export const TOOL_DEFINITIONS = [
|
|
|
420
421
|
properties: {},
|
|
421
422
|
},
|
|
422
423
|
},
|
|
424
|
+
{
|
|
425
|
+
name: 'huaweicloud_check_account_type',
|
|
426
|
+
description:
|
|
427
|
+
'Check whether the current credentials belong to the primary account or an IAM sub-user. Runs STS GetCallerIdentity + IAM KeystoneListAuthDomains (both read-only, no identity-policy permission required) and applies the validated rule: username == domainName -> primary account, otherwise IAM sub-user. Use before sandbox deployment (primary-account prechecks), account confirmation, or any task that needs to know who the current AK/SK belongs to. Returns isPrimaryAccount, applicable, domainId, domainName, userId, username, principalUrn, and an evidence string. Agency-session credentials are detected and reported as applicable:false.',
|
|
428
|
+
inputSchema: {
|
|
429
|
+
type: 'object',
|
|
430
|
+
properties: {
|
|
431
|
+
region: {
|
|
432
|
+
type: 'string',
|
|
433
|
+
description:
|
|
434
|
+
'Optional region ID for the region-level GetCallerIdentity endpoint (e.g., cn-north-4). Defaults to the configured cli-region.',
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
},
|
|
423
439
|
{
|
|
424
440
|
name: 'huaweicloud_get_regional_availability',
|
|
425
441
|
description:
|
|
@@ -621,12 +637,16 @@ export const TOOL_DEFINITIONS = [
|
|
|
621
637
|
{
|
|
622
638
|
name: 'huaweicloud_sandbox_upload_file',
|
|
623
639
|
description:
|
|
624
|
-
'Upload a local file into the sandbox workspace. Base64-encodes the file, writes it in small chunks through the terminal session (the exec channel is fragile for large single commands), then decodes and verifies the md5 checksum. Use this instead of embedding large file content directly in a command.',
|
|
640
|
+
'Upload a local file into the sandbox workspace. Base64-encodes the file, writes it in small chunks through the terminal session (the exec channel is fragile for large single commands), then decodes and verifies the md5 checksum. The remote parent directory is created automatically if absent. Use this instead of embedding large file content directly in a command. local_path must be readable from the machine running the DevKit MCP server — if the file lives elsewhere, copy it to the local temp directory first.',
|
|
625
641
|
inputSchema: {
|
|
626
642
|
type: 'object',
|
|
627
643
|
required: ['local_path', 'remote_path'],
|
|
628
644
|
properties: {
|
|
629
|
-
local_path: {
|
|
645
|
+
local_path: {
|
|
646
|
+
type: 'string',
|
|
647
|
+
description:
|
|
648
|
+
'Absolute path to the local file, readable from the machine running the DevKit MCP server (copy to the local temp dir first if not).',
|
|
649
|
+
},
|
|
630
650
|
remote_path: { type: 'string', description: 'Target path in the sandbox, e.g. /workspace/<repo>/index.html.' },
|
|
631
651
|
workspace_id: {
|
|
632
652
|
type: 'string',
|
|
@@ -641,12 +661,16 @@ export const TOOL_DEFINITIONS = [
|
|
|
641
661
|
{
|
|
642
662
|
name: 'huaweicloud_sandbox_upload_project',
|
|
643
663
|
description:
|
|
644
|
-
'Package a local project directory and upload it to a sandbox workspace via HTTP tunnel. Falls back to base64 chunking if tunnel fails. Creates a tar.gz archive, uploads it, and extracts it on the sandbox by default.',
|
|
664
|
+
'Package a local project directory and upload it to a sandbox workspace via HTTP tunnel. Falls back to base64 chunking if tunnel fails. Creates a tar.gz archive, uploads it, and extracts it on the sandbox by default. local_dir must be readable from the machine running the DevKit MCP server — if the project lives elsewhere, copy it to the local temp directory first.',
|
|
645
665
|
inputSchema: {
|
|
646
666
|
type: 'object',
|
|
647
667
|
required: ['local_dir'],
|
|
648
668
|
properties: {
|
|
649
|
-
local_dir: {
|
|
669
|
+
local_dir: {
|
|
670
|
+
type: 'string',
|
|
671
|
+
description:
|
|
672
|
+
'Local project directory, readable from the machine running the DevKit MCP server (copy to the local temp dir first if not).',
|
|
673
|
+
},
|
|
650
674
|
remote_dir: {
|
|
651
675
|
type: 'string',
|
|
652
676
|
description:
|
|
@@ -1186,6 +1210,8 @@ export async function callTool(name, rawArgs = {}, opts = {}) {
|
|
|
1186
1210
|
return retrieveSkill(args.name || '');
|
|
1187
1211
|
case 'huaweicloud_list_regions':
|
|
1188
1212
|
return listRegions();
|
|
1213
|
+
case 'huaweicloud_check_account_type':
|
|
1214
|
+
return checkAccountType(args);
|
|
1189
1215
|
case 'huaweicloud_get_regional_availability':
|
|
1190
1216
|
return getRegionalAvailability(args.service || '', args.region || '');
|
|
1191
1217
|
case 'huaweicloud_explain_error':
|
|
@@ -2279,8 +2305,18 @@ function explainError({ service = 'unknown', errorCode = '', message = '', reque
|
|
|
2279
2305
|
fgs: 'FSS',
|
|
2280
2306
|
ecs: 'Ecs',
|
|
2281
2307
|
ECS: 'Ecs',
|
|
2308
|
+
kps: 'Kps',
|
|
2309
|
+
KPS: 'Kps',
|
|
2282
2310
|
};
|
|
2283
|
-
|
|
2311
|
+
// #935 E2E-B1: real MCP calls pass only errorCode (e.g. Ecs.0019, KPS.9004)
|
|
2312
|
+
// with no service — derive the service key from the dotted-code prefix so the
|
|
2313
|
+
// service-keyed mapping table is hit. Explicit service behavior is unchanged.
|
|
2314
|
+
let resolvedService = service;
|
|
2315
|
+
if ((!service || svc === 'unknown') && /^[A-Za-z]+\.\w+/.test(errorCode)) {
|
|
2316
|
+
const prefix = errorCode.split('.')[0].toLowerCase();
|
|
2317
|
+
resolvedService = SERVICE_ALIASES[prefix] || errorCode.split('.')[0].toUpperCase();
|
|
2318
|
+
}
|
|
2319
|
+
const patternKey = SERVICE_ALIASES[svc] || resolvedService;
|
|
2284
2320
|
|
|
2285
2321
|
const hwErrorPatterns = {
|
|
2286
2322
|
OBS: {
|
|
@@ -2309,6 +2345,14 @@ function explainError({ service = 'unknown', errorCode = '', message = '', reque
|
|
|
2309
2345
|
Ecs: {
|
|
2310
2346
|
'Ecs.0707':
|
|
2311
2347
|
'The flavor + image-type combination does not exist ("the product does not exist") — the error does not say which side is wrong, so check BOTH (#922): (1) the flavor is abandoned/sellout in this region/AZ (check os_extra_specs.cond:operation:status and cond:operation:az; see the huawei-ecs skill references/flavors.md for the AZ-vs-global-status conflict rule); (2) the image TYPE is incompatible with the flavor — market-type images fail with KunPeng flavors (kc1/kc2 etc.). Fix: switch the image to a gold-type image or switch to a compatible general-purpose flavor (verified: kc2.small.2 + market Ubuntu → Ecs.0707; s6.medium.2 + gold Ubuntu works), re-listing with hcloud ECS ListFlavors / hcloud IMS ListImages --__imagetype=gold first.',
|
|
2348
|
+
// #935 (report 4 problem 1 / report 1 坑5): real-world ECS order failures
|
|
2349
|
+
// with no mapping — flavor offline, AZ capacity, balance, keypair restriction.
|
|
2350
|
+
'Ecs.0019':
|
|
2351
|
+
'The flavor has been taken offline (Ecs.0019). Run `hcloud ECS ListFlavors --cli-region=<region>` to query currently on-sale flavors and switch to a replacement flavor (see the huawei-ecs skill references/flavors.md for the cond:operation:status field rules — a flavor marked 卖光/下线 keeps failing until you pick an on-sale one), then recreate.',
|
|
2352
|
+
'Ecs.0319':
|
|
2353
|
+
'The requested flavor has insufficient capacity in the selected availability zone (Ecs.0319). Fix: retry in a different availability zone, or switch to a replacement flavor (list on-sale flavors with `hcloud ECS ListFlavors --cli-region=<region>`), then recreate.',
|
|
2354
|
+
'Ecs.0067':
|
|
2355
|
+
'Order submission rejected for balance reasons (Ecs.0067). Check the cash balance with `hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1` and top up if needed — pay-per-use order risk control checks the CASH balance only (代金券/vouchers do NOT participate in order risk control; they only offset the bill at settlement). Also settle any historical arrears, however small, before retrying.',
|
|
2312
2356
|
},
|
|
2313
2357
|
APIGW: {
|
|
2314
2358
|
'APIGW.0301':
|
|
@@ -2316,6 +2360,12 @@ function explainError({ service = 'unknown', errorCode = '', message = '', reque
|
|
|
2316
2360
|
'APIGW.0802':
|
|
2317
2361
|
'The current IAM user has no permissions in the requested region. Go to IAM console → Users → Permissions → add the target region, or switch to a different region.',
|
|
2318
2362
|
},
|
|
2363
|
+
// #935 (report 1 坑5): KPS keypair creation has its own restriction code —
|
|
2364
|
+
// the Kps service had no entry at all, so the error fell through to generic advice.
|
|
2365
|
+
Kps: {
|
|
2366
|
+
'KPS.9004':
|
|
2367
|
+
'Keypair creation rejected for account restrictions (KPS.9004). Check the cash balance with `hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1` and top up if needed, and settle any historical arrears (even a small unpaid amount triggers this) — then retry `hcloud ECS NovaCreateKeypair` or create the keypair in the console.',
|
|
2368
|
+
},
|
|
2319
2369
|
};
|
|
2320
2370
|
if (hwErrorPatterns[patternKey] && hwErrorPatterns[patternKey][errorCode]) {
|
|
2321
2371
|
suggestions.push(hwErrorPatterns[patternKey][errorCode]);
|