huaweicloud-devkit 1.0.2-next.2 → 1.0.3-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -25
- package/README.zh-CN.md +1 -23
- package/bin/setup.cjs +0 -0
- package/package.json +1 -3
- 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/.workbuddy-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/skills/huawei-obs/SKILL.md +0 -6
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +4 -5
- package/plugins/huaweicloud-core/skills/huaweicloud-capability-discovery/SKILL.md +0 -4
- package/plugins/huaweicloud-core/skills/huaweicloud-core/SKILL.md +3 -18
- package/plugins/huaweicloud-core/src/auth/agent-registration.mjs +1 -19
- package/plugins/huaweicloud-core/src/sandbox/hdkitservice-api.mjs +3 -7
- package/plugins/huaweicloud-core/src/sandbox/hwlink-api.mjs +3 -12
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +0 -7
- package/plugins/huaweicloud-core/src/search-market.mjs +2 -7
- package/plugins/huaweicloud-core/src/setup-cli.mjs +10 -433
- package/plugins/huaweicloud-core/src/tools.mjs +6 -21
- package/plugins/huaweicloud-core/src/proxy/proxy-agent.mjs +0 -155
- package/plugins/huaweicloud-core/src/proxy/proxy-config.mjs +0 -87
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
Help AI coding agents use Huawei Cloud safely and accurately — a single integration that gives agents cloud knowledge, CLI tooling, and safety guardrails.
|
|
10
10
|
|
|
11
|
-
Supports OpenCode, Codex, CodeArts Agent,
|
|
11
|
+
Supports OpenCode, Codex, CodeArts Agent, and WorkBuddy.
|
|
12
12
|
|
|
13
13
|
## Prerequisites
|
|
14
14
|
|
|
@@ -85,29 +85,6 @@ npx --yes huaweicloud-devkit uninstall --target workbuddy
|
|
|
85
85
|
|
|
86
86
|
> **Updating**: `update` is incremental per agent — it refreshes only the installed files and leaves your config untouched. Use `update --target all` to update every installed agent at once.
|
|
87
87
|
|
|
88
|
-
### DeepSeek Harness (DSH)
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
npx --yes huaweicloud-devkit install --target dsh
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
The installer copies Skills to `$DSH_HOME/skills`, installs the MCP server and
|
|
95
|
-
safety policy under `$DSH_HOME/huaweicloud-plugins`, and maintains
|
|
96
|
-
`$DSH_HOME/profiles/web/cordis.patch.yml`. **Restart the DSH session** after
|
|
97
|
-
installation.
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
npx --yes huaweicloud-devkit doctor
|
|
101
|
-
npx --yes huaweicloud-devkit status --target dsh
|
|
102
|
-
npx --yes huaweicloud-devkit update --target dsh
|
|
103
|
-
npx --yes huaweicloud-devkit uninstall --target dsh
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
> DSH V1 reuses the existing MCP server through
|
|
107
|
-
> `@deepseek-ai/dsh-mcp-client`. If the installer reports that the DSH MCP
|
|
108
|
-
> client is not detected, run:
|
|
109
|
-
> `npx @deepseek-ai/dsh plugin --profile web add @deepseek-ai/dsh-mcp-client`.
|
|
110
|
-
|
|
111
88
|
### Other Agents
|
|
112
89
|
|
|
113
90
|
For agents that support the Model Context Protocol (MCP):
|
|
@@ -148,7 +125,6 @@ ECS, OBS, VPC, IAM, RDS, GaussDB, FunctionGraph, APIG, CCE, SMN/DMS, ModelArts,
|
|
|
148
125
|
- [Architecture](docs/architecture.md)
|
|
149
126
|
- [Safety Model](docs/safety-model.md)
|
|
150
127
|
- [Hook Rule Model](docs/hook-rule-model.md)
|
|
151
|
-
- [DeepSeek Harness Integration](docs/dsh-integration.md)
|
|
152
128
|
- [Changelog](docs/CHANGELOG.md)
|
|
153
129
|
- [KooCLI official docs](https://support.huaweicloud.com/qs-hcli/hcli_02_003.html)
|
|
154
130
|
|
package/README.zh-CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
帮助 AI 编码助手安全、准确地使用华为云——一站式集成云知识、CLI 工具和安全护栏。
|
|
10
10
|
|
|
11
|
-
支持 OpenCode、Codex、码道(CodeArts Agent)、WorkBuddy
|
|
11
|
+
支持 OpenCode、Codex、码道(CodeArts Agent)、WorkBuddy。
|
|
12
12
|
|
|
13
13
|
## 前置条件
|
|
14
14
|
|
|
@@ -85,27 +85,6 @@ npx --yes huaweicloud-devkit uninstall --target workbuddy
|
|
|
85
85
|
|
|
86
86
|
> **更新机制**:`update` 按 agent 增量更新,只刷新必要文件、不动你的配置文件。`update --target all` 可一次更新所有已安装的 agent。
|
|
87
87
|
|
|
88
|
-
### DeepSeek Harness(DSH)
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
npx --yes huaweicloud-devkit install --target dsh
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
安装器会把 Skills 写入 `$DSH_HOME/skills`,把 MCP Server 和安全策略写入
|
|
95
|
-
`$DSH_HOME/huaweicloud-plugins`,并自动维护
|
|
96
|
-
`$DSH_HOME/profiles/web/cordis.patch.yml`。安装后**重启 DSH 会话**。
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
npx --yes huaweicloud-devkit doctor
|
|
100
|
-
npx --yes huaweicloud-devkit status --target dsh
|
|
101
|
-
npx --yes huaweicloud-devkit update --target dsh
|
|
102
|
-
npx --yes huaweicloud-devkit uninstall --target dsh
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
> DSH V1 通过 `@deepseek-ai/dsh-mcp-client` 复用现有 MCP Server。
|
|
106
|
-
> 如果安装器提示 DSH MCP 客户端未检测到,请按提示执行
|
|
107
|
-
> `npx @deepseek-ai/dsh plugin --profile web add @deepseek-ai/dsh-mcp-client`。
|
|
108
|
-
|
|
109
88
|
### 其他 Agent
|
|
110
89
|
|
|
111
90
|
支持 MCP 协议的 Agent,手动配置:
|
|
@@ -146,7 +125,6 @@ ECS、OBS、VPC、IAM、RDS、GaussDB、FunctionGraph、APIG、CCE、SMN/DMS、M
|
|
|
146
125
|
- [架构](docs/architecture.md)
|
|
147
126
|
- [安全模型](docs/safety-model.md)
|
|
148
127
|
- [Hook 规则模型](docs/hook-rule-model.md)
|
|
149
|
-
- [DeepSeek Harness 集成](docs/dsh-integration.md)
|
|
150
128
|
- [变更记录](docs/CHANGELOG.md)
|
|
151
129
|
- [KooCLI 官方文档](https://support.huaweicloud.com/qs-hcli/hcli_02_003.html)
|
|
152
130
|
|
package/bin/setup.cjs
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3-dev.0",
|
|
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": [
|
|
@@ -33,8 +33,6 @@
|
|
|
33
33
|
"codex",
|
|
34
34
|
"opencode",
|
|
35
35
|
"workbuddy",
|
|
36
|
-
"dsh",
|
|
37
|
-
"deepseek-harness",
|
|
38
36
|
"mcp",
|
|
39
37
|
"koocli",
|
|
40
38
|
"hcloud"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"mcpServers": "./.mcp.json",
|
|
21
21
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
22
22
|
"skills": "./skills/",
|
|
23
|
-
"version": "1.0.
|
|
23
|
+
"version": "1.0.3-dev.0",
|
|
24
24
|
"author": {
|
|
25
25
|
"name": "HuaweiCloud Mate",
|
|
26
26
|
"url": "https://github.com/huaweicloud"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3-dev.0",
|
|
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",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"mcpServers": "./.mcp.json",
|
|
21
21
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
22
22
|
"skills": "./skills/",
|
|
23
|
-
"version": "1.0.
|
|
23
|
+
"version": "1.0.3-dev.0",
|
|
24
24
|
"author": {
|
|
25
25
|
"name": "HuaweiCloud Mate",
|
|
26
26
|
"url": "https://github.com/huaweicloud"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.0",
|
|
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",
|
|
@@ -8,12 +8,6 @@ version: 1
|
|
|
8
8
|
|
|
9
9
|
**STOP - Do not answer from general knowledge.** Follow the procedure below.
|
|
10
10
|
|
|
11
|
-
## Routing Guard: Deploy vs Store
|
|
12
|
-
|
|
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.
|
|
15
|
-
- OBS is a storage service; it is not a general web-hosting default.
|
|
16
|
-
|
|
17
11
|
## Critical: OBS Command Syntax
|
|
18
12
|
|
|
19
13
|
KooCLI OBS uses **obsutil-style** commands, NOT API-style operations. Always run `hcloud OBS help` (no `--`) before constructing commands:
|
|
@@ -15,7 +15,6 @@ Domain expertise for Huawei Cloud Sandbox (DevStation) instances and workspace t
|
|
|
15
15
|
## Activation
|
|
16
16
|
|
|
17
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
|
-
- **Static website hosting — present options, sandbox first**: when the developer asks to deploy/host/publish a static website or web app without naming a target, do NOT silently pick a service. Present the target options in this order: ① 沙箱 (recommended — temporary runtime, instant preview URL) ② OBS 静态托管 (long-term static hosting/CDN) ③ ECS ④ CCE, then follow the developer's choice. Recommended prompt: "建议优先部署到沙箱(临时运行环境,可预览访问),也可选择 OBS 静态托管、ECS 或 CCE,你想部署到哪里?" If the developer has no preference, proceed with the sandbox.
|
|
19
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 应用,建议优先使用沙箱部署(临时运行环境,可预览访问),是否使用?"
|
|
20
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.
|
|
21
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.
|
|
@@ -49,9 +48,9 @@ Domain expertise for Huawei Cloud Sandbox (DevStation) instances and workspace t
|
|
|
49
48
|
|
|
50
49
|
Setup is a **plugin-side preflight** — the developer should be asked a question only once, when the agreement actually needs signing:
|
|
51
50
|
|
|
52
|
-
1. **Check user** (transparent): `huaweicloud_sandbox_check_user` — verify `
|
|
53
|
-
2. **Real-name verification** (only if `
|
|
54
|
-
3. **Sign agreement** (only if `
|
|
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
|
|
55
54
|
4. **Connect**: `huaweicloud_sandbox_connect` — returns `session_id`, `dev_stage_id`, `connection_id`, `connection_address`
|
|
56
55
|
5. **Inject credentials** (optional): `huaweicloud_sandbox_credentials` — enables cloud API access from sandbox
|
|
57
56
|
6. **Execute commands**: `huaweicloud_sandbox_exec_with_session` for interactive work
|
|
@@ -98,7 +97,7 @@ sleep 10 && cat /tmp/host.log
|
|
|
98
97
|
| Trap | Why |
|
|
99
98
|
|------|-----|
|
|
100
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 |
|
|
101
|
-
| Real-name required | `sandbox_connect` fails if `
|
|
100
|
+
| Real-name required | `sandbox_connect` fails if `realname_verified=false`; tell the developer once and stop, don't loop on connect |
|
|
102
101
|
| Never expose tunnel details | Do not mention "DevBridge"/"tunnel"/"devbridge" to the developer — say "正在生成访问地址..." and hand over only the URL |
|
|
103
102
|
| Login needs `--huaweicloud` | `devbridge auth login --access-key/--secret-key` without `--huaweicloud` falls back to interactive browser login, which fails in the sandbox |
|
|
104
103
|
| CLI PATH | The installer only writes `~/.bashrc`; run `export PATH=$PATH:$HOME/.huawei/bin` in the session before using `devbridge` |
|
|
@@ -22,10 +22,6 @@ Use this skill to turn vague developer intent into a precise Huawei Cloud capabi
|
|
|
22
22
|
8. Treat Terraform as a secondary V1 path for reviewed IaC, not the default.
|
|
23
23
|
9. When no built-in devkit skill matches, browse the community skill marketplace at https://github.com/huaweicloud/huaweicloud-skills. Fetch the index from https://raw.githubusercontent.com/huaweicloud/huaweicloud-skills/master/skills-index/index.json.
|
|
24
24
|
|
|
25
|
-
## Deployment Target Options
|
|
26
|
-
|
|
27
|
-
When the intent is to **deploy, host, or preview a web app or static website** and the developer has not named a target, do NOT default to OBS or any single service. Present the options and let the developer choose, recommending the sandbox first: ① huawei-sandbox (recommended — temporary runtime, instant preview URL) ② huawei-obs (long-term static hosting/CDN) ③ huawei-ecs ④ huawei-cce. Only follow an explicit target when the developer names one.
|
|
28
|
-
|
|
29
25
|
## Region Intent
|
|
30
26
|
|
|
31
27
|
- Extract region intent from the user's words before querying. Examples: Singapore -> `ap-southeast-3` first, Hong Kong -> `ap-southeast-2`, Beijing -> `cn-north-4`, Shanghai -> `cn-east-3`.
|
|
@@ -26,7 +26,7 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
26
26
|
|----|------|----------------|------------|
|
|
27
27
|
| select | Service Selection | which service, what should I use, compare, recommend | Read references/select.md | select
|
|
28
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
|
|
29
|
+
| storage | Storage Routing | store files, bucket, OBS, backup, disk, EVS, SFS | Handoff to huawei-obs or huawei-cbr |
|
|
30
30
|
| database | Database Routing | database, SQL, NoSQL, cache, RDS, GaussDB, DDS, DCS | Handoff to huawei-rds or huawei-gaussdb |
|
|
31
31
|
| network | Network Routing | VPC, subnet, security group, EIP, NAT, VPN | Handoff to huawei-vpc |
|
|
32
32
|
| serverless | Serverless Routing | function, Lambda, serverless, FunctionGraph, API gateway | Handoff to huawei-functiongraph or huawei-apig |
|
|
@@ -36,7 +36,7 @@ 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,
|
|
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
40
|
| sandbox | Sandbox Routing | sandbox, DevStation, workspace, terminal, preview, temporary runtime | Handoff to huawei-sandbox |
|
|
41
41
|
| cli | CLI and Auth Routing | install hcloud, configure KooCLI, AK/SK setup | Handoff to huaweicloud-cli-and-auth |
|
|
42
42
|
| safety | Safety Routing | is this safe, approve command, risk review | Handoff to huaweicloud-safety |
|
|
@@ -50,7 +50,7 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
50
50
|
|----------|----------------|-------|
|
|
51
51
|
| Web application hosting | ECS | huawei-ecs |
|
|
52
52
|
| Containerized microservices | CCE | huawei-cce |
|
|
53
|
-
| Static file storage / CDN
|
|
53
|
+
| Static file storage / CDN | OBS | huawei-obs |
|
|
54
54
|
| Relational database (MySQL/PG) | RDS | huawei-rds |
|
|
55
55
|
| Distributed SQL database | GaussDB | huawei-gaussdb |
|
|
56
56
|
| Document database (MongoDB API) | DDS | huawei-dds-dcs |
|
|
@@ -71,21 +71,6 @@ Do not rely on training data for facts. Huawei Cloud services, pricing, quotas,
|
|
|
71
71
|
| Temporary runtime / web app preview | Sandbox (DevStation) | huawei-sandbox |
|
|
72
72
|
| Getting started | Account setup | huaweicloud-cli-and-auth |
|
|
73
73
|
|
|
74
|
-
## Deployment Target Options
|
|
75
|
-
|
|
76
|
-
When the intent is to **deploy, host, or preview a web app or static website** (no explicit target named), NEVER default to a single service such as OBS. Ask the developer to choose a target and present the options in this order:
|
|
77
|
-
|
|
78
|
-
| # | Option | When to choose | Skill |
|
|
79
|
-
|---|--------|----------------|-------|
|
|
80
|
-
| 1 | **Sandbox (DevStation) — recommended** | Temporary runtime, quick preview, demo; instant public URL | huawei-sandbox |
|
|
81
|
-
| 2 | OBS static website hosting | Long-term static hosting / CDN, no backend | huawei-obs |
|
|
82
|
-
| 3 | ECS | Needs a server runtime (backend, custom server) | huawei-ecs |
|
|
83
|
-
| 4 | CCE | Containerized workloads, scaling | huawei-cce |
|
|
84
|
-
|
|
85
|
-
- Recommended prompt: "这个项目是 Web 应用/静态网站,建议优先部署到沙箱(临时运行环境,立即可预览)。也可选择 OBS 静态托管、ECS 或 CCE,你想部署到哪里?"
|
|
86
|
-
- If the developer explicitly names a target (e.g. "deploy to OBS"), follow that target and hand off to the corresponding service skill.
|
|
87
|
-
- If the developer has no preference, recommend the sandbox first.
|
|
88
|
-
|
|
89
74
|
## Capability Sources
|
|
90
75
|
|
|
91
76
|
- Huawei Cloud Skills: scenario workflows and recipes (check first)
|
|
@@ -3,7 +3,7 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
|
|
6
|
-
export const SUPPORTED_AGENT_TARGETS = ['opencode', 'codex', 'codex-desktop', 'codearts', 'workbuddy'
|
|
6
|
+
export const SUPPORTED_AGENT_TARGETS = ['opencode', 'codex', 'codex-desktop', 'codearts', 'workbuddy'];
|
|
7
7
|
|
|
8
8
|
function baseHome() {
|
|
9
9
|
return process.env.HUAWEICLOUD_HOME || homedir();
|
|
@@ -71,23 +71,6 @@ function workbuddyRegistered() {
|
|
|
71
71
|
return Boolean(cfg?.mcpServers?.['huaweicloud-devkit']);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
function dshRoot() {
|
|
75
|
-
return process.env.DSH_HOME || join(baseHome(), '.dsh');
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function dshRegistered() {
|
|
79
|
-
const patchPath = join(dshRoot(), 'profiles', 'web', 'cordis.patch.yml');
|
|
80
|
-
if (!existsSync(patchPath)) return false;
|
|
81
|
-
try {
|
|
82
|
-
const patch = readFileSync(patchPath, 'utf8');
|
|
83
|
-
return patch.includes('id: mcp-huaweicloud')
|
|
84
|
-
&& patch.includes("@deepseek-ai/dsh-mcp-client")
|
|
85
|
-
&& patch.includes('serverName: huaweicloud');
|
|
86
|
-
} catch {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
74
|
export function getAgentRegistrationStatuses(target = 'all') {
|
|
92
75
|
const requested = target === 'all' ? SUPPORTED_AGENT_TARGETS : [target];
|
|
93
76
|
const result = { target, agents: {} };
|
|
@@ -98,7 +81,6 @@ export function getAgentRegistrationStatuses(target = 'all') {
|
|
|
98
81
|
if (agent === 'codex') configured = codexCliRegistered();
|
|
99
82
|
if (agent === 'codearts') configured = codeartsRegistered();
|
|
100
83
|
if (agent === 'workbuddy') configured = workbuddyRegistered();
|
|
101
|
-
if (agent === 'dsh') configured = dshRegistered();
|
|
102
84
|
result.agents[agent] = { configured };
|
|
103
85
|
}
|
|
104
86
|
return result;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getCredentials } from './hwlink-api.mjs';
|
|
2
|
-
import { getProxyDispatcher } from '../proxy/proxy-agent.mjs';
|
|
3
2
|
|
|
4
3
|
const HDKIT_BASE_URL =
|
|
5
4
|
process.env.HDKITSERVICE_ENDPOINT ||
|
|
@@ -23,15 +22,12 @@ async function hdkitRequest(method, path, body, timeoutMs = 300000) {
|
|
|
23
22
|
|
|
24
23
|
let resp;
|
|
25
24
|
try {
|
|
26
|
-
|
|
27
|
-
const fetchOpts = {
|
|
25
|
+
resp = await fetch(url, {
|
|
28
26
|
method,
|
|
29
27
|
headers,
|
|
30
28
|
body: body ? JSON.stringify(body) : undefined,
|
|
31
29
|
signal: controller.signal,
|
|
32
|
-
};
|
|
33
|
-
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
34
|
-
resp = await fetch(url, fetchOpts);
|
|
30
|
+
});
|
|
35
31
|
} finally {
|
|
36
32
|
clearTimeout(timer);
|
|
37
33
|
}
|
|
@@ -50,7 +46,7 @@ async function hdkitRequest(method, path, body, timeoutMs = 300000) {
|
|
|
50
46
|
);
|
|
51
47
|
err.code = data.code;
|
|
52
48
|
err.status = resp.status;
|
|
53
|
-
err.traceId = data.
|
|
49
|
+
err.traceId = data.trace_id;
|
|
54
50
|
throw err;
|
|
55
51
|
}
|
|
56
52
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import { resolveCredentials } from '../auth/credentials.mjs';
|
|
3
|
-
import { getProxyDispatcher } from '../proxy/proxy-agent.mjs';
|
|
4
3
|
|
|
5
4
|
const BASE_URL = process.env.HWLINK_ENDPOINT || 'https://devstation.myhuaweicloud.com';
|
|
6
5
|
|
|
@@ -97,25 +96,17 @@ async function apiGet(path, query, ak, sk, securitytoken) {
|
|
|
97
96
|
const qs = sortedQs(query);
|
|
98
97
|
const fullPath = qs ? `${path}?${qs}` : path;
|
|
99
98
|
const headers = signRequest('GET', path, query, undefined, ak, sk, securitytoken);
|
|
100
|
-
const
|
|
101
|
-
const dispatcher = await getProxyDispatcher(url);
|
|
102
|
-
const fetchOpts = { headers };
|
|
103
|
-
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
104
|
-
const resp = await fetch(url, fetchOpts);
|
|
99
|
+
const resp = await fetch(`${BASE_URL}${fullPath}`, { headers });
|
|
105
100
|
return { status: resp.status, data: await resp.json() };
|
|
106
101
|
}
|
|
107
102
|
|
|
108
103
|
async function apiPost(path, body, ak, sk, securitytoken) {
|
|
109
104
|
const headers = signRequest('POST', path, {}, body, ak, sk, securitytoken);
|
|
110
|
-
const
|
|
111
|
-
const dispatcher = await getProxyDispatcher(url);
|
|
112
|
-
const fetchOpts = {
|
|
105
|
+
const resp = await fetch(`${BASE_URL}${path}`, {
|
|
113
106
|
method: 'POST',
|
|
114
107
|
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
115
108
|
body: JSON.stringify(body),
|
|
116
|
-
};
|
|
117
|
-
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
118
|
-
const resp = await fetch(url, fetchOpts);
|
|
109
|
+
});
|
|
119
110
|
return { status: resp.status, data: await resp.json() };
|
|
120
111
|
}
|
|
121
112
|
|
|
@@ -2,7 +2,6 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
4
|
import { createConnection, getCredentials } from './hwlink-api.mjs';
|
|
5
|
-
import { getWebSocketImpl } from '../proxy/proxy-agent.mjs';
|
|
6
5
|
|
|
7
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
7
|
export const WS_EXEC_INDEX_URL = pathToFileURL(join(__dirname, '..', 'ws-exec', 'index.js')).href;
|
|
@@ -56,15 +55,12 @@ async function getSession(workspaceId, username, timeoutMs) {
|
|
|
56
55
|
const { ak, sk, securitytoken } = getCredentials();
|
|
57
56
|
const { wsUrl, source } = await createConnection(workspaceId, ak, sk, securitytoken);
|
|
58
57
|
|
|
59
|
-
const WebSocketImpl = getWebSocketImpl(wsUrl);
|
|
60
|
-
|
|
61
58
|
const { connectHwlinkTerminalSession } = await import(WS_EXEC_INDEX_URL);
|
|
62
59
|
const session = await connectHwlinkTerminalSession({
|
|
63
60
|
url: wsUrl,
|
|
64
61
|
source,
|
|
65
62
|
username,
|
|
66
63
|
timeoutMs,
|
|
67
|
-
WebSocketImpl,
|
|
68
64
|
});
|
|
69
65
|
|
|
70
66
|
sessions.set(key, session);
|
|
@@ -75,8 +71,6 @@ export async function execOneShot(workspaceId, command, username, timeoutMs) {
|
|
|
75
71
|
const { ak, sk, securitytoken } = getCredentials();
|
|
76
72
|
const { wsUrl, source } = await createConnection(workspaceId, ak, sk, securitytoken);
|
|
77
73
|
|
|
78
|
-
const WebSocketImpl = getWebSocketImpl(wsUrl);
|
|
79
|
-
|
|
80
74
|
const { executeHwlinkCommand } = await import(WS_EXEC_INDEX_URL);
|
|
81
75
|
return await executeHwlinkCommand({
|
|
82
76
|
url: wsUrl,
|
|
@@ -84,7 +78,6 @@ export async function execOneShot(workspaceId, command, username, timeoutMs) {
|
|
|
84
78
|
username,
|
|
85
79
|
command,
|
|
86
80
|
timeoutMs,
|
|
87
|
-
WebSocketImpl,
|
|
88
81
|
});
|
|
89
82
|
}
|
|
90
83
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getProxyDispatcher } from './proxy/proxy-agent.mjs';
|
|
2
|
-
|
|
3
1
|
const INDEX_URL = 'https://gitcode.com/api/v5/repos/2501_91318609/skills-for-index/contents/skills-index/index.json?ref=main';
|
|
4
2
|
const CN_EN_MAP_URL = 'https://gitcode.com/api/v5/repos/2501_91318609/skills-for-index/contents/skills-index/cn-en-map.json?ref=main';
|
|
5
3
|
const HTTP_TIMEOUT_MS = 10000;
|
|
@@ -21,13 +19,10 @@ async function fetchJson(url, label = '') {
|
|
|
21
19
|
const controller = new AbortController();
|
|
22
20
|
const timer = setTimeout(() => controller.abort(), HTTP_TIMEOUT_MS);
|
|
23
21
|
try {
|
|
24
|
-
const
|
|
25
|
-
const fetchOpts = {
|
|
22
|
+
const resp = await fetch(url, {
|
|
26
23
|
headers: { 'User-Agent': 'huaweicloud-devkit/1.0' },
|
|
27
24
|
signal: controller.signal,
|
|
28
|
-
};
|
|
29
|
-
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
30
|
-
const resp = await fetch(url, fetchOpts);
|
|
25
|
+
});
|
|
31
26
|
const data = await resp.json();
|
|
32
27
|
if (data && data.encoding === 'base64' && data.content) {
|
|
33
28
|
const decoded = Buffer.from(data.content, 'base64').toString('utf8');
|