huaweicloud-devkit 1.1.1-next.12 → 1.1.1-next.13
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 +5 -0
- package/README.zh-CN.md +5 -0
- 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/skills/huawei-apig/SKILL.md +4 -0
- package/plugins/huaweicloud-core/skills/huawei-cce/SKILL.md +4 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/SKILL.md +1 -1
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/SKILL.md +4 -0
- package/plugins/huaweicloud-core/skills/huawei-iac/SKILL.md +93 -0
- package/plugins/huaweicloud-core/skills/huawei-iac/references/architectures.md +83 -0
- package/plugins/huaweicloud-core/skills/huawei-iac/references/resource-catalog.md +106 -0
- package/plugins/huaweicloud-core/skills/huawei-iac/references/state-file.md +104 -0
- package/plugins/huaweicloud-core/skills/huawei-obs/SKILL.md +1 -1
- package/plugins/huaweicloud-core/skills/huawei-rds/SKILL.md +4 -0
- package/plugins/huaweicloud-core/skills/huaweicloud-core/SKILL.md +25 -24
- package/plugins/huaweicloud-core/src/sandbox/uninstall-cleanup.mjs +50 -0
- package/plugins/huaweicloud-core/src/setup-cli.mjs +137 -2
package/README.md
CHANGED
|
@@ -27,6 +27,11 @@ Supports OpenCode, Codex, CodeArts Agent, WorkBuddy, DeepSeek Harness (DSH), Off
|
|
|
27
27
|
|
|
28
28
|
> If `--target` is omitted, the installer auto-detects agents on your machine. When multiple agents are detected, **all of them** will be installed. Specify `--target` to control which agent receives the install.
|
|
29
29
|
|
|
30
|
+
```bash
|
|
31
|
+
npx --yes huaweicloud-devkit version # print the installed plugin version per agent
|
|
32
|
+
npx --yes huaweicloud-devkit uninstall --target all --clean-global # also remove KooCLI + OBS config
|
|
33
|
+
```
|
|
34
|
+
|
|
30
35
|
### OpenCode
|
|
31
36
|
|
|
32
37
|
```bash
|
package/README.zh-CN.md
CHANGED
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
|
|
28
28
|
> 省略 `--target` 时,安装器会自动检测机器上的 agent,检测到多个时**全部安装**。建议始终指定 `--target` 以明确安装目标。
|
|
29
29
|
|
|
30
|
+
```bash
|
|
31
|
+
npx --yes huaweicloud-devkit version # 查看各 agent 已安装的插件版本
|
|
32
|
+
npx --yes huaweicloud-devkit uninstall --target all --clean-global # 一并删除 KooCLI 与 OBS 配置
|
|
33
|
+
```
|
|
34
|
+
|
|
30
35
|
### OpenCode
|
|
31
36
|
|
|
32
37
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.1-next.
|
|
3
|
+
"version": "1.1.1-next.13",
|
|
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.1-next.
|
|
20
|
+
"version": "1.1.1-next.13",
|
|
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.1-next.
|
|
23
|
+
"version": "1.1.1-next.13",
|
|
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.1-next.
|
|
20
|
+
"version": "1.1.1-next.13",
|
|
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.1-next.
|
|
3
|
+
"version": "1.1.1-next.13",
|
|
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.1-next.
|
|
3
|
+
"version": "1.1.1-next.13",
|
|
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.1-next.
|
|
5
|
+
"version": "1.1.1-next.13",
|
|
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.",
|
|
@@ -8,6 +8,10 @@ version: 1
|
|
|
8
8
|
|
|
9
9
|
**STOP - Do not answer from general knowledge.** Follow the procedure below.
|
|
10
10
|
|
|
11
|
+
## Deployment Routing Guard
|
|
12
|
+
|
|
13
|
+
If this skill was reached via a DEPLOYMENT intent (the gateway instance is part of an application deployment, not a standalone ad-hoc operation), this is a cloud resource purchase: load `huawei-iac` first for orchestration (mandatory cost+balance gate, batch approval, session state, ordered destroy), then return here for the exact instance/API commands. Sandbox-deployed workloads (huawei-sandbox) bypass iac - no purchase involved.
|
|
14
|
+
|
|
11
15
|
## Overview
|
|
12
16
|
|
|
13
17
|
Domain expertise for Huawei Cloud API Gateway (APIG). Covers instance lifecycle, API group/API creation, publishing, and FunctionGraph trigger integration.
|
|
@@ -10,6 +10,10 @@ version: 1
|
|
|
10
10
|
|
|
11
11
|
Always run `hcloud <Service> <Operation> --help` before constructing commands to discover exact parameter names and requirements.
|
|
12
12
|
|
|
13
|
+
## Deployment Routing Guard
|
|
14
|
+
|
|
15
|
+
If this skill was reached via a DEPLOYMENT intent (the cluster is part of an application deployment, not a standalone ad-hoc operation), this is a cloud resource purchase: load `huawei-iac` first for orchestration (mandatory cost+balance gate, batch approval, session state, ordered destroy), then return here for the exact cluster/nodepool commands. Sandbox-deployed workloads (huawei-sandbox) bypass iac - no purchase involved.
|
|
16
|
+
|
|
13
17
|
## Overview
|
|
14
18
|
|
|
15
19
|
Domain expertise for CCE (Cloud Container Engine) and SWR (Software Repository for Container). CCE uses two hcloud services: `CCE` for clusters and `SWR` for container images.
|
|
@@ -24,7 +24,7 @@ Before creating an ECS instance from scratch, you MUST have:
|
|
|
24
24
|
- A subnet with DNS configured (see `huawei-vpc`)
|
|
25
25
|
- A security group with application ports open (see `huawei-vpc`)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
**Deployment routing guard**: if this skill was reached via a DEPLOYMENT intent (creating resources to host an application), load the `huawei-iac` skill FIRST and follow its orchestration flow - UNCONDITIONALLY. Reusing an existing VPC does NOT make it single-resource: the purchase still involves billable resources (ECS, system disk, EIP, keypair, SG rules) that must pass the cost+balance gate, batch approval, and state tracking. Only create directly here if the user explicitly declines the orchestration flow or the user only wants a lifecycle operation on an EXISTING instance (query/reboot/resize/delete). Discovery already done (flavors, images, AZs) carries over.
|
|
28
28
|
|
|
29
29
|
## Critical Warnings
|
|
30
30
|
|
|
@@ -8,6 +8,10 @@ version: 1
|
|
|
8
8
|
|
|
9
9
|
**STOP - Do not answer from general knowledge.** Follow the procedure below.
|
|
10
10
|
|
|
11
|
+
## Deployment Routing Guard
|
|
12
|
+
|
|
13
|
+
If this skill was reached via a DEPLOYMENT intent ("部署/搭建/上线一个应用/接口" - the function is part of an application deployment), this is a cloud resource purchase: load `huawei-iac` first for orchestration (mandatory cost+balance gate, batch approval, session state, ordered destroy), then return here for the exact function/trigger commands. Direct function operations (query/update/debug an existing function) do not need iac.
|
|
14
|
+
|
|
11
15
|
## Overview
|
|
12
16
|
|
|
13
17
|
Domain expertise for Huawei Cloud FunctionGraph. Covers function lifecycle, code deployment, trigger configuration, and troubleshooting.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: huawei-iac
|
|
3
|
+
description: 'Use whenever the user wants to DEPLOY, host, or purchase anything on Huawei Cloud that creates billable resources: application deployments (部署应用到华为云, deploy my app, 上线, 搭建), architecture proposals, cost estimation, multi-resource provisioning (VPC, subnet, security group, ECS, EIP, RDS, OBS, CDN, DNS, FunctionGraph, CCE, GaussDB and more), session-scoped state tracking, and reverse-order destroy. Trigger words: 部署, 部署到华为云, 上线, 购买, 搭建, 开通, 成本估算, 多少钱, 销毁, deploy, deploy to Huawei Cloud, provision, purchase, architecture, hosting. Reusing an existing VPC does NOT make it single-resource - any purchase (ECS, EIP, disk, keypair, rules) must pass the cost+balance gate here. NOT for: sandbox preview (huawei-sandbox - free, no purchase), read-only or lifecycle operations on EXISTING resources (query/reboot/resize/delete - use the service skill directly).'
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Huawei Cloud IaC Orchestration
|
|
8
|
+
|
|
9
|
+
**STOP - Do not answer from general knowledge.** Follow the 8-stage workflow below in strict order.
|
|
10
|
+
|
|
11
|
+
Always run `hcloud <Service> <Operation> --help` before constructing commands to discover exact parameter names and requirements.
|
|
12
|
+
|
|
13
|
+
## Scope and Routing Guard
|
|
14
|
+
|
|
15
|
+
- This skill orchestrates the **purchase lifecycle of ALL supported resources**: proposal → pricing → provisioning → destroy, across every service in the plugin catalog.
|
|
16
|
+
- **Web app deployment keeps sandbox as the first choice** (see `huaweicloud-core` Deployment Target Options). Route here only when the user wants billed, long-term, or multi-resource cloud infrastructure, or explicitly asks for an architecture + cost proposal.
|
|
17
|
+
- Single-resource tasks go directly to the service skill. This skill adds value for **multi-resource orchestration, mandatory cost gating, and ordered destroy**.
|
|
18
|
+
|
|
19
|
+
## Workflow (strict order)
|
|
20
|
+
|
|
21
|
+
**Proactive by design**: any deployment intent ("部署一个博客", "搭一套环境", "买个服务器") automatically triggers stages 1-5 BEFORE anything is created. The user NEVER needs to ask for an architecture proposal, cost estimate, or risk warnings - they are built into the flow. Only stages 6-8 (create / verify / manage) wait for explicit user confirmation at the approval gates.
|
|
22
|
+
|
|
23
|
+
| Stage | What happens | Hard rule |
|
|
24
|
+
| -------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| 1. Scale assessment | Classify: personal / small business / enterprise → product mix | **If the scale is not stated or clearly inferable, ASK - present the 3 tiers as options with what each includes and its monthly cost band** (see `references/architectures.md`), and let the user choose. Never assume a tier. FunctionGraph filesystem is ephemeral - never recommend SQLite/local files for persistent data |
|
|
26
|
+
| 2. Frontend hosting choice | Present BOTH options: (a) OBS+CDN+DNS custom domain, (b) ECS+EIP | For option (a) three prerequisites: domain ownership verification (CDN requires a DNS record or file upload first - `CDN.00010185` otherwise), ICP filing check, DNS hosting check; domain registration link: https://www.huaweicloud.com/product/domain.html |
|
|
27
|
+
| 3. Architecture proposal | ASCII topology tree with dependencies | User confirms before continuing |
|
|
28
|
+
| 4. Parameter discovery | `ListFlavors` / `ListImages` / `huaweicloud_list_regions` | Never hardcode flavor/image names |
|
|
29
|
+
| 5. Cost + balance gate | Price every resource via BSS `ListOnDemandResourceRatings`, then query balance | Balance = 0 → the FIRST message must state: "您的余额为 0,按时长计费的资源(ECS/EIP/RDS 等)需要交保证金。保证金与余额是两个概念——它是可退还的押金,且是代金券正常使用的前提"。Remedy priority: (1) FIRST claim the one-time incentive voucher (huaweicloud_voucher_status → huaweicloud_voucher_claim) to offset usage fees; (2) then instruct the user to pay the refundable deposit so the voucher applies and orders pass (otherwise `Ecs.7000`); (3) free-tier resources (FunctionGraph, small OBS) may proceed meanwhile without deposit. Balance > 0 → report how long it can sustain (balance ÷ monthly estimate). Pricing codes are per-service - never guess them; see `references/resource-catalog.md` § Pricing |
|
|
30
|
+
| 6. Provision | deployment_id, session state, batch approval, ordered creation | See "Provisioning Rules" below |
|
|
31
|
+
| 7. Verify | `curl -I` the site / API; expect 200 | DNS CNAME may take minutes to propagate - not an error |
|
|
32
|
+
| 8. Manage | Session-scoped status query and destroy | See "Destroy Rules" below |
|
|
33
|
+
|
|
34
|
+
## Provisioning Rules (Stage 6)
|
|
35
|
+
|
|
36
|
+
1. Generate `deployment_id` (`d-xxx`), initialize the session state file (path and schema: `references/state-file.md`).
|
|
37
|
+
2. **Batch approval: show the RESOURCE LIST (name / type / purpose), never the raw commands.** After the user approves, execute each resource via `huaweicloud_run_approved_command`. Never execute anything outside the approved list.
|
|
38
|
+
3. Create in dependency-topological order (network → compute/db → bindings). After each success, extract the resource ID and write it to state immediately.
|
|
39
|
+
4. Any failure: stop immediately, mark state `partial`, report the error, offer destroy of already-created resources. No automatic rollback.
|
|
40
|
+
|
|
41
|
+
## Destroy Rules (Stage 8, current session only)
|
|
42
|
+
|
|
43
|
+
Preconditions - all required:
|
|
44
|
+
|
|
45
|
+
1. Session state file exists and contains the deployment_id (state dies with the session; a fresh session cannot destroy past deployments - direct the user to the console instead).
|
|
46
|
+
2. Status is `deployed` or `partial` (`destroyed` is terminal).
|
|
47
|
+
3. The user explicitly names the target deployment. Ambiguous "delete it" → list deployments and ask. Never guess.
|
|
48
|
+
4. Every delete command still goes through plan → approve → run.
|
|
49
|
+
|
|
50
|
+
Execution: show the to-be-deleted list for final confirmation → delete in **reverse creation order** → a "resource not found" error counts as already deleted, continue → mark `destroyed`. OBS: upload paths like `assets/style.css` auto-create folder-marker objects that outlive the files - prefer one recursive sweep `hcloud OBS rm obs://<bucket>/ -r -f` over per-object deletes, then delete the bucket (a non-empty bucket fails with 409 `BucketNotEmpty`). CDN: disable then delete. DNS: delete the record set (only if hosted in Huawei Cloud DNS).
|
|
51
|
+
|
|
52
|
+
## Critical Warnings
|
|
53
|
+
|
|
54
|
+
| Trap | Why / Rule |
|
|
55
|
+
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| Stale `securityToken` poisons every hcloud call | Symptom: every API returns `APIGW.0301 Incorrect IAM authentication information` while OBS/obsutil still works. `configure set` refuses empty values and auth-sync never clears the field. Fix: `hcloud configure delete --cli-profile=default`, then re-run auth init with AK/SK only (no token) |
|
|
57
|
+
| OBS writes bypass the REST write-prefix policy | `mb` / `cp` / `rm` / `chattri` are obsutil-style commands. ALWAYS route them through `huaweicloud_plan_cli_command` → approval → `huaweicloud_run_approved_command`. Never treat them as read-only |
|
|
58
|
+
| `OBS mb` flag rules differ from cp/rm | `mb` does NOT accept `-f` (flag parse error) and REQUIRES explicit `-location=<region>` even with a regional endpoint (else `IllegalLocationConstraintException`) |
|
|
59
|
+
| Duplicate `OBS mb` is idempotent success | Same-account same-name bucket creation returns success, not an error - never treat a second create as failure. OBS deletes are also idempotent (deleting a nonexistent object succeeds) |
|
|
60
|
+
| Bucket ACL does not cascade to objects | Every uploaded object needs `-acl=public-read` at upload time (`-f` IS valid on cp/rm) |
|
|
61
|
+
| OBS static website bucket name must equal the domain | e.g. bucket `www.example.com` for domain `www.example.com` |
|
|
62
|
+
| VPC v3 API differs from older docs | v3 `CreateSecurityGroup` has NO `vpc_id` (account-scoped); `CreateSecurityGroupRule` uses `multiport=80` not `port_range_min/max`; `DeleteSubnet` requires `vpc_id` too. Always `--help` first |
|
|
63
|
+
| Public exposure is auto-blocked | Risk rules deny `0.0.0.0/0` port rules at plan time. For test/dev use a narrower `remote_ip_prefix` (e.g. the VPC CIDR) or get user consent for a documented exception |
|
|
64
|
+
| ECS CreateServers hidden required params | Besides flavor/image/nics/az it also needs `--server.vpcid` and `--server.root_volume.volumetype` - order submission fails without them |
|
|
65
|
+
| FunctionGraph runtime/code enums are strict | runtime must be exact (`Node.js18.15`, `Python3.9`, `Go1.x`, ...); inline code is the PAIR `--package=default --code_type=inline` (`--package=inline` → `FSS.1006`); TIMER triggers use `--event_data.schedule_type=Rate --event_data.schedule=1m` (`@every` style → `FSS.1109`); DeleteFunction takes `--function_urn` WITHOUT `:latest` |
|
|
66
|
+
| Zero balance blocks order submission | ECS creation fails with `Ecs.7000 Insufficient account balance` when cash + voucher accounts are 0. This is the stage-5 gate materialized: stop, mark `partial`, tell the user pay-by-duration resources need a deposit. Free-tier resources (FunctionGraph, small OBS) DO work at 0 balance - the gate applies to order-submission resources only |
|
|
67
|
+
| CDN mainland acceleration requires ICP filing | Unregistered domains cannot go live on CDN - check before stage 3. CDN create ALSO requires domain ownership verification first (`CDN.00010185 Verify domain ownership failed` - user must add a DNS record or upload a verification file) |
|
|
68
|
+
| CDN is a global service in KooCLI | CDN operations only accept `--cli-region=cn-north-1` or `ap-southeast-1` - never the resource region |
|
|
69
|
+
| OBS static website hosting has NO CLI path | `chattri` only sets ACL/storage-class; obsutil has no website command. Options: console setup, or CDN OBS-origin with `--domain.sources.1.enable_obs_web_hosting=1`. Without website hosting, verify via direct object URLs (still public HTTP 200) |
|
|
70
|
+
| DNS hosting location | `hcloud DNS ListPublicZones` decides: hosted in Huawei Cloud → auto-create CNAME record set; hosted elsewhere → output the CNAME value for manual setup at the user's DNS provider |
|
|
71
|
+
| EIP bills when idle; stopped ECS still bills | Include in cost estimate; destroy unattached EIPs |
|
|
72
|
+
| ECS delete defaults leak resources | `--delete_publicip` and `--delete_volume` are false by default - set `true` when tearing down |
|
|
73
|
+
| EIP binding type is non-obvious | `--publicip.associate_instance_type=PORT` (not INSTANCE) |
|
|
74
|
+
| State is session-only | Temp-dir file, dies with the session. Never promise cross-session deploy management |
|
|
75
|
+
| State file must be UTF-8 WITHOUT BOM | PowerShell `Set-Content -Encoding utf8` adds a BOM that breaks JSON parsers - write state with Node or another BOM-less writer |
|
|
76
|
+
| HTTPS needs a certificate | CDN serves plain HTTP by default; SSL cert (upload or SCM) required for HTTPS |
|
|
77
|
+
|
|
78
|
+
## MCP Tools
|
|
79
|
+
|
|
80
|
+
- `huaweicloud_plan_cli_command` → classify and plan each write command
|
|
81
|
+
- `huaweicloud_run_approved_command` → execute after explicit approval (approvedCommand must match the planned command exactly - use the `command` field verbatim, never retype it)
|
|
82
|
+
- `huaweicloud_run_readonly_command` → discovery (flavors, images, zones, prices)
|
|
83
|
+
- `huaweicloud_list_regions` / `huaweicloud_get_regional_availability` → region intent
|
|
84
|
+
- `huaweicloud_hook_check_deploy_plan` → risk-check the plan before approval
|
|
85
|
+
- Balance and pricing: `huawei-billing` skill. Balance operation (BSS is pinned to cn-north-1 in KooCLI): `hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1 --cli-domain-id=<domain_id>`. Global services (BSS/IAM) require `--cli-domain-id` per call or in the profile - if unknown, extract it from any resource response's `tenant_id` field (e.g. a VPC create response), or from the profile's domainId once configured
|
|
86
|
+
|
|
87
|
+
## Cross-Skill References
|
|
88
|
+
|
|
89
|
+
- Per-resource commands: `huawei-vpc` (VPC / subnet / security group / EIP), `huawei-ecs`, `huawei-rds`, `huawei-gaussdb`, `huawei-dds-dcs`, `huawei-cce`, `huawei-obs`, `huawei-functiongraph`, `huawei-apig`, `huawei-smn-dms`, `huawei-cbr`, `huawei-cloud-eye`, `huawei-cts`, `huawei-dew`, `huawei-modelarts`, `huawei-waf-aad`, `huawei-iam`
|
|
90
|
+
- **CDN and DNS have no dedicated skill** - discover operations with `hcloud CDN <Operation> --help` and `hcloud DNS <Operation> --help`
|
|
91
|
+
- Full purchase catalog: `references/resource-catalog.md`
|
|
92
|
+
- Architecture templates by scale: `references/architectures.md`
|
|
93
|
+
- State file spec: `references/state-file.md`
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Architecture Templates by Scale
|
|
2
|
+
|
|
3
|
+
Templates define the resource mix and dependency topology per user scale. Adapt specs to the target region (always verify with `ListFlavors` / `ListImages`), never copy them blindly.
|
|
4
|
+
|
|
5
|
+
## Scale Classification
|
|
6
|
+
|
|
7
|
+
**When the user has not stated their scale** (and signals like "生产环境"/"学习用" are absent), present this table as a choice - the user picks the tier, the template follows:
|
|
8
|
+
|
|
9
|
+
| Scale | Signals | Product mix | Cost signal |
|
|
10
|
+
| -------------- | -------------------------------------------------- | --------------------------------------------------------------------- | ---------------------- |
|
|
11
|
+
| Personal | Side project, low traffic, cost-sensitive | FunctionGraph (free tier) + OBS static hosting, or single minimal ECS | Tens of CNY/month |
|
|
12
|
+
| Small business | Team product, stable traffic, needs SLA-ish uptime | ECS + RDS (single instance) + EIP, frontend OBS+CDN or same ECS | Hundreds of CNY/month |
|
|
13
|
+
| Enterprise | Production, HA, compliance | CCE + GaussDB (primary/standby) + WAF + CDN + OBS logs | Thousands of CNY/month |
|
|
14
|
+
|
|
15
|
+
## Template: Personal - OBS+CDN frontend / FunctionGraph backend (lightest)
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
OBS public bucket -> CDN acceleration -> DNS CNAME -> user domain
|
|
19
|
+
(Vue/React build output)
|
|
20
|
+
FunctionGraph (Node.js/Python)
|
|
21
|
+
(Express/FastAPI backend logic)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- FunctionGraph has a free tier; personal projects are often near-free
|
|
25
|
+
- Persistent data needs a real database (DDS single node in free tier, or minimal RDS). FG filesystem is ephemeral - SQLite data is lost between invocations
|
|
26
|
+
|
|
27
|
+
## Template: Personal - ECS+EIP frontend / FunctionGraph backend
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
VPC -> Subnet -> ECS(1C1G) -> EIP
|
|
31
|
+
(Nginx serves static files)
|
|
32
|
+
FunctionGraph (backend API)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Template: Small business - OBS+CDN frontend / ECS+RDS backend
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
OBS public bucket -> CDN -> DNS -> user domain
|
|
39
|
+
|
|
40
|
+
VPC -> Subnet -> SG -> ECS(2C4G) -> EIP
|
|
41
|
+
└─ RDS (MySQL single instance)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Template: Small business - all on ECS
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
VPC -> Subnet -> SG -> ECS(2C4G) -> EIP
|
|
48
|
+
├─ Nginx (frontend static)
|
|
49
|
+
├─ Node.js (backend)
|
|
50
|
+
└─ RDS (MySQL single instance)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Fewest resources; no CDN, no HTTPS by default. Good for quick validation or intranet scenarios.
|
|
54
|
+
|
|
55
|
+
## Template: Enterprise
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
OBS public bucket -> CDN -> WAF -> DNS -> user domain
|
|
59
|
+
|
|
60
|
+
VPC -> Subnet -> SG
|
|
61
|
+
├─ CCE (3 nodes) -> ELB -> EIP
|
|
62
|
+
├─ GaussDB (primary/standby)
|
|
63
|
+
└─ OBS (logs)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Dependency Ordering Rules
|
|
67
|
+
|
|
68
|
+
Creation must follow topological order; destroy is the exact reverse:
|
|
69
|
+
|
|
70
|
+
1. Network foundation first: VPC → Subnet → Security Group (+ rules)
|
|
71
|
+
2. Compute / database next: ECS, RDS, CCE, FunctionGraph
|
|
72
|
+
3. Bindings and exposure last: EIP bind, CDN domain, DNS record set
|
|
73
|
+
4. Shared foundations (VPC/Subnet) are referenced by many resources - deleting them first always fails with "resource in use"
|
|
74
|
+
|
|
75
|
+
## Frontend Hosting Decision Matrix
|
|
76
|
+
|
|
77
|
+
| Aspect | OBS+CDN+DNS | ECS+EIP |
|
|
78
|
+
| -------------------- | --------------------------------------- | ------------------------------------- |
|
|
79
|
+
| Prerequisite | Registered + ICP-filed domain | None (IP access) |
|
|
80
|
+
| Ops | Zero server ops | Full server management |
|
|
81
|
+
| Backend on same host | No (static only) | Yes (SSR / API / Nginx) |
|
|
82
|
+
| Traffic cost | Pay per GB, cheap at scale | Fixed bandwidth billing |
|
|
83
|
+
| Best for | Static sites, SPAs, docs, landing pages | SSR frontends, all-in-one deployments |
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Resource Purchase Catalog
|
|
2
|
+
|
|
3
|
+
Every resource type the orchestration flow can purchase, bind, and destroy. This is the authoritative checklist when composing a deployment plan.
|
|
4
|
+
|
|
5
|
+
> **Operation names below are entry points, not gospel.** Always confirm exact parameters with `hcloud <Service> <Operation> --help` before planning a command. When an operation name is uncertain, run `hcloud <Service> --help` first.
|
|
6
|
+
|
|
7
|
+
## Networking (foundation - create first, destroy last)
|
|
8
|
+
|
|
9
|
+
> **v3 API notes (verified by E2E)**: `CreateSecurityGroup` is account-scoped - NO `vpc_id` param. `CreateSecurityGroupRule` uses `multiport=80` (not `port_range_min/max`). `DeleteSubnet` requires `--vpc_id` in addition to `--subnet_id`. Deletion APIs return empty output on success (async 202/204) - confirm via list, not stdout.
|
|
10
|
+
|
|
11
|
+
| Resource | Create | Delete | Skill | Depends on |
|
|
12
|
+
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| VPC | `hcloud VPC CreateVpc --vpc.name=<n> --vpc.cidr=<cidr>` | `hcloud VPC DeleteVpc --vpc_id=<id>` | huawei-vpc | - |
|
|
14
|
+
| Subnet | `hcloud VPC CreateSubnet --subnet.name=<n> --subnet.cidr=<cidr> --subnet.gateway_ip=<gw> --subnet.vpc_id=<id>` | `hcloud VPC DeleteSubnet --subnet_id=<id> --vpc_id=<id>` | huawei-vpc | VPC |
|
|
15
|
+
| Security group | `hcloud VPC CreateSecurityGroup --security_group.name=<n>` (v3: account-scoped, no vpc_id) | `hcloud VPC DeleteSecurityGroup --security_group_id=<id>` | huawei-vpc | - |
|
|
16
|
+
| Security group rules | `hcloud VPC CreateSecurityGroupRule --security_group_rule.security_group_id=<id> --security_group_rule.direction=ingress --security_group_rule.protocol=tcp --security_group_rule.multiport=80 --security_group_rule.remote_ip_prefix=<cidr>` | `hcloud VPC DeleteSecurityGroupRule --security_group_rule_id=<id>` | huawei-vpc | Security group. New SGs deny ALL inbound - rules are mandatory. Risk rules block `0.0.0.0/0` exposure - use the VPC CIDR for internal rules |
|
|
17
|
+
| EIP | `hcloud EIP CreatePublicip` | `hcloud EIP DeletePublicip` | huawei-vpc | - (bills when idle) |
|
|
18
|
+
| EIP bind | `hcloud EIP AssociatePublicips --publicip.associate_instance_type=PORT` | `hcloud EIP DisassociatePublicips` | huawei-vpc | EIP + target port |
|
|
19
|
+
|
|
20
|
+
## Compute
|
|
21
|
+
|
|
22
|
+
| Resource | Create | Delete | Skill | Depends on |
|
|
23
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ---------- | -------------------------------------------------------------------------- |
|
|
24
|
+
| ECS instance | `hcloud ECS CreateServers --server.name=<n> --server.flavorRef=<id> --server.imageRef=<id> --server.vpcid=<id> --server.nics.1.subnet_id=<id> --server.security_groups.1.id=<id> --server.availability_zone=<az> --server.root_volume.volumetype=<type>` (hidden required: `vpcid` + `root_volume.volumetype`; check flavor family vs image arch, e.g. kc1 = ARM needs an ARM image) | `hcloud ECS DeleteServers --servers.1.id=<id> --delete_publicip=true --delete_volume=true` | huawei-ecs | VPC + Subnet + SG. Set both delete flags true on teardown or EIP/disk leak |
|
|
25
|
+
| EVS data disk | `hcloud EVS CreateVolume` | `hcloud EVS DeleteVolume` | huawei-ecs | - (attach with `hcloud EVS AttachVolume`) |
|
|
26
|
+
|
|
27
|
+
## Databases
|
|
28
|
+
|
|
29
|
+
| Resource | Create | Delete | Skill | Depends on |
|
|
30
|
+
| --------------------------- | --------------------------------------------------------- | ------------------------------------------------------- | -------------- | ------------ |
|
|
31
|
+
| RDS (MySQL/PG/SQLServer) | discover with `hcloud RDS --help` (CreateInstance family) | discover with `hcloud RDS --help` | huawei-rds | VPC + Subnet |
|
|
32
|
+
| GaussDB | discover with `hcloud GaussDB --help` | discover with `hcloud GaussDB --help` | huawei-gaussdb | VPC + Subnet |
|
|
33
|
+
| DDS (MongoDB) / DCS (Redis) | discover with `hcloud DDS --help` / `hcloud DCS --help` | discover with `hcloud DDS --help` / `hcloud DCS --help` | huawei-dds-dcs | VPC + Subnet |
|
|
34
|
+
|
|
35
|
+
## Storage / Delivery
|
|
36
|
+
|
|
37
|
+
| Resource | Create | Delete | Skill | Depends on |
|
|
38
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------- |
|
|
39
|
+
| OBS bucket | `hcloud OBS mb obs://<bucket> -location=<region>` (NO `-f`; `-location` is mandatory even with a regional endpoint; same-name re-create is idempotent success) | `hcloud OBS rm obs://<bucket> -f` (empty objects first; idempotent) | huawei-obs | - |
|
|
40
|
+
| Upload objects | `hcloud OBS cp <src> obs://<bucket>/ -f -acl=public-read` | - | huawei-obs | Bucket. Per-object ACL mandatory - bucket ACL does not cascade |
|
|
41
|
+
| Static website hosting | NO CLI path - `chattri` only sets ACL/storage-class and obsutil has no website command. Use the console, or enable via CDN OBS-origin (`--domain.sources.1.enable_obs_web_hosting=1`) | - | huawei-obs | Bucket. Bucket name must equal the custom domain for CDN custom-domain access |
|
|
42
|
+
| CDN acceleration domain | `hcloud CDN CreateDomain --domain.business_type=web --domain.domain_name=<domain> --domain.sources.1.origin_type=obs_bucket --domain.sources.1.ip_or_domain=<bucket-website-endpoint> --domain.sources.1.active_standby=1 --cli-region=cn-north-1` (CDN is a GLOBAL service: region must be cn-north-1 or ap-southeast-1; first create attempt fails with `CDN.00010185` until the user passes domain ownership verification via DNS record or file upload; `--domain.sources.1.enable_obs_web_hosting=1` enables OBS website hosting on the origin) | disable then delete | - (no skill) | OBS source or ECS origin. Mainland acceleration requires ICP filing |
|
|
43
|
+
| DNS record set | discover with `hcloud DNS --help` (CreateRecordSet family) | discover with `hcloud DNS --help` | - (no skill) | CDN CNAME + domain hosted in Huawei Cloud DNS (check `hcloud DNS ListPublicZones`) |
|
|
44
|
+
|
|
45
|
+
## Serverless / API
|
|
46
|
+
|
|
47
|
+
| Resource | Create | Delete | Skill | Depends on |
|
|
48
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------------- |
|
|
49
|
+
| FunctionGraph function | `hcloud FunctionGraph CreateFunction --func_name=<n> --runtime=Node.js18.15 --handler=index.handler --memory_size=128 --timeout=3 --package=default --code_type=inline --func_code.file=<base64>` (runtime enum is exact: `Node.js18.15`, `Python3.9`, `Go1.x`, ...; `--package=inline` fails with `FSS.1006` - the pair is `--package=default --code_type=inline`) | `hcloud FunctionGraph DeleteFunction --function_urn=<urn-without-:latest>` (urn must omit version/alias to delete the whole function; param is `--function_urn`, NOT `--func_urn`) | huawei-functiongraph | - |
|
|
50
|
+
| FunctionGraph trigger | `hcloud FunctionGraph CreateFunctionTrigger --function_urn=<urn> --trigger_type_code=TIMER --trigger_status=ACTIVE --event_data.name=<n> --event_data.schedule_type=Rate --event_data.schedule=1m` (timer uses `schedule_type=Rate` + bare `1m`; `schedule=@every 1h` fails with `FSS.1109`) | `hcloud FunctionGraph DeleteFunctionTrigger --function_urn=<urn> --trigger_type_code=TIMER --trigger_id=<id>` | huawei-functiongraph | Function. Use DEDICATEDGATEWAY (not deprecated APIG type) |
|
|
51
|
+
| APIG instance | `hcloud APIG CreateInstanceV2 --spec_id=<id>` | discover with `hcloud APIG --help` | huawei-apig | - |
|
|
52
|
+
|
|
53
|
+
## Container
|
|
54
|
+
|
|
55
|
+
| Resource | Create | Delete | Skill | Depends on |
|
|
56
|
+
| ----------------------- | --------------------------------- | --------------------------------- | ---------- | ------------------------------------------------ |
|
|
57
|
+
| CCE cluster + node pool | discover with `hcloud CCE --help` | discover with `hcloud CCE --help` | huawei-cce | VPC + Subnet. Long creation time - warn the user |
|
|
58
|
+
|
|
59
|
+
## Messaging / Backup / Observability / Security
|
|
60
|
+
|
|
61
|
+
| Resource | Create | Delete | Skill |
|
|
62
|
+
| ----------------------------- | ------------------------------------------------------- | --------------------------------- | ---------------- |
|
|
63
|
+
| SMN topic / subscription | discover with `hcloud SMN --help` | discover with `hcloud SMN --help` | huawei-smn-dms |
|
|
64
|
+
| DMS queue (Kafka/RocketMQ) | discover with `hcloud DMS --help` | discover with `hcloud DMS --help` | huawei-smn-dms |
|
|
65
|
+
| CBR vault / policy | discover with `hcloud CBR --help` | discover with `hcloud CBR --help` | huawei-cbr |
|
|
66
|
+
| CES alarm rule | discover with `hcloud CES --help` | discover with `hcloud CES --help` | huawei-cloud-eye |
|
|
67
|
+
| CTS tracker | discover with `hcloud CTS --help` | discover with `hcloud CTS --help` | huawei-cts |
|
|
68
|
+
| DEW secret / KMS key | discover with `hcloud DEW --help` / `hcloud KMS --help` | discover with `hcloud DEW --help` | huawei-dew |
|
|
69
|
+
| WAF policy | discover with `hcloud WAF --help` | discover with `hcloud WAF --help` | huawei-waf-aad |
|
|
70
|
+
| IAM users / groups / agencies | discover with `hcloud IAM --help` | discover with `hcloud IAM --help` | huawei-iam |
|
|
71
|
+
|
|
72
|
+
## Pricing and Balance
|
|
73
|
+
|
|
74
|
+
### On-demand price inquiry (verified template)
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
hcloud BSS ListOnDemandResourceRatings --project_id=<pid> \
|
|
78
|
+
--product_infos.1.id=<label> \
|
|
79
|
+
--product_infos.1.cloud_service_type=hws.service.type.ec2 \
|
|
80
|
+
--product_infos.1.resource_type=hws.resource.type.vm \
|
|
81
|
+
--product_infos.1.region=<resource-region> \
|
|
82
|
+
--product_infos.1.resource_spec=kc1.small.1.linux \
|
|
83
|
+
--product_infos.1.subscription_num=1 \
|
|
84
|
+
--product_infos.1.usage_factor=Duration \
|
|
85
|
+
--product_infos.1.usage_measure_id=4 \
|
|
86
|
+
--product_infos.1.usage_value=730 \
|
|
87
|
+
--cli-region=cn-north-1 --cli-domain-id=<domain_id>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- `usage_measure_id=4` = hour; `usage_value=730` = one month. Response: `amount` (CNY) per product label
|
|
91
|
+
- **ECS codes verified**: service `hws.service.type.ec2`, resource `hws.resource.type.vm`, spec = `<flavor>.linux` (or `.win`); monthly price for kc1.small.1 = 87.60 CNY (official, cn-north-4)
|
|
92
|
+
- **Other services**: codes are per-service and MUST be looked up via BSS metadata APIs (`ListServiceTypes` / `ListResourceTypes` / `ListUsageTypes`) or docs - a wrong combination fails with `CBC.6074 billing item does not exist`. Never guess
|
|
93
|
+
- EIP example shape (unverified codes): service `hws.service.type.vpc`, spec `19_bgp` (per-bandwidth) + `resource_size=5` + `size_measure_id=15` (Mbps)
|
|
94
|
+
|
|
95
|
+
- Account balance: `hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1 --cli-domain-id=<domain_id>`
|
|
96
|
+
- Global services (BSS/IAM/CDN) demand `--cli-domain-id` per call (or in the profile) under AK/SK auth
|
|
97
|
+
- If the domain_id is unknown: extract it from ANY resource response's `tenant_id` field (e.g. a VPC create response) or from the console (My Credentials page)
|
|
98
|
+
- Response shape: `account_balances[].amount` (cash account type=1, voucher account type=5), `debt_amount`, `currency`
|
|
99
|
+
- Cost gate rule: no deployment without a per-resource cost estimate AND a balance check. Verified failure mode when skipped: ECS creation dies with `Ecs.7000 Insufficient account balance` at order submission
|
|
100
|
+
|
|
101
|
+
## Auth Bootstrapping (prerequisite for every command above)
|
|
102
|
+
|
|
103
|
+
- Symptom of a broken profile: every hcloud API returns `APIGW.0301 Incorrect IAM authentication information` while OBS/obsutil keeps working - caused by a stale `securityToken` in the profile
|
|
104
|
+
- Fix: `hcloud configure delete --cli-profile=default`, then re-run `npx huaweicloud-devkit auth init` with permanent AK/SK only (no token). `configure set` refuses empty values, so the token cannot be cleared in place
|
|
105
|
+
- project_id is auto-discovered once signing works - no need to configure it manually
|
|
106
|
+
- VPC/OBS create responses expose `tenant_id` (= domain_id) - the reliable fallback source when BSS/IAM discovery is blocked
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Deployment State File Specification
|
|
2
|
+
|
|
3
|
+
Session-scoped tracking for the orchestration flow. This is a manual, session-scoped analog of Terraform state - lightweight by design, not a long-term deployment ledger.
|
|
4
|
+
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
System temp directory (session dies with the file):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Linux/macOS: /tmp/huaweicloud-iac-state.json
|
|
11
|
+
Windows: %TEMP%\huaweicloud-iac-state.json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Lifecycle
|
|
15
|
+
|
|
16
|
+
- Created at the start of Stage 6 (provisioning) with the first `deploying` deployment
|
|
17
|
+
- Updated after EVERY successful resource creation (never batch-write at the end)
|
|
18
|
+
- Marked `partial` immediately on any failure
|
|
19
|
+
- Marked `destroyed` after a successful teardown
|
|
20
|
+
- Expires with the session - never promise cross-session deploy management
|
|
21
|
+
|
|
22
|
+
## Schema
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"version": "1.0",
|
|
27
|
+
"deployments": {
|
|
28
|
+
"d-002": {
|
|
29
|
+
"created_at": "2026-09-05T14:00:00Z",
|
|
30
|
+
"arch": "personal-serverless",
|
|
31
|
+
"region": "cn-east-3",
|
|
32
|
+
"frontend": "obs-cdn",
|
|
33
|
+
"domain": "www.example.com",
|
|
34
|
+
"resources": [
|
|
35
|
+
{
|
|
36
|
+
"id": "obs_bucket",
|
|
37
|
+
"type": "OBS_Bucket",
|
|
38
|
+
"resource_id": "www.example.com",
|
|
39
|
+
"params": { "acl": "public-read", "website": true }
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "cdn",
|
|
43
|
+
"type": "CDN_Domain",
|
|
44
|
+
"resource_id": "cdn-xxx",
|
|
45
|
+
"params": { "cname": "xxx.cdn.myhuaweicloud.com" },
|
|
46
|
+
"depends_on": ["obs_bucket"]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "dns",
|
|
50
|
+
"type": "DNS_RecordSet",
|
|
51
|
+
"resource_id": "rs-xxx",
|
|
52
|
+
"params": { "type": "CNAME", "value": "xxx.cdn.myhuaweicloud.com" },
|
|
53
|
+
"depends_on": ["cdn"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "fg",
|
|
57
|
+
"type": "FunctionGraph",
|
|
58
|
+
"resource_id": "urn:fss:xxx",
|
|
59
|
+
"params": { "runtime": "Node.js" }
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"status": "deployed"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Field rules:
|
|
69
|
+
|
|
70
|
+
- `id`: stable resource role within the deployment (`vpc`, `subnet`, `sg`, `ecs`, `eip`, `rds`, `obs_bucket`, `cdn`, `dns`, `fg`, ...) - later resources reference these names in `depends_on`
|
|
71
|
+
- `resource_id`: the real cloud ID extracted from the creation command output - never reconstructed from memory
|
|
72
|
+
- `depends_on`: array of `id`s this resource was created after; determines reverse destroy order
|
|
73
|
+
- `params`: only what teardown or diagnostics needs (name, flags like ACL) - no secrets
|
|
74
|
+
|
|
75
|
+
## Status Machine
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
deploying ──all created + verified──▶ deployed
|
|
79
|
+
│
|
|
80
|
+
└──any failure──▶ partial (keep created-resource records; destroy to clean up)
|
|
81
|
+
|
|
82
|
+
deployed/partial ──destroy──▶ destroyed (terminal; queries only)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
| Status | Meaning | Allowed operations |
|
|
86
|
+
| ----------- | ----------------------------------- | -------------------------------- |
|
|
87
|
+
| `deploying` | Provisioning in progress | Wait / observe |
|
|
88
|
+
| `deployed` | All resources created and verified | Query, destroy |
|
|
89
|
+
| `partial` | Interrupted; orphan resources exist | **Destroy (clean up leftovers)** |
|
|
90
|
+
| `destroyed` | Torn down | Query only |
|
|
91
|
+
|
|
92
|
+
## Write Rules
|
|
93
|
+
|
|
94
|
+
1. Write state after every single successful create - extract `resource_id` from the actual command output
|
|
95
|
+
2. `resource_id` extraction is deterministic: parse the JSON the command returned; if the output shape is unexpected, stop and inspect instead of guessing
|
|
96
|
+
3. A failed create is recorded only via the `partial` status - do not fabricate IDs for failed resources
|
|
97
|
+
4. Destroy order = exact reverse of the recorded `resources` array order (creation order is already topological)
|
|
98
|
+
5. "Resource not found" during destroy = already gone; keep going and still record it as processed
|
|
99
|
+
6. **UTF-8 WITHOUT BOM**: PowerShell 5.1 `Set-Content -Encoding utf8` writes a BOM that makes strict JSON parsers fail (`Unexpected token ''`). Write state with Node `fs.writeFileSync` or another BOM-less writer; if parsing fails on a `\uFEFF` prefix, strip it and rewrite the file clean
|
|
100
|
+
7. Empty command stdout is a valid success signal for VPC v3 deletes (async 202/204) - confirm teardown via list APIs, not stdout
|
|
101
|
+
|
|
102
|
+
## Known Weakness
|
|
103
|
+
|
|
104
|
+
State correctness rests entirely on the agent writing each `resource_id` right after creation. A wrong or missing ID causes leaks (missed deletes) or wrong deletes at teardown. Mitigations: write immediately after each step, parse output programmatically, show the full to-be-deleted list for final confirmation before destroying.
|
|
@@ -11,7 +11,7 @@ version: 1
|
|
|
11
11
|
## Routing Guard: Deploy vs Store
|
|
12
12
|
|
|
13
13
|
- If the developer's goal is to **deploy, host, or preview a web app / static website** (temporary hosting, quick preview), do NOT default to OBS. Present deployment-target options with the sandbox first: ① huawei-sandbox (recommended), ② OBS static hosting, ③ ECS, ④ CCE. Ask: "建议优先部署到沙箱(临时运行环境,可预览访问),也可选 OBS 静态托管/ECS/CCE,你想部署到哪里?"
|
|
14
|
-
- Proceed with OBS only when the developer selects OBS, explicitly asks for OBS, or the intent is long-term static hosting / CDN / file storage.
|
|
14
|
+
- Proceed with OBS only when the developer selects OBS, explicitly asks for OBS, or the intent is long-term static hosting / CDN / file storage. **Deployment intent proceeding on OBS is a resource purchase: load `huawei-iac` for orchestration (cost+balance gate, batch approval, state tracking, ordered destroy) - this skill then supplies the bucket/object commands.** Sandbox choice (huawei-sandbox) bypasses iac - no purchase involved.
|
|
15
15
|
- OBS is a storage service; it is not a general web-hosting default.
|
|
16
16
|
|
|
17
17
|
## Critical: OBS Command Syntax
|
|
@@ -10,6 +10,10 @@ version: 1
|
|
|
10
10
|
|
|
11
11
|
Always run `hcloud RDS <Operation> --help` before constructing commands to discover exact parameter names and requirements.
|
|
12
12
|
|
|
13
|
+
## Deployment Routing Guard
|
|
14
|
+
|
|
15
|
+
If this skill was reached via a DEPLOYMENT intent (the database is part of an application deployment, not a standalone ad-hoc operation), this is a cloud resource purchase: load `huawei-iac` first for orchestration (mandatory cost+balance gate, batch approval, session state, ordered destroy), then return here for the exact instance commands. Sandbox-deployed workloads (huawei-sandbox) bypass iac - no purchase involved.
|
|
16
|
+
|
|
13
17
|
## Prerequisites
|
|
14
18
|
|
|
15
19
|
Before creating an RDS instance, you MUST have:
|
|
@@ -22,28 +22,29 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
22
22
|
|
|
23
23
|
## Sub-skill Registry
|
|
24
24
|
|
|
25
|
-
| ID | Name | Trigger Phrases
|
|
26
|
-
| ------------- | ----------------------- |
|
|
27
|
-
| select | Service Selection | which service, what should I use, compare, recommend
|
|
28
|
-
| compute | Compute Routing | server, VM, instance, ECS, BMS, GPU, HPC
|
|
29
|
-
| storage | Storage Routing | store files, bucket, OBS, backup, disk, EVS, SFS (long-term storage/CDN intent only)
|
|
30
|
-
| database | Database Routing | database, SQL, NoSQL, cache, RDS, GaussDB, DDS, DCS
|
|
31
|
-
| network | Network Routing | VPC, subnet, security group, EIP, NAT, VPN
|
|
32
|
-
| serverless | Serverless Routing | function, Lambda, serverless, FunctionGraph, API gateway
|
|
33
|
-
| ai | AI/ML Routing | AI, model, LLM, Pangu, training, inference, RAG
|
|
34
|
-
| messaging | Messaging Routing | message queue, notification, Kafka, RabbitMQ, event, SMN
|
|
35
|
-
| security | Security Routing | secret, credential, encrypt, KMS, WAF, firewall, DDoS
|
|
36
|
-
| observability | Observability Routing | monitor, alarm, log, audit, trace, Cloud Eye
|
|
37
|
-
| billing | Billing Routing | cost, bill, budget, spending, invoice
|
|
38
|
-
| iam | IAM Routing | permission, policy, role, user, group, AK/SK
|
|
39
|
-
| deployment | Deployment Routing | deploy, host, publish, CI/CD, pipeline, release
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
25
|
+
| ID | Name | Trigger Phrases | Next Steps |
|
|
26
|
+
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
27
|
+
| select | Service Selection | which service, what should I use, compare, recommend | Read references/select.md | select |
|
|
28
|
+
| compute | Compute Routing | server, VM, instance, ECS, BMS, GPU, HPC | Handoff to huawei-ecs or huawei-cce |
|
|
29
|
+
| storage | Storage Routing | store files, bucket, OBS, backup, disk, EVS, SFS (long-term storage/CDN intent only) | Handoff to huawei-obs or huawei-cbr |
|
|
30
|
+
| database | Database Routing | database, SQL, NoSQL, cache, RDS, GaussDB, DDS, DCS | Handoff to huawei-rds or huawei-gaussdb |
|
|
31
|
+
| network | Network Routing | VPC, subnet, security group, EIP, NAT, VPN | Handoff to huawei-vpc |
|
|
32
|
+
| serverless | Serverless Routing | function, Lambda, serverless, FunctionGraph, API gateway | Handoff to huawei-functiongraph or huawei-apig |
|
|
33
|
+
| ai | AI/ML Routing | AI, model, LLM, Pangu, training, inference, RAG | Handoff to huawei-modelarts |
|
|
34
|
+
| messaging | Messaging Routing | message queue, notification, Kafka, RabbitMQ, event, SMN | Handoff to huawei-smn-dms |
|
|
35
|
+
| security | Security Routing | secret, credential, encrypt, KMS, WAF, firewall, DDoS | Handoff to huawei-dew or huawei-waf-aad |
|
|
36
|
+
| observability | Observability Routing | monitor, alarm, log, audit, trace, Cloud Eye | Handoff to huawei-cloud-eye or huawei-cts |
|
|
37
|
+
| billing | Billing Routing | cost, bill, budget, spending, invoice | Handoff to huawei-billing |
|
|
38
|
+
| iam | IAM Routing | permission, policy, role, user, group, AK/SK | Handoff to huawei-iam |
|
|
39
|
+
| deployment | Deployment Routing | deploy, host, publish, CI/CD, pipeline, release | CI/CD pipeline -> huawei-deployment; deploy/host/preview a web app or static website (no CI/CD target) -> present deployment-target options first, see "Deployment Target Options" below |
|
|
40
|
+
| iac | IaC Orchestration | 部署方案, 资源编排, 购买资源, 搭建环境, 部署一套, 成本估算, 销毁部署, provision resources, architecture proposal, multi-resource deployment | Handoff to huawei-iac - multi-resource purchase orchestration with cost gating and ordered destroy. Single web app preview still goes to huawei-sandbox first |
|
|
41
|
+
| sandbox | Sandbox Routing | sandbox, DevStation, workspace, terminal, preview, temporary runtime | Handoff to huawei-sandbox |
|
|
42
|
+
| cli | CLI and Auth Routing | install hcloud, configure KooCLI, AK/SK setup | Handoff to huaweicloud-cli-and-auth |
|
|
43
|
+
| safety | Safety Routing | is this safe, approve command, risk review | Handoff to huaweicloud-safety |
|
|
44
|
+
| troubleshoot | Troubleshooting Routing | error, bug, failed, AccessDenied, quota | Handoff to huaweicloud-troubleshooting |
|
|
45
|
+
| api-sdk | API/SDK Routing | API call, SDK, REST, integration, code example | Handoff to huaweicloud-api-and-sdk |
|
|
46
|
+
| report-issue | Issue Reporting | wrong service, you picked wrong, incorrect | Read references/report-issue.md |
|
|
47
|
+
| voucher | Voucher Routing | 领券, 代金券, 优惠券, 激励金, 领取, voucher, coupon, incentive | Handoff to huawei-voucher |
|
|
47
48
|
|
|
48
49
|
## Service Map
|
|
49
50
|
|
|
@@ -73,7 +74,7 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
73
74
|
| Getting started | Account setup | huaweicloud-cli-and-auth |
|
|
74
75
|
| Incentive voucher | Voucher | huawei-voucher |
|
|
75
76
|
|
|
76
|
-
**Web app scenario layering**: for "deploy a web app", prefer `huawei-sandbox` for free/quick try (hello world, prototype, demo, temporary preview — temporary runtime + public URL, ~8h validity, zero billed resources); route to `huawei-functiongraph` / `huawei-ecs` (or `huawei-cce`) for production / long-term / custom-domain / high-availability hosting.
|
|
77
|
+
**Web app scenario layering**: for "deploy a web app", prefer `huawei-sandbox` for free/quick try (hello world, prototype, demo, temporary preview — temporary runtime + public URL, ~8h validity, zero billed resources); route to `huawei-functiongraph` / `huawei-ecs` (or `huawei-cce`) for production / long-term / custom-domain / high-availability hosting. When the chosen target requires **multiple purchased resources** (e.g. VPC + subnet + ECS + EIP + RDS, or OBS + CDN + DNS) or the user asks for an architecture/cost proposal first, hand off to `huawei-iac` for orchestrated provisioning with a mandatory cost gate.
|
|
77
78
|
|
|
78
79
|
## Deployment Target Options
|
|
79
80
|
|
|
@@ -87,7 +88,7 @@ When the intent is to **deploy, host, or preview a web app or static website** (
|
|
|
87
88
|
| 4 | CCE | Containerized workloads, scaling | huawei-cce |
|
|
88
89
|
|
|
89
90
|
- Recommended prompt: "这个项目是 Web 应用/静态网站,建议优先部署到沙箱(临时运行环境,立即可预览)。也可选择 OBS 静态托管、ECS 或 CCE,你想部署到哪里?"
|
|
90
|
-
- If the developer explicitly names a target (e.g. "deploy to OBS"),
|
|
91
|
+
- If the developer explicitly names a target (e.g. "deploy to OBS"), the SANDBOX target hands off directly to `huawei-sandbox`; every other target (OBS / ECS / CCE / FunctionGraph / ...) hands off to `huawei-iac` for orchestration - iac loads the corresponding service skill for commands and adds the mandatory cost+balance gate, batch approval, state tracking, and ordered destroy. Direct handoff to the bare service skill skips these safety stages and must not happen for deployment intent. **Existing network resources (a reusable VPC) do NOT downgrade this to a single-service task - the purchase itself (compute, EIP, disk, rules) is what triggers iac.**
|
|
91
92
|
- If the developer has no preference, recommend the sandbox first.
|
|
92
93
|
|
|
93
94
|
## Capability Sources
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { existsSync, readdirSync, rmSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
|
|
5
|
+
import { obsConfigPath } from '../auth/credentials.mjs';
|
|
6
|
+
|
|
7
|
+
// Remove the KooCLI (hcloud) binary and its config directory. Only touches the
|
|
8
|
+
// default install locations; a user-managed binary behind HCLOUD_BIN or a
|
|
9
|
+
// Windows PATH entry is left alone. Returns the list of removed paths.
|
|
10
|
+
export function removeKooCli(home = homedir()) {
|
|
11
|
+
const removed = [];
|
|
12
|
+
|
|
13
|
+
for (const bin of [
|
|
14
|
+
join(home, '.local', 'bin', 'hcloud'),
|
|
15
|
+
join(home, 'hcloud', 'hcloud'),
|
|
16
|
+
join(home, 'hcloud', 'hcloud.exe'),
|
|
17
|
+
]) {
|
|
18
|
+
if (existsSync(bin)) {
|
|
19
|
+
rmSync(bin, { force: true });
|
|
20
|
+
removed.push(bin);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const configDir = join(home, '.hcloud');
|
|
25
|
+
if (existsSync(configDir)) {
|
|
26
|
+
rmSync(configDir, { recursive: true, force: true });
|
|
27
|
+
removed.push(configDir);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const installDir = join(home, 'hcloud');
|
|
31
|
+
try {
|
|
32
|
+
if (existsSync(installDir) && readdirSync(installDir).length === 0) {
|
|
33
|
+
rmSync(installDir, { recursive: true, force: true });
|
|
34
|
+
removed.push(installDir);
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
// Non-fatal: an empty-dir cleanup is best-effort.
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return removed;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Remove the OBS credential config (~/.obsutilconfig). Returns the removed
|
|
44
|
+
// path, or an empty array when the file did not exist.
|
|
45
|
+
export function removeObsConfig() {
|
|
46
|
+
const p = obsConfigPath();
|
|
47
|
+
if (!existsSync(p)) return [];
|
|
48
|
+
rmSync(p, { force: true });
|
|
49
|
+
return [p];
|
|
50
|
+
}
|
|
@@ -14,6 +14,7 @@ import { homedir, platform } from 'node:os';
|
|
|
14
14
|
import { createInterface } from 'node:readline';
|
|
15
15
|
import { spawnSync } from 'node:child_process';
|
|
16
16
|
import { randomUUID } from 'node:crypto';
|
|
17
|
+
import { createRequire } from 'node:module';
|
|
17
18
|
|
|
18
19
|
import { getAuthStatus, syncAuth } from './auth/service.mjs';
|
|
19
20
|
import { SUPPORTED_AGENT_TARGETS } from './auth/agent-registration.mjs';
|
|
@@ -30,8 +31,8 @@ import {
|
|
|
30
31
|
clearProxyConfig,
|
|
31
32
|
getProxySettings,
|
|
32
33
|
} from './proxy/proxy-config.mjs';
|
|
34
|
+
import { removeKooCli, removeObsConfig } from './sandbox/uninstall-cleanup.mjs';
|
|
33
35
|
|
|
34
|
-
import { createRequire } from 'node:module';
|
|
35
36
|
const { DatabaseSync } = createRequire(import.meta.url)('node:sqlite');
|
|
36
37
|
|
|
37
38
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -444,6 +445,38 @@ function checkNode() {
|
|
|
444
445
|
console.log(` Node.js ${process.version} \x1b[32mOK\x1b[0m`);
|
|
445
446
|
}
|
|
446
447
|
|
|
448
|
+
function sleepSync(ms) {
|
|
449
|
+
try {
|
|
450
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
451
|
+
} catch {
|
|
452
|
+
// main-thread restriction or unavailable Atomics - fall back to a busy wait
|
|
453
|
+
const end = Date.now() + ms;
|
|
454
|
+
while (Date.now() < end) {
|
|
455
|
+
// spin
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function copyFileVerified(src, dest) {
|
|
461
|
+
const expected = statSync(src).size;
|
|
462
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
463
|
+
copyFileSync(src, dest);
|
|
464
|
+
let actual = -1;
|
|
465
|
+
try {
|
|
466
|
+
actual = statSync(dest).size;
|
|
467
|
+
} catch {
|
|
468
|
+
// destination missing - fall through to retry
|
|
469
|
+
}
|
|
470
|
+
if (actual === expected) return;
|
|
471
|
+
if (attempt < 3) sleepSync(150);
|
|
472
|
+
}
|
|
473
|
+
throw new Error(
|
|
474
|
+
`copyDir verification failed after 3 attempts: ${src} -> ${dest} (expected ${expected} bytes). ` +
|
|
475
|
+
`The destination file may be locked by another process (e.g. a running agent session using the installed MCP server). ` +
|
|
476
|
+
`Close it and re-run the install.`,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
447
480
|
function copyDir(src, dest) {
|
|
448
481
|
if (!existsSync(src)) return;
|
|
449
482
|
mkdirSync(dest, { recursive: true });
|
|
@@ -453,7 +486,7 @@ function copyDir(src, dest) {
|
|
|
453
486
|
if (entry.isDirectory()) {
|
|
454
487
|
copyDir(s, d);
|
|
455
488
|
} else {
|
|
456
|
-
|
|
489
|
+
copyFileVerified(s, d);
|
|
457
490
|
}
|
|
458
491
|
}
|
|
459
492
|
}
|
|
@@ -2967,8 +3000,63 @@ async function cmdUninstall() {
|
|
|
2967
3000
|
console.log(` Removed empty directory: ${vaultDir}`);
|
|
2968
3001
|
}
|
|
2969
3002
|
} catch {}
|
|
3003
|
+
await promptGlobalCleanup();
|
|
2970
3004
|
}
|
|
3005
|
+
|
|
2971
3006
|
console.log(`\n\x1b[32mUninstall complete.\x1b[0m`);
|
|
3007
|
+
|
|
3008
|
+
if (target !== 'all') {
|
|
3009
|
+
console.log(
|
|
3010
|
+
`\n\x1b[33m💡 本次仅卸载了 ${target} 的插件。如需清理全局配置(凭据库/OBS/KooCLI),请运行 \`npx huaweicloud-devkit uninstall --target all\`。\x1b[0m`,
|
|
3011
|
+
);
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
function removeKooCliWithMessage() {
|
|
3016
|
+
const removed = removeKooCli();
|
|
3017
|
+
if (removed.length) {
|
|
3018
|
+
console.log(` KooCLI removed: ${removed.join(', ')}`);
|
|
3019
|
+
} else {
|
|
3020
|
+
console.log(' KooCLI not found (nothing to remove).');
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
|
|
3024
|
+
function removeObsConfigWithMessage() {
|
|
3025
|
+
const removed = removeObsConfig();
|
|
3026
|
+
if (removed.length) {
|
|
3027
|
+
console.log(` OBS config removed: ${removed.join(', ')}`);
|
|
3028
|
+
} else {
|
|
3029
|
+
console.log(' OBS config not found (nothing to remove).');
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
async function promptGlobalCleanup() {
|
|
3034
|
+
const hasFlag = (name) => process.argv.includes(name);
|
|
3035
|
+
const cleanKocli = hasFlag('--clean-kocli') || hasFlag('--clean-global');
|
|
3036
|
+
const cleanObs = hasFlag('--clean-obs') || hasFlag('--clean-global');
|
|
3037
|
+
|
|
3038
|
+
// Interactive terminal: ask the user for each account-level tool.
|
|
3039
|
+
if (!cleanKocli && !cleanObs && process.stdin.isTTY && process.stdout.isTTY) {
|
|
3040
|
+
console.log('\n —— 全局凭据库已清除,是否一并删除账号级工具?——');
|
|
3041
|
+
const kocliAnswer = await readLineQuestion(' 是否一并删除 KooCLI (hcloud)?(y/N) ');
|
|
3042
|
+
const obsAnswer = await readLineQuestion(' 是否一并删除 OBS 配置 (~/.obsutilconfig)?(y/N) ');
|
|
3043
|
+
if (/^\s*y\s*$/i.test(kocliAnswer)) removeKooCliWithMessage();
|
|
3044
|
+
else console.log(' KooCLI kept.');
|
|
3045
|
+
if (/^\s*y\s*$/i.test(obsAnswer)) removeObsConfigWithMessage();
|
|
3046
|
+
else console.log(' OBS config kept.');
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
// Explicit flags: delete deterministically, without prompting.
|
|
3051
|
+
if (cleanKocli) removeKooCliWithMessage();
|
|
3052
|
+
if (cleanObs) removeObsConfigWithMessage();
|
|
3053
|
+
|
|
3054
|
+
// No flag and non-interactive: keep them and surface the option.
|
|
3055
|
+
if (!cleanKocli && !cleanObs) {
|
|
3056
|
+
console.log(
|
|
3057
|
+
`\n\x1b[33m已保留 KooCLI 与 OBS 配置(全局凭据库已删除)。如需一并清理,请使用 --clean-kocli / --clean-obs / --clean-global flag,或在交互终端重新执行全局卸载。\x1b[0m`,
|
|
3058
|
+
);
|
|
3059
|
+
}
|
|
2972
3060
|
}
|
|
2973
3061
|
|
|
2974
3062
|
async function cmdStatus() {
|
|
@@ -4005,6 +4093,42 @@ async function cmdProxy() {
|
|
|
4005
4093
|
return cmdProxyShow();
|
|
4006
4094
|
}
|
|
4007
4095
|
|
|
4096
|
+
function readInstalledVersion(pluginsDir) {
|
|
4097
|
+
const p = join(pluginsDir, 'package.json');
|
|
4098
|
+
if (!existsSync(p)) return null;
|
|
4099
|
+
try {
|
|
4100
|
+
const v = JSON.parse(readFileSync(p, 'utf8')).version;
|
|
4101
|
+
return typeof v === 'string' && v ? v : null;
|
|
4102
|
+
} catch {
|
|
4103
|
+
return null;
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
|
|
4107
|
+
function cmdVersion() {
|
|
4108
|
+
const agents = [
|
|
4109
|
+
['OpenCode', opencodePluginsDir()],
|
|
4110
|
+
['Codex Desktop', codexDesktopPluginsDir()],
|
|
4111
|
+
['OpenClaw', openclawPluginsDir()],
|
|
4112
|
+
['CodeArts', codeartsPluginsDir()],
|
|
4113
|
+
['CodeArts Work', codeartsWorkPluginsDir()],
|
|
4114
|
+
['WorkBuddy', workbuddyPluginsDir()],
|
|
4115
|
+
['DSH', dshPluginsDir()],
|
|
4116
|
+
['OfficeAce', officeacePluginsDir()],
|
|
4117
|
+
['Hermes', hermesPluginsDir()],
|
|
4118
|
+
['AtomCode', atomcodePluginsDir()],
|
|
4119
|
+
];
|
|
4120
|
+
let found = 0;
|
|
4121
|
+
for (const [label, dir] of agents) {
|
|
4122
|
+
const v = dir ? readInstalledVersion(dir) : null;
|
|
4123
|
+
if (!v) continue;
|
|
4124
|
+
console.log(`${label}: ${v}`);
|
|
4125
|
+
found += 1;
|
|
4126
|
+
}
|
|
4127
|
+
if (found === 0) {
|
|
4128
|
+
console.log('No Huawei Cloud DevKit plugin installed. Run `npx huaweicloud-devkit install --target <agent>`.');
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
|
|
4008
4132
|
async function main() {
|
|
4009
4133
|
const cmd = process.argv[2] || 'help';
|
|
4010
4134
|
|
|
@@ -4041,6 +4165,12 @@ async function main() {
|
|
|
4041
4165
|
case 'proxy':
|
|
4042
4166
|
await cmdProxy();
|
|
4043
4167
|
break;
|
|
4168
|
+
case 'version':
|
|
4169
|
+
case '--version':
|
|
4170
|
+
case '-v':
|
|
4171
|
+
case '-V':
|
|
4172
|
+
cmdVersion();
|
|
4173
|
+
break;
|
|
4044
4174
|
case 'help':
|
|
4045
4175
|
case '--help':
|
|
4046
4176
|
case '-h':
|
|
@@ -4059,11 +4189,16 @@ async function main() {
|
|
|
4059
4189
|
console.log(' install-hcloud Show KooCLI install commands for your OS');
|
|
4060
4190
|
console.log(' auth Manage unified auth: init | sync | status');
|
|
4061
4191
|
console.log(' proxy Manage proxy config: init | show | clear');
|
|
4192
|
+
console.log(' version Print installed plugin version per agent');
|
|
4062
4193
|
console.log(' help Show this help');
|
|
4063
4194
|
console.log('\nOptions:');
|
|
4064
4195
|
console.log(
|
|
4065
4196
|
' --target Target agent: opencode (default), codex, codearts, codearts-work, workbuddy, dsh, officeace, hermes, openclaw, atomcode, all',
|
|
4066
4197
|
);
|
|
4198
|
+
console.log(' --version Print installed plugin version per agent');
|
|
4199
|
+
console.log(' --clean-kocli (with: uninstall --target all) also remove KooCLI');
|
|
4200
|
+
console.log(' --clean-obs (with: uninstall --target all) also remove OBS config');
|
|
4201
|
+
console.log(' --clean-global (with: uninstall --target all) also remove KooCLI + OBS config');
|
|
4067
4202
|
console.log('\nExamples:');
|
|
4068
4203
|
console.log(' npx huaweicloud-devkit install');
|
|
4069
4204
|
console.log(' npx huaweicloud-devkit install --target codex');
|