huaweicloud-devkit 1.0.0 → 1.0.1
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 +75 -93
- package/README.zh-CN.md +138 -0
- package/package.json +2 -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/.mcp.json +3 -1
- package/plugins/huaweicloud-core/.workbuddy-plugin/plugin.json +44 -0
- package/plugins/huaweicloud-core/safety/policy.json +15 -1
- package/plugins/huaweicloud-core/safety/rules/cloud-risk-rules.json +21 -0
- package/plugins/huaweicloud-core/skills/huawei-apig/SKILL.md +22 -2
- package/plugins/huaweicloud-core/skills/huawei-cloud-eye/SKILL.md +17 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/SKILL.md +51 -1
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/create-instance.md +20 -2
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/troubleshooting.md +1 -1
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/SKILL.md +1 -1
- package/plugins/huaweicloud-core/skills/huawei-getting-started/SKILL.md +2 -2
- package/plugins/huaweicloud-core/skills/huawei-obs/SKILL.md +21 -3
- package/plugins/huaweicloud-core/skills/huawei-obs/references/single-file-share.md +40 -0
- package/plugins/huaweicloud-core/skills/huawei-rds/SKILL.md +48 -5
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +134 -0
- package/plugins/huaweicloud-core/skills/huawei-vpc/SKILL.md +5 -2
- package/plugins/huaweicloud-core/skills/huaweicloud-cli-and-auth/SKILL.md +2 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-core/SKILL.md +3 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-troubleshooting/SKILL.md +1 -1
- package/plugins/huaweicloud-core/src/auth/agent-registration.mjs +87 -0
- package/plugins/huaweicloud-core/src/auth/credentials.mjs +95 -0
- package/plugins/huaweicloud-core/src/auth/service.mjs +63 -0
- package/plugins/huaweicloud-core/src/mcp-server.mjs +11 -0
- package/plugins/huaweicloud-core/src/sandbox/hdkitservice-api.mjs +87 -0
- package/plugins/huaweicloud-core/src/sandbox/hwlink-api.mjs +153 -0
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +105 -0
- package/plugins/huaweicloud-core/src/setup-cli.mjs +732 -73
- package/plugins/huaweicloud-core/src/tools.mjs +164 -3
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-exec-client.js +427 -0
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-fair-queue.js +132 -0
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-multiplexer.js +227 -0
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-packet.js +202 -0
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-terminal-channel.js +158 -0
- package/plugins/huaweicloud-core/src/ws-exec/index.js +19 -0
- package/plugins/huaweicloud-core/src/ws-exec/ws-exec-client.js +338 -0
|
@@ -61,6 +61,11 @@ hcloud ECS CreateServers ... --server.user_data=$user_data
|
|
|
61
61
|
> **Security**: Never embed secrets (passwords, AK/SK, tokens) in user_data. It is stored unencrypted and readable from within the instance via IMDS. Fetch secrets at boot from DEW/CSMS instead.
|
|
62
62
|
>
|
|
63
63
|
> **Debugging**: If the script didn't run, check `/var/log/cloud-init-output.log` on the instance.
|
|
64
|
+
>
|
|
65
|
+
> **Recovery after failure**: user_data only executes on **first boot**. Restarting the instance will NOT re-run user_data scripts. If cloud-init fails (e.g., DNS missing → `yum`/`apt` cannot resolve repos):
|
|
66
|
+
> 1. Fix the root cause (e.g., update subnet DNS via `VPC UpdateSubnet`)
|
|
67
|
+
> 2. Either: SSH into the instance and run the setup commands manually (see `huawei-ecs` → SSH Connection Verification → Running Commands Inside the Instance)
|
|
68
|
+
> 3. Or: Delete the instance and recreate with corrected user_data (fresh boot)
|
|
64
69
|
|
|
65
70
|
## 7. EIP (two methods)
|
|
66
71
|
|
|
@@ -91,8 +96,21 @@ hcloud EIP AssociatePublicips --publicip_id=<eip-id> --publicip.associate_instan
|
|
|
91
96
|
```
|
|
92
97
|
|
|
93
98
|
## 8. Verify
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
|
|
100
|
+
ECS creation is asynchronous. Wait times vary widely (20s to 3min). Status transitions: `BUILD` → `ACTIVE` (or `ERROR`). Never use fixed sleep — poll actively:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
for i in $(seq 1 30); do
|
|
104
|
+
status=$(hcloud ECS ListServersDetails --cli-region=<region> --server_id=<instance-id> --cli-output=json | jq -r '.servers[0].status')
|
|
105
|
+
if [ "$status" = "ACTIVE" ]; then break; fi
|
|
106
|
+
if [ "$status" = "ERROR" ]; then echo "Creation failed"; exit 1; fi
|
|
107
|
+
sleep 10
|
|
108
|
+
done
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- Poll interval: 10 seconds
|
|
112
|
+
- Maximum wait: 5 minutes (30 iterations)
|
|
113
|
+
- After ACTIVE, confirm once more: `hcloud ECS ListServersDetails --cli-region=<region> --server_id=<instance-id>`
|
|
96
114
|
|
|
97
115
|
### Verify HTTP accessibility (if EIP bound)
|
|
98
116
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| Cannot SSH | 安全组未开放22端口 或 未绑定EIP | 1) 添加入方向规则 tcp 22。2) `hcloud EIP BindPublicIp` |
|
|
14
14
|
| Flavor unavailable | 区域不支持该规格 | `hcloud ECS ListFlavors --cli-region=<r>` 先查。不硬编码 s6/m6 等规格名 |
|
|
15
15
|
| Insufficient resources | AZ 库存不足 | 换规格、换 AZ、或等待资源释放 |
|
|
16
|
-
| AuthFailure | AK/SK 过期或无效 | `
|
|
16
|
+
| AuthFailure | AK/SK 过期或无效 | `npx huaweicloud-devkit auth init` 重新配置统一凭据 |
|
|
17
17
|
|
|
18
18
|
## 创建失败诊断流程
|
|
19
19
|
|
|
@@ -95,7 +95,7 @@ See `references/deploy-workflow.md` for a step-by-step example with code templat
|
|
|
95
95
|
| DeleteFunction with `:latest` | Strip `:latest` version suffix from URN |
|
|
96
96
|
| Code too large | Inline limit 10KB — use `zip`/`obs` code type |
|
|
97
97
|
| Cold start slow | Set reserved instances for critical functions |
|
|
98
|
-
| Auth failure | Run `
|
|
98
|
+
| Auth failure | Run `npx huaweicloud-devkit auth init` |
|
|
99
99
|
|
|
100
100
|
## Security Considerations
|
|
101
101
|
|
|
@@ -19,11 +19,11 @@ version: 1
|
|
|
19
19
|
## First-Time Setup
|
|
20
20
|
1. **Install KooCLI** using command above
|
|
21
21
|
2. **Accept privacy policy** (first run only): KooCLI requires one-time privacy agreement. Run `hcloud version` to read the agreement, then respond `y` to accept. Do not pipe `echo "y" |` — you must review the terms first.
|
|
22
|
-
3. **Configure credentials**: `hcloud configure init
|
|
22
|
+
3. **Configure credentials (unified)**: `npx huaweicloud-devkit auth init` — prefer this over `hcloud configure init`, which only covers KooCLI.
|
|
23
23
|
4. **Verify**: `hcloud configure list` to confirm profile, then `hcloud ECS ListServersDetails --cli-region=cn-north-4`
|
|
24
24
|
5. For detailed auth guidance, see `huaweicloud-cli-and-auth` skill
|
|
25
25
|
|
|
26
|
-
> **Security**: Never pass AK/SK as command-line arguments (`--ak=...`). Always use `
|
|
26
|
+
> **Security**: Never pass AK/SK as command-line arguments (`--ak=...`). Always use `npx huaweicloud-devkit auth init` (unified, interactive, recommended) or `hcloud configure init` (KooCLI only) to avoid secrets in shell history.
|
|
27
27
|
|
|
28
28
|
### Non-Interactive Setup (Agent/CI Environments)
|
|
29
29
|
|
|
@@ -31,7 +31,7 @@ Domain expertise for Huawei Cloud Object Storage Service (OBS). Covers bucket/ob
|
|
|
31
31
|
|
|
32
32
|
| Trap | Why |
|
|
33
33
|
|------|-----|
|
|
34
|
-
| Bucket name is global | All users share bucket namespace |
|
|
34
|
+
| Bucket name is global | All users share bucket namespace. Always use a unique name: `{prefix}-{timestamp}` (e.g. `mybucket-20260810155048`) |
|
|
35
35
|
| Three-layer permissions | IAM > Bucket Policy > ACL. Most restrictive wins |
|
|
36
36
|
| Versioning is irreversible | Once enabled, cannot be disabled, only suspended |
|
|
37
37
|
| OBS uses AK/SK directly | NOT IAM tokens. Auth errors mean check AK/SK validity |
|
|
@@ -42,7 +42,17 @@ Domain expertise for Huawei Cloud Object Storage Service (OBS). Covers bucket/ob
|
|
|
42
42
|
|
|
43
43
|
## OBS Credential Setup (Required Before First Use)
|
|
44
44
|
|
|
45
|
-
KooCLI OBS uses a separate config file (`~/.obsutilconfig`), NOT `~/.hcloud/config.json`.
|
|
45
|
+
KooCLI OBS uses a separate config file (`~/.obsutilconfig`), NOT `~/.hcloud/config.json`. All OBS commands fail with credential errors until this is configured.
|
|
46
|
+
|
|
47
|
+
**In-session bootstrap (recommended)**: Call `huaweicloud_setup_obs_config` — it syncs AK/SK from the active hcloud profile automatically. No manual key entry needed. Run this once per session before any OBS command.
|
|
48
|
+
|
|
49
|
+
**CLI fallback** (if MCP tools unavailable):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
hcloud OBS config -e=<endpoint> -i=<AK> -k=<SK> -t=token
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> `huaweicloud_setup_obs_config` should be called at the start of every OBS task — never assume credentials are pre-configured from a previous session.
|
|
46
56
|
|
|
47
57
|
## Common Workflows
|
|
48
58
|
|
|
@@ -69,6 +79,13 @@ Build → Create bucket → Upload → Set bucket ACL → Set object ACL → Con
|
|
|
69
79
|
|
|
70
80
|
> KooCLI OBS does NOT support `SetBucketWebsite`. Configure static website hosting via REST API (`PUT /?website`) or the Huawei Cloud console.
|
|
71
81
|
|
|
82
|
+
## Single-File Quick Share
|
|
83
|
+
|
|
84
|
+
See `references/single-file-share.md` for the full workflow to host one file and get a shareable link in seconds:
|
|
85
|
+
|
|
86
|
+
- **Private, time-limited**: `hcloud OBS sign obs://<bucket>/<key> -e=<seconds>` (max 7 days)
|
|
87
|
+
- **Public, permanent**: `hcloud OBS cp <file> obs://<bucket>/<key> -f` + `hcloud OBS chattri obs://<bucket>/<key> -acl=public-read`, then share `https://<bucket>.obs.<region>.myhuaweicloud.com/<key>`
|
|
88
|
+
|
|
72
89
|
## Storage Classes
|
|
73
90
|
|
|
74
91
|
| Class | Use Case | Min Storage | Retrieval Fee |
|
|
@@ -82,7 +99,7 @@ Build → Create bucket → Upload → Set bucket ACL → Set object ACL → Con
|
|
|
82
99
|
| Error | Root Cause -> Fix |
|
|
83
100
|
|-------|------------------|
|
|
84
101
|
| AccessDenied on bucket | IAM/bucket policy/ACL conflict -> Check all three layers |
|
|
85
|
-
| BucketAlreadyExists | Name taken globally ->
|
|
102
|
+
| BucketAlreadyExists | Name taken globally -> Generate unique name with timestamp suffix: `{prefix}-{yyyymmddHHMMSS}` |
|
|
86
103
|
| NoSuchKey | Object doesn't exist or wrong region -> Verify key and region |
|
|
87
104
|
| InvalidAccessKeyId | OBS uses AK/SK directly -> Verify AK/SK validity, OBS endpoint, OBS permissions |
|
|
88
105
|
| EntityTooLarge | Single PUT limit 5GB -> Use multipart upload |
|
|
@@ -105,5 +122,6 @@ Build → Create bucket → Upload → Set bucket ACL → Set object ACL → Con
|
|
|
105
122
|
|
|
106
123
|
- OBS Docs: https://support.huaweicloud.com/obs/
|
|
107
124
|
- Static website: references/static-website.md
|
|
125
|
+
- Single-file share: references/single-file-share.md
|
|
108
126
|
- Lifecycle: references/bucket-lifecycle.md
|
|
109
127
|
- Replication: references/replication.md
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# OBS Single-File Quick Share
|
|
2
|
+
|
|
3
|
+
Host one file and get a shareable link in seconds. Two options:
|
|
4
|
+
|
|
5
|
+
| Option | Link type | Bucket/object visibility | Expiry |
|
|
6
|
+
|--------|-----------|--------------------------|--------|
|
|
7
|
+
| Presigned URL | Time-limited private link | Keep private | `-e=<seconds>`, max 7 days |
|
|
8
|
+
| Public URL | Permanent public link | Set object `-acl=public-read` | None |
|
|
9
|
+
|
|
10
|
+
## Option 1: Presigned URL (private, time-limited)
|
|
11
|
+
|
|
12
|
+
No ACL change needed. The object stays private; the link grants temporary access.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
hcloud OBS cp <file> obs://<bucket>/<key> -f
|
|
16
|
+
hcloud OBS sign obs://<bucket>/<key> -e=3600 # valid 1 hour, max 604800 (7 days)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The `sign` command prints the full presigned URL directly — share it as-is.
|
|
20
|
+
|
|
21
|
+
## Option 2: Public URL (permanent, public-read)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
hcloud OBS cp <file> obs://<bucket>/<key> -f
|
|
25
|
+
hcloud OBS chattri obs://<bucket>/<key> -acl=public-read
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The shareable public URL follows the OBS endpoint format (NOT the `obs-website` static-site endpoint):
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
https://<bucket>.obs.<region>.myhuaweicloud.com/<key>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Key Gotchas
|
|
35
|
+
|
|
36
|
+
- **Bucket ACL does NOT cascade**: `chattri obs://<bucket> -acl=public-read` alone does not make objects public. Set the object-level ACL explicitly.
|
|
37
|
+
- **`-f` is mandatory**: `cp` without `-f` prompts "Please input (y/n)" on overwrite → agent hangs (TIMEOUT).
|
|
38
|
+
- **Public-read means anyone with the link can access**: use presigned URLs when the file is sensitive.
|
|
39
|
+
- **Presigned URL max expiry is 7 days** (`-e=604800`). For longer-lived public access, use the public-read option.
|
|
40
|
+
- **Credential setup**: OBS uses a separate config (`~/.obsutilconfig`). Call `huaweicloud_setup_obs_config` before first use.
|
|
@@ -29,7 +29,7 @@ hcloud RDS <Operation> --cli-region=<region> [--key=value ...]
|
|
|
29
29
|
| Operation | PascalCase: `ListInstances`, `CreateManualBackup` |
|
|
30
30
|
| Params | `--key=value` format. JSON params: `--key='{"k":"v"}'` |
|
|
31
31
|
| Array params | 1-based: `--instance_ids.1=xxx` |
|
|
32
|
-
| Password param | Conflicts with KooCLI system param;
|
|
32
|
+
| Password param | Conflicts with KooCLI system param; use `--cli-jsonInput` (see Critical Warnings) |
|
|
33
33
|
|
|
34
34
|
## Critical Warnings
|
|
35
35
|
|
|
@@ -38,9 +38,12 @@ hcloud RDS <Operation> --cli-region=<region> [--key=value ...]
|
|
|
38
38
|
| Engine version immutable | Cannot change MySQL to PostgreSQL in-place |
|
|
39
39
|
| Automated backups use OBS | Backup storage incurs separate charges. Set retention period explicitly |
|
|
40
40
|
| Storage auto-scaling off by default | Enable before storage runs out or instance goes read-only |
|
|
41
|
-
| `--password` conflicts with KooCLI |
|
|
41
|
+
| `--password` conflicts with KooCLI | Use `--cli-jsonInput=<file>` with JSON file (see `--cli-jsonInput` section below). The `printf "b\n"` workaround is broken in KooCLI 7.2.12+ |
|
|
42
42
|
| Volume type must match flavor | General→CLOUDSSD; Dedicated→CLOUDSSD\|ESSD; ARM→ULTRAHIGH |
|
|
43
43
|
| Flavor not in region | Always `ListFlavors` first. Spec codes vary by region |
|
|
44
|
+
| `database_name` is case-sensitive | Use `MySQL` / `PostgreSQL` / `SQLServer` / `MariaDB` — NOT lower-case `mysql` |
|
|
45
|
+
| Instance creation takes 3–8 min | Status: BUILD→MODIFYING→ACTIVE. Poll every 15s: `hcloud RDS ListInstances --cli-region=<r> --instance_id=<id> \| jq '.instances[0].status'` |
|
|
46
|
+
| Body `--region` is required | CreateInstance body requires `--region=<r>` (same as `--cli-region`) or `DBS.280243` |
|
|
44
47
|
| Restore creates new instance | No in-place restore. Verify target flavor before restoring |
|
|
45
48
|
|
|
46
49
|
## Instance Management
|
|
@@ -56,6 +59,7 @@ hcloud RDS ListEngineFlavors --instance_id=<id> --cli-region=<r>
|
|
|
56
59
|
### Create Instance
|
|
57
60
|
```bash
|
|
58
61
|
hcloud RDS CreateInstance --cli-region=<r> \
|
|
62
|
+
--region=<r> \
|
|
59
63
|
--name=<name> \
|
|
60
64
|
--datastore.type=<engine> \
|
|
61
65
|
--datastore.version=<version> \
|
|
@@ -66,11 +70,36 @@ hcloud RDS CreateInstance --cli-region=<r> \
|
|
|
66
70
|
--subnet_id=<subnet-id> \
|
|
67
71
|
--security_group_id=<sg-id> \
|
|
68
72
|
--availability_zone=<az> \
|
|
69
|
-
--charge_info.charge_mode=<mode>
|
|
70
|
-
--password=<pw>
|
|
73
|
+
--charge_info.charge_mode=<mode>
|
|
71
74
|
```
|
|
72
75
|
|
|
73
|
-
> `--password` conflicts with a KooCLI system param.
|
|
76
|
+
> `--password` conflicts with a KooCLI system param. Use `--cli-jsonInput` (see below). The `printf "b\n"` pipe workaround is broken in KooCLI 7.2.12+.
|
|
77
|
+
|
|
78
|
+
### `--cli-jsonInput` for CreateInstance
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"path": {
|
|
83
|
+
"project_id": "<project-id>"
|
|
84
|
+
},
|
|
85
|
+
"body": {
|
|
86
|
+
"name": "<name>",
|
|
87
|
+
"region": "<region>",
|
|
88
|
+
"datastore": { "type": "<engine>", "version": "<version>" },
|
|
89
|
+
"ha": { "mode": "single", "replication_mode": "semisync" },
|
|
90
|
+
"flavor_ref": "<flavor-id>",
|
|
91
|
+
"volume": { "type": "<vol-type>", "size": <gb> },
|
|
92
|
+
"vpc_id": "<vpc-id>",
|
|
93
|
+
"subnet_id": "<subnet-id>",
|
|
94
|
+
"security_group_id": "<sg-id>",
|
|
95
|
+
"availability_zone": "<az>",
|
|
96
|
+
"password": "<pw>",
|
|
97
|
+
"charge_info": { "charge_mode": "postPaid" }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
> Save as `rds-create.json` then: `hcloud RDS CreateInstance --cli-jsonInput=rds-create.json`. For `project_id`, run `hcloud IAM KeystoneListProjects`.
|
|
74
103
|
|
|
75
104
|
| Param | Required | Note |
|
|
76
105
|
|-------|----------|------|
|
|
@@ -139,6 +168,20 @@ psql -h <private_ip> -p 5432 -U root -d postgres
|
|
|
139
168
|
> hcloud does NOT support SQL execution. Use a database client.
|
|
140
169
|
> For public access, bind an EIP (see `huawei-vpc`).
|
|
141
170
|
|
|
171
|
+
### Database Client Acquisition
|
|
172
|
+
|
|
173
|
+
If a database client is not installed on the agent's machine, install one:
|
|
174
|
+
|
|
175
|
+
| Platform | MySQL | PostgreSQL |
|
|
176
|
+
|----------|-------|------------|
|
|
177
|
+
| **Linux** | `apt install mysql-client` / `yum install mysql` | `apt install postgresql-client` |
|
|
178
|
+
| **macOS** | `brew install mysql-client` | `brew install libpq` |
|
|
179
|
+
| **Windows** | Download MySQL Workbench or `winget install Oracle.MySQL` | Download pgAdmin or `winget install PostgreSQL.PostgreSQL` |
|
|
180
|
+
| **Python (any)** | `pip install pymysql` then `python -c "import pymysql; ..."` | `pip install psycopg2` then `python -c "import psycopg2; ..."` |
|
|
181
|
+
| **Docker (any)** | `docker run -it --rm mysql:8 mysql -h <ip> -u root -p` | `docker run -it --rm postgres:16 psql -h <ip> -U root` |
|
|
182
|
+
|
|
183
|
+
> If no client can be installed, use the Huawei Cloud **Data Studio** console: https://console.huaweicloud.com/dms/
|
|
184
|
+
|
|
142
185
|
## Mutating Operations (Require Approval)
|
|
143
186
|
|
|
144
187
|
| Operation | Effect |
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: huawei-sandbox
|
|
3
|
+
description: "Use when creating, connecting, or managing Huawei Cloud Sandbox instances and workspace terminals, or when a task needs a temporary runtime to deploy, run, or preview a web application. Covers sandbox lifecycle (check-user, sign-agreement, connect, release), session-based terminal execution, and credential injection. Triggers on: sandbox, workspace, terminal, web app deployment, deploy web app, preview app, deploy github, github repo, deploy repo, website, static site, web application, hwlink, devstation, hdkitservice, remote exec. NOT for: ECS instances (use huawei-ecs), CCE clusters (use huawei-cce)."
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Huawei Cloud Sandbox
|
|
8
|
+
|
|
9
|
+
**STOP - Do not answer from general knowledge.** Follow the procedure below.
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Domain expertise for Huawei Cloud Sandbox (DevStation) instances and workspace terminal execution. Covers sandbox lifecycle via hdkitservice API and remote terminal command execution via hwlink protocol.
|
|
14
|
+
|
|
15
|
+
## Activation
|
|
16
|
+
|
|
17
|
+
- **Proactive offering**: when the developer's task needs a temporary runtime (e.g. "deploy this web app", "run this app and preview it"), offer the sandbox proactively — the developer never has to say "use sandbox". Prompt: "This task can be satisfied by a sandbox — use it?"
|
|
18
|
+
- **Detect web apps in deploy-a-repo prompts**: prompts like "部署 GitHub - <owner>/<repo>" or "deploy <github repo>" do not say "web app". Clone or inspect the repository first (package.json with dev/serve/build scripts, index.html, frontend framework dependencies such as vue/react/angular/vite, static sites, Dockerfile running a web server). If it is a web application, offer the sandbox first: "检测到该项目是 Web 应用,建议优先使用沙箱部署(临时运行环境,可预览访问),是否使用?"
|
|
19
|
+
- **Clone into the sandbox workspace directory**: always put project code under `/workspace/<repo-name>` (create the directory if missing) — `/workspace` is the sandbox's dedicated workspace mount at the filesystem root, not `$HOME/workspace`. Never use `/tmp` or other ephemeral locations. This keeps the project with the sandbox session, is easy to reference for serving/exposing, and survives session-level restarts of the shell.
|
|
20
|
+
- **Deployment must end with a public URL**: after deploying and exposing the app with DevBridge, always return the tunnel URL to the developer as the final result — a deployment without an accessible link is incomplete.
|
|
21
|
+
- **Do not intercept a specified target**: if the task already names a deployment target (ECS, CCE, an existing server), follow that target instead of offering the sandbox. Offer the sandbox only when the task needs a temporary runtime or no target is specified.
|
|
22
|
+
- The developer never needs to name or understand the sandbox as a separate service. Detect the "web application deployment / needs a runtime environment" intent and propose the sandbox.
|
|
23
|
+
|
|
24
|
+
## MCP Tools
|
|
25
|
+
|
|
26
|
+
### User Verification (Prerequisites)
|
|
27
|
+
|
|
28
|
+
| Tool | Purpose |
|
|
29
|
+
|------|---------|
|
|
30
|
+
| `huaweicloud_sandbox_check_user` | Check real-name verification and agreement signing status |
|
|
31
|
+
| `huaweicloud_sandbox_sign_agreement` | Sign unsigned/outdated agreements (required before connect) |
|
|
32
|
+
|
|
33
|
+
### Sandbox Lifecycle
|
|
34
|
+
|
|
35
|
+
| Tool | Purpose |
|
|
36
|
+
|------|---------|
|
|
37
|
+
| `huaweicloud_sandbox_connect` | Connect to sandbox (one user one instance, reuses existing if available) |
|
|
38
|
+
| `huaweicloud_sandbox_credentials` | Inject temporary AK/SK into a running sandbox |
|
|
39
|
+
|
|
40
|
+
### Terminal Execution
|
|
41
|
+
|
|
42
|
+
| Tool | Purpose |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| `huaweicloud_sandbox_exec_with_session` | Session-based execution (state persists) |
|
|
45
|
+
| `huaweicloud_sandbox_close_session` | Close a persistent terminal session |
|
|
46
|
+
|
|
47
|
+
## Workflow
|
|
48
|
+
|
|
49
|
+
Setup is a **plugin-side preflight** — the developer should be asked a question only once, when the agreement actually needs signing:
|
|
50
|
+
|
|
51
|
+
1. **Check user** (transparent): `huaweicloud_sandbox_check_user` — verify `realname_verified` and `agreement_signed`
|
|
52
|
+
2. **Real-name verification** (only if `realname_verified=false`): tell the developer once, "Huawei Cloud requires real-name verification before using the sandbox." and stop — do not retry `connect` in a loop
|
|
53
|
+
3. **Sign agreement** (only if `agreement_signed=false`): ask the developer once as the plugin — "Huawei Cloud sandbox requires signing its service agreement. May I sign it on your behalf?" — then call `huaweicloud_sandbox_sign_agreement`. Do not expose the underlying sandbox/DevBridge service as a separate entity the developer must understand or sign up for
|
|
54
|
+
4. **Connect**: `huaweicloud_sandbox_connect` — returns `session_id`, `dev_stage_id`, `connection_id`, `connection_address`
|
|
55
|
+
5. **Inject credentials** (optional): `huaweicloud_sandbox_credentials` — enables cloud API access from sandbox
|
|
56
|
+
6. **Execute commands**: `huaweicloud_sandbox_exec_with_session` for interactive work
|
|
57
|
+
7. **Expose the deployed app and return the public URL**: set up a public access link for the app port and give the URL to the developer as the final result (see "Expose the deployed app (public URL)") — this step uses an internal tunnel mechanism that must never be mentioned to the developer
|
|
58
|
+
|
|
59
|
+
## Expose the deployed app (public URL)
|
|
60
|
+
|
|
61
|
+
Expose a deployed web app to a public URL and return that URL to the developer.
|
|
62
|
+
|
|
63
|
+
**User-facing language rule**: the tunnel mechanism below is an internal implementation detail. Never mention "DevBridge", "tunnel", or the tunnel CLI to the developer. Tell the developer only: "正在生成访问地址..." while exposing, then hand over the final URL.
|
|
64
|
+
|
|
65
|
+
**Install** (internal tooling; skip if `devbridge version` already works):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
curl -fsSL https://res-hd.hc-cdn.cn/sharedata/hdspace/devbridge/install.sh | bash
|
|
69
|
+
export PATH=$PATH:$HOME/.huawei/bin # installer only writes ~/.bashrc; session shells do not re-source it
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Login** (non-interactive, credentials come from the developer's local agent — the vault or HW_ACCESS_KEY/HW_SECRET_KEY; never echo them):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
devbridge auth login --huaweicloud --access-key "$AK" --secret-key "$SK"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- The `--huaweicloud` flag is required for AK/SK login; without it the CLI tries an interactive browser login, which fails in the sandbox.
|
|
79
|
+
- Write the AK/SK to temp files with `umask 077` (or shell vars) and delete them right after login. Verify with `devbridge auth status`.
|
|
80
|
+
|
|
81
|
+
**Expose** (run the web server and the tunnel in the background, then read the URL from the log; the app lives in the workspace mount, e.g. `/workspace/<repo-name>`):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cd /workspace/<repo-name> && nohup python3 -m http.server 8080 > /tmp/http.log 2>&1 &
|
|
85
|
+
nohup devbridge host -p 8080 -e 8 > /tmp/host.log 2>&1 &
|
|
86
|
+
sleep 10 && cat /tmp/host.log
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- The public URL has the form `https://<id>-<port>.cn-north-4-bridge.myhuaweicloud.com` (from the `Tunnel URL:` line).
|
|
90
|
+
- **Return this URL to the developer as the deployment result link.** Keep the host process running (do not close the session before handing over the URL).
|
|
91
|
+
- Internal docs: https://huaweicloud.github.io/devspace-devbridge/
|
|
92
|
+
|
|
93
|
+
**No local downgrade**: if the tunnel tooling cannot be installed in the sandbox, STOP and report a generic error ("无法生成访问地址") without technical detail. Never install it on the developer's local machine — a local install would defeat the purpose of sandbox deployment.
|
|
94
|
+
|
|
95
|
+
## Critical Warnings
|
|
96
|
+
|
|
97
|
+
| Trap | Why |
|
|
98
|
+
|------|-----|
|
|
99
|
+
| Agreement required first | `sandbox_connect` fails if the agreement isn't signed; the `sandbox_check_user` preflight detects this, so surface it to the developer only when signing is needed |
|
|
100
|
+
| Real-name required | `sandbox_connect` fails if `realname_verified=false`; tell the developer once and stop, don't loop on connect |
|
|
101
|
+
| Never expose tunnel details | Do not mention "DevBridge"/"tunnel"/"devbridge" to the developer — say "正在生成访问地址..." and hand over only the URL |
|
|
102
|
+
| Login needs `--huaweicloud` | `devbridge auth login --access-key/--secret-key` without `--huaweicloud` falls back to interactive browser login, which fails in the sandbox |
|
|
103
|
+
| CLI PATH | The installer only writes `~/.bashrc`; run `export PATH=$PATH:$HOME/.huawei/bin` in the session before using `devbridge` |
|
|
104
|
+
| Never install tunnel tooling locally | If the sandbox cannot install it, report a generic error and stop — installing on the developer's machine defeats sandbox deployment |
|
|
105
|
+
| Return the deployment URL | Always hand the public URL from the host log to the developer as the final result |
|
|
106
|
+
| Session state persists | `exec_with_session` preserves `cd`, env vars, aliases between calls |
|
|
107
|
+
| Destructive commands blocked | `rm -rf /`, `mkfs`, `dd if=`, fork bombs are denied by safety policy |
|
|
108
|
+
| Workspace ID = dev_stage_id | Use `dev_stage_id` from `sandbox_connect` as `workspace_id` for terminal exec |
|
|
109
|
+
| Projects live in `/workspace` | Clone/install project code under `/workspace/<repo-name>` (filesystem-root workspace mount, not `$HOME/workspace`), never in `/tmp` — ephemeral locations lose the project when the sandbox session restarts |
|
|
110
|
+
| Node.js >= 22 required | Sandbox terminal uses built-in WebSocket (globalThis.WebSocket); if Node.js is missing, install it from the Huawei Cloud mirror (see "Node.js in the sandbox") |
|
|
111
|
+
|
|
112
|
+
## Node.js in the sandbox
|
|
113
|
+
|
|
114
|
+
If the sandbox has no Node.js, download it from the Huawei Cloud mirror. Pick the tarball matching the sandbox arch (`uname -m`: `aarch64` -> arm64, `x86_64` -> x64):
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# aarch64 sandbox:
|
|
118
|
+
curl -fsSL https://mirrors.huaweicloud.com/nodejs/v24.19.0/node-v24.19.0-linux-arm64.tar.gz -o node.tar.gz
|
|
119
|
+
# x86_64 sandbox:
|
|
120
|
+
curl -fsSL https://mirrors.huaweicloud.com/nodejs/v24.19.0/node-v24.19.0-linux-x64.tar.gz -o node.tar.gz
|
|
121
|
+
sudo tar -xzf node.tar.gz -C /usr/local --strip-components=1
|
|
122
|
+
node --version
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Environment Variables
|
|
126
|
+
|
|
127
|
+
| Variable | Required | Description |
|
|
128
|
+
|----------|----------|-------------|
|
|
129
|
+
| `HW_ACCESS_KEY` | Yes | Huawei Cloud AK |
|
|
130
|
+
| `HW_SECRET_KEY` | Yes | Huawei Cloud SK |
|
|
131
|
+
| `HW_SECURITY_TOKEN` | No | STS security token |
|
|
132
|
+
| `HW_WORKSPACE_ID` | No | Default workspace ID |
|
|
133
|
+
| `HDKITSERVICE_ENDPOINT` | No | hdkitservice API endpoint |
|
|
134
|
+
| `HWLINK_ENDPOINT` | No | DevStation API endpoint |
|
|
@@ -28,15 +28,17 @@ Domain expertise for Huawei Cloud Virtual Private Cloud (VPC). Covers VPC/subnet
|
|
|
28
28
|
| EIP PER type needs `--bandwidth.name` | PER bandwidth requires explicit name; `--help` marks it optional but it's required |
|
|
29
29
|
| **VPC params need nested prefix** | KooCLI 7.x VPC API uses `--vpc.<param>`, `--subnet.<param>`, `--security_group.<param>`. Example: `--vpc.name=xxx` NOT `--name=xxx` |
|
|
30
30
|
| **Security group needs no vpc_id** | VPC v3 API `CreateSecurityGroup` does NOT accept `vpc_id`. Security groups are region-level, not VPC-bound |
|
|
31
|
-
| Subnet DNS empty → ECS no DNS | DNS params (`--subnet.primary_dns`, `--subnet.secondary_dns`) marked optional but empty default breaks cloud-init domain resolution — `yum`/`apt` installs fail silently. Always set both.
|
|
31
|
+
| Subnet DNS empty → ECS no DNS | DNS params (`--subnet.primary_dns`, `--subnet.secondary_dns`) marked optional but empty default breaks cloud-init domain resolution — `yum`/`apt` installs fail silently. Always set both. Common DNS IPs: cn-north-4 (100.125.1.250 / 100.125.1.251), cn-north-1 (100.125.1.250 / 100.125.129.250), cn-east-3 (100.125.1.250 / 100.125.129.250), ap-southeast-3 (100.125.1.250 / 100.125.128.250) |
|
|
32
32
|
| SCP blocks 0.0.0.0/0 SG rules | If `CreateSecurityGroupRule` with `--remote_ip_prefix=0.0.0.0/0` fails with `SYS.0403`, an org-level SCP policy is denying wide-open rules. Narrow to a specific CIDR range (e.g., your office IP) instead |
|
|
33
|
+
| **VPC tags use `*` separator** | VPC tag format: `--vpc.tags.1=env*test` (asterisk between key and value). NOT `--vpc.tags.1.key=env` (ECS-style). This is different from ECS `--server.metadata.key=value` |
|
|
33
34
|
|
|
34
35
|
## Common Workflows
|
|
35
36
|
|
|
36
37
|
| Task | Command | Steps |
|
|
37
38
|
|------|---------|-------|
|
|
38
39
|
| Create VPC | hcloud VPC CreateVpc --vpc.name=<name> --vpc.cidr=<cidr> | CIDR must not conflict with existing VPCs. Run `hcloud VPC ListVpcs` first |
|
|
39
|
-
| Create subnet | hcloud VPC CreateSubnet --subnet.name=<name> --subnet.vpc_id=<id> --subnet.cidr=<cidr> --subnet.gateway_ip=<gw> --subnet.primary_dns=<dns1> --subnet.secondary_dns=<dns2> --subnet.availability_zone=<az> | Subnet CIDR must be a subset of the VPC CIDR. DNS addresses vary by region — see
|
|
40
|
+
| Create subnet | hcloud VPC CreateSubnet --subnet.name=<name> --subnet.vpc_id=<id> --subnet.cidr=<cidr> --subnet.gateway_ip=<gw> --subnet.primary_dns=<dns1> --subnet.secondary_dns=<dns2> --subnet.availability_zone=<az> | Subnet CIDR must be a subset of the VPC CIDR. DNS addresses vary by region — see Critical Warnings for common values |
|
|
41
|
+
| Update subnet | hcloud VPC UpdateSubnet --subnet_id=<id> --subnet.dnsList.1=<dns1> --subnet.dnsList.2=<dns2> | Fix DNS after creation. Restart ECS after updating DNS for cloud-init to pick up changes |
|
|
40
42
|
| Security group | hcloud VPC CreateSecurityGroup --security_group.name=<name> | references/security-group.md |
|
|
41
43
|
| SG rule | hcloud VPC CreateSecurityGroupRule --security_group_rule.security_group_id=<id> --security_group_rule.direction=<direction> --security_group_rule.protocol=<protocol> --security_group_rule.multiport=<port> --security_group_rule.remote_ip_prefix=<cidr> | references/security-group.md |
|
|
42
44
|
| Create EIP | hcloud EIP CreatePublicip --publicip.type=<type> --bandwidth.size=<size> --bandwidth.share_type=<share-type> --bandwidth.name=<name> | Run `hcloud EIP CreatePublicip --help` to confirm valid type values per region |
|
|
@@ -58,6 +60,7 @@ Domain expertise for Huawei Cloud Virtual Private Cloud (VPC). Covers VPC/subnet
|
|
|
58
60
|
| VPC.0301: Bandwidth name invalid | PER type requires `--bandwidth.name`, even though `--help` marks it optional |
|
|
59
61
|
| EIP has no public IP after binding | May need AddIngressEipV2 for ELB-type resources (see huawei-apig) |
|
|
60
62
|
| ECS cloud-init fails silently (port 80/443 closed) | Subnet likely has no DNS. Check `hcloud VPC ShowSubnet --subnet_id=<id>` → `dnsList` empty? Rebuild subnet with `--subnet.primary_dns=<dns1> --subnet.secondary_dns=<dns2>`. DNS addresses per region: `hcloud VPC CreateSubnet --help` |
|
|
63
|
+
| VPC.0209: Subnet still used | Subnet has dependent resources (ECS/RDS) — delete instances first, then subnet |
|
|
61
64
|
| SYS.0403 / SCP deny | Service Control Policy explicitly denies this operation — contact org admin to adjust SCP, or use an account/region without the restriction. If SSH is blocked, bootstrap via cloud-init user_data instead: see `huawei-ecs` — no SSH needed |
|
|
62
65
|
|
|
63
66
|
## Security Considerations
|
|
@@ -60,7 +60,8 @@ Agent processes find executables through `PATH`. If OpenCode/Codex cannot find `
|
|
|
60
60
|
**NEVER let AK/SK enter shell history. This is the #1 credential leak vector.**
|
|
61
61
|
|
|
62
62
|
- Create AK/SK in the Huawei Cloud console under `My Credentials -> Access Keys`.
|
|
63
|
-
- **
|
|
63
|
+
- **Unified credentials** (preferred): `npx huaweicloud-devkit auth init`. This is the DevKit's primary auth path; `hcloud configure init` only covers KooCLI.
|
|
64
|
+
- **KooCLI only, interactive** (SAFE): `hcloud configure init` — prompts for AK/SK via terminal input. Values do NOT enter shell history.
|
|
64
65
|
- **Non-interactive** (DANGEROUS — AK/SK in shell history): `hcloud configure set --cli-access-key=<AK> --cli-secret-key=<SK> --cli-region=<region>`. Only use in ephemeral CI/CD shells. User must execute outside agent chat.
|
|
65
66
|
- If MCP is available, use `huaweicloud_show_profile_redacted` to check status without ever seeing credentials.
|
|
66
67
|
- Never paste AK/SK, passwords, tokens, or profile files into the agent conversation.
|
|
@@ -36,7 +36,8 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
36
36
|
| observability | Observability Routing | monitor, alarm, log, audit, trace, Cloud Eye | Handoff to huawei-cloud-eye or huawei-cts |
|
|
37
37
|
| billing | Billing Routing | cost, bill, budget, spending, invoice | Handoff to huawei-billing |
|
|
38
38
|
| iam | IAM Routing | permission, policy, role, user, group, AK/SK | Handoff to huawei-iam |
|
|
39
|
-
| deployment | Deployment Routing | deploy, CI/CD, pipeline, release |
|
|
39
|
+
| deployment | Deployment Routing | deploy, CI/CD, pipeline, release | CI/CD pipeline -> huawei-deployment; deploy a web app or a GitHub repo (no CI/CD target) -> huawei-sandbox |
|
|
40
|
+
| sandbox | Sandbox Routing | sandbox, DevStation, workspace, terminal, preview, temporary runtime | Handoff to huawei-sandbox |
|
|
40
41
|
| cli | CLI and Auth Routing | install hcloud, configure KooCLI, AK/SK setup | Handoff to huaweicloud-cli-and-auth |
|
|
41
42
|
| safety | Safety Routing | is this safe, approve command, risk review | Handoff to huaweicloud-safety |
|
|
42
43
|
| troubleshoot | Troubleshooting Routing | error, bug, failed, AccessDenied, quota | Handoff to huaweicloud-troubleshooting |
|
|
@@ -67,6 +68,7 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
67
68
|
| Audit trails | CTS | huawei-cts |
|
|
68
69
|
| Backup / disaster recovery | CBR | huawei-cbr |
|
|
69
70
|
| CI/CD pipeline | CloudDeploy | huawei-deployment |
|
|
71
|
+
| Temporary runtime / web app preview | Sandbox (DevStation) | huawei-sandbox |
|
|
70
72
|
| Getting started | Account setup | huaweicloud-cli-and-auth |
|
|
71
73
|
|
|
72
74
|
## Capability Sources
|
|
@@ -50,7 +50,7 @@ Use evidence before fixes. Do not guess service behavior when request IDs, regio
|
|
|
50
50
|
|
|
51
51
|
| Error | Likely Cause | Fix |
|
|
52
52
|
|-------|-------------|-----|
|
|
53
|
-
| AuthFailure / 401 | AK/SK invalid or expired | Regenerate AK/SK, re-run `
|
|
53
|
+
| AuthFailure / 401 | AK/SK invalid or expired | Regenerate AK/SK, re-run `npx huaweicloud-devkit auth init` |
|
|
54
54
|
| AccessDenied / 403 | IAM permission missing | Check `huawei-iam` skill, add required policy action |
|
|
55
55
|
| NoSuchKey / 404 | Resource not found | Verify resource ID, region, and project_id |
|
|
56
56
|
| QuotaExceeded | Account limit reached | Request quota increase in console |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
export const SUPPORTED_AGENT_TARGETS = ['opencode', 'codex', 'codex-desktop', 'codearts', 'workbuddy'];
|
|
7
|
+
|
|
8
|
+
function baseHome() {
|
|
9
|
+
return process.env.HUAWEICLOUD_HOME || homedir();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function opencodeConfigFile() {
|
|
13
|
+
const jsonc = join(baseHome(), '.config', 'opencode', 'opencode.jsonc');
|
|
14
|
+
if (existsSync(jsonc)) return jsonc;
|
|
15
|
+
return join(baseHome(), '.config', 'opencode', 'opencode.json');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function readJsonSafe(path) {
|
|
19
|
+
if (!existsSync(path)) return null;
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function opencodeRegistered() {
|
|
28
|
+
const path = opencodeConfigFile();
|
|
29
|
+
const cfg = readJsonSafe(path);
|
|
30
|
+
return Boolean(cfg?.mcp?.['huaweicloud-devkit']);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function codexDesktopRegistered() {
|
|
34
|
+
const path = join(baseHome(), '.codex', 'config.toml');
|
|
35
|
+
if (!existsSync(path)) return false;
|
|
36
|
+
try {
|
|
37
|
+
return readFileSync(path, 'utf8').includes('[mcp_servers.huaweicloud-devkit]');
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function codexCliRegistered() {
|
|
44
|
+
try {
|
|
45
|
+
const r = spawnSync('codex', ['plugin', 'list'], {
|
|
46
|
+
shell: false,
|
|
47
|
+
windowsHide: true,
|
|
48
|
+
stdio: 'pipe',
|
|
49
|
+
timeout: 10000,
|
|
50
|
+
});
|
|
51
|
+
const out = `${r.stdout || ''}${r.stderr || ''}`;
|
|
52
|
+
return out.includes('huaweicloud-core');
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function codeartsRegistered() {
|
|
59
|
+
const paths = [
|
|
60
|
+
join(baseHome(), '.codeartsdoer', 'mcp', 'mcp_settings.json'),
|
|
61
|
+
join(process.cwd(), '.codeartsdoer', 'mcp', 'mcp_settings.json'),
|
|
62
|
+
];
|
|
63
|
+
return paths.some((path) => {
|
|
64
|
+
const cfg = readJsonSafe(path);
|
|
65
|
+
return Boolean(cfg?.mcpServers?.['huaweicloud-devkit']);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function workbuddyRegistered() {
|
|
70
|
+
const cfg = readJsonSafe(join(baseHome(), '.workbuddy', 'mcp.json'));
|
|
71
|
+
return Boolean(cfg?.mcpServers?.['huaweicloud-devkit']);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function getAgentRegistrationStatuses(target = 'all') {
|
|
75
|
+
const requested = target === 'all' ? SUPPORTED_AGENT_TARGETS : [target];
|
|
76
|
+
const result = { target, agents: {} };
|
|
77
|
+
for (const agent of requested) {
|
|
78
|
+
let configured = false;
|
|
79
|
+
if (agent === 'opencode') configured = opencodeRegistered();
|
|
80
|
+
if (agent === 'codex-desktop') configured = codexDesktopRegistered();
|
|
81
|
+
if (agent === 'codex') configured = codexCliRegistered();
|
|
82
|
+
if (agent === 'codearts') configured = codeartsRegistered();
|
|
83
|
+
if (agent === 'workbuddy') configured = workbuddyRegistered();
|
|
84
|
+
result.agents[agent] = { configured };
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|