huaweicloud-devkit 1.1.0-next.0 → 1.1.0-next.2
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/.agents/plugins/marketplace.json +7 -7
- package/package.json +1 -1
- package/plugins/huaweicloud-core/.claude-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.codex-plugin/plugin.json +22 -19
- 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/assets/icon.png +0 -0
- package/plugins/huaweicloud-core/assets/logo-dark.png +0 -0
- package/plugins/huaweicloud-core/assets/logo.png +0 -0
- package/plugins/huaweicloud-core/openclaw.plugin.json +1 -1
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +148 -0
- package/plugins/huaweicloud-core/skills/huawei-sandbox/references/framework-commands.md +65 -0
- package/plugins/huaweicloud-core/skills/huawei-sandbox/references/nginx-templates.md +95 -0
- package/plugins/huaweicloud-core/src/auth/credentials.mjs +19 -6
- package/plugins/huaweicloud-core/src/detect-framework.mjs +344 -0
- package/plugins/huaweicloud-core/src/mcp-server.mjs +5 -0
- package/plugins/huaweicloud-core/src/sandbox/hdkitservice-api.mjs +18 -0
- package/plugins/huaweicloud-core/src/setup-cli.mjs +282 -100
- package/plugins/huaweicloud-core/src/tools.mjs +54 -1
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
},
|
|
6
6
|
"plugins": [
|
|
7
7
|
{
|
|
8
|
-
"name": "huaweicloud-devkit",
|
|
9
|
-
"source": {
|
|
10
|
-
"source": "local",
|
|
11
|
-
"path": "./plugins/huaweicloud-core"
|
|
12
|
-
},
|
|
13
8
|
"policy": {
|
|
14
|
-
"installation": "
|
|
9
|
+
"installation": "INSTALLED_BY_DEFAULT",
|
|
15
10
|
"authentication": "ON_USE"
|
|
16
11
|
},
|
|
17
|
-
"category": "Cloud"
|
|
12
|
+
"category": "Cloud",
|
|
13
|
+
"name": "huaweicloud-devkit",
|
|
14
|
+
"source": {
|
|
15
|
+
"path": "./plugins/huaweicloud-core",
|
|
16
|
+
"source": "local"
|
|
17
|
+
}
|
|
18
18
|
}
|
|
19
19
|
]
|
|
20
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.0-next.
|
|
3
|
+
"version": "1.1.0-next.2",
|
|
4
4
|
"description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"mcpServers": "./.mcp.json",
|
|
18
18
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
19
19
|
"skills": "./skills/",
|
|
20
|
-
"version": "1.1.0-next.
|
|
20
|
+
"version": "1.1.0-next.2",
|
|
21
21
|
"author": {
|
|
22
22
|
"name": "HuaweiCloud Mate",
|
|
23
23
|
"url": "https://github.com/huaweicloud"
|
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.0-next.0",
|
|
4
|
-
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "HuaweiCloud Mate",
|
|
7
|
-
"url": "https://github.com/huaweicloud"
|
|
8
|
-
},
|
|
9
|
-
"homepage": "https://github.com/huaweicloud/HuaweiCloud-Devkit",
|
|
10
|
-
"repository": "https://github.com/huaweicloud/HuaweiCloud-Devkit",
|
|
11
|
-
"license": "Apache-2.0",
|
|
12
|
-
"keywords": ["huaweicloud", "huawei-cloud", "koocli", "hcloud", "agent", "mcp", "api", "sdk", "skills"],
|
|
13
|
-
"skills": "./skills/",
|
|
14
|
-
"mcpServers": "./.mcp.json",
|
|
15
2
|
"interface": {
|
|
16
|
-
"displayName": "HuaweiCloud Devkit",
|
|
17
3
|
"shortDescription": "HuaweiCloud Devkit - Huawei Cloud guidance, CLI/API/SDK routing, MCP tools, and safety for coding agents.",
|
|
18
|
-
"longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
|
|
19
4
|
"developerName": "HuaweiCloud Mate",
|
|
20
|
-
"category": "Cloud",
|
|
21
5
|
"capabilities": ["Read", "Interactive"],
|
|
22
|
-
"websiteURL": "https://github.com/huaweicloud/HuaweiCloud-Devkit",
|
|
23
6
|
"brandColor": "#C7000B",
|
|
7
|
+
"composerIcon": "./assets/icon.png",
|
|
8
|
+
"logo": "./assets/logo.png",
|
|
9
|
+
"logoDark": "./assets/logo-dark.png",
|
|
10
|
+
"category": "Cloud",
|
|
24
11
|
"defaultPrompt": [
|
|
25
12
|
"Help me choose the right Huawei Cloud capability.",
|
|
26
13
|
"Check my Huawei Cloud CLI setup safely.",
|
|
27
14
|
"Plan this Huawei Cloud API or SDK task."
|
|
28
|
-
]
|
|
29
|
-
|
|
15
|
+
],
|
|
16
|
+
"longDescription": "HuaweiCloud Devkit helps coding agents choose and use Huawei Cloud Skills, KooCLI, APIs, SDKs, and MCP tools with less context, safer command execution, and more accurate cloud implementation decisions.",
|
|
17
|
+
"websiteURL": "https://github.com/huaweicloud/HuaweiCloud-Devkit",
|
|
18
|
+
"displayName": "HuaweiCloud Devkit"
|
|
19
|
+
},
|
|
20
|
+
"mcpServers": "./.mcp.json",
|
|
21
|
+
"description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
|
|
22
|
+
"skills": "./skills/",
|
|
23
|
+
"version": "1.1.0-next.2",
|
|
24
|
+
"author": {
|
|
25
|
+
"name": "HuaweiCloud Mate",
|
|
26
|
+
"url": "https://github.com/huaweicloud"
|
|
27
|
+
},
|
|
28
|
+
"name": "huaweicloud-devkit",
|
|
29
|
+
"homepage": "https://github.com/huaweicloud/HuaweiCloud-Devkit",
|
|
30
|
+
"repository": "https://github.com/huaweicloud/HuaweiCloud-Devkit",
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"keywords": ["huaweicloud", "huawei-cloud", "koocli", "hcloud", "agent", "mcp", "api", "sdk", "skills"]
|
|
30
33
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"mcpServers": "./.mcp.json",
|
|
18
18
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
19
19
|
"skills": "./skills/",
|
|
20
|
-
"version": "1.1.0-next.
|
|
20
|
+
"version": "1.1.0-next.2",
|
|
21
21
|
"author": {
|
|
22
22
|
"name": "HuaweiCloud Mate",
|
|
23
23
|
"url": "https://github.com/huaweicloud"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.0-next.
|
|
3
|
+
"version": "1.1.0-next.2",
|
|
4
4
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "HuaweiCloud Mate",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.0-next.
|
|
3
|
+
"version": "1.1.0-next.2",
|
|
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",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
3
|
"id": "huaweicloud-devkit",
|
|
4
4
|
"displayName": "HuaweiCloud DevKit",
|
|
5
|
-
"version": "1.1.0-next.
|
|
5
|
+
"version": "1.1.0-next.2",
|
|
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.",
|
|
@@ -31,6 +31,12 @@ Domain expertise for Huawei Cloud Sandbox (DevStation) instances and workspace t
|
|
|
31
31
|
| `huaweicloud_sandbox_check_user` | Check real-name verification and agreement signing status |
|
|
32
32
|
| `huaweicloud_sandbox_sign_agreement` | Sign unsigned/outdated agreements (required before connect) |
|
|
33
33
|
|
|
34
|
+
### Local Detection
|
|
35
|
+
|
|
36
|
+
| Tool | Purpose |
|
|
37
|
+
| ------------------------------ | ---------------------------------------------------------- |
|
|
38
|
+
| `huaweicloud_detect_framework` | Scan local project, return framework type + build commands |
|
|
39
|
+
|
|
34
40
|
### Sandbox Lifecycle
|
|
35
41
|
|
|
36
42
|
| Tool | Purpose |
|
|
@@ -175,6 +181,148 @@ sleep 10 && cat /tmp/host.log
|
|
|
175
181
|
|
|
176
182
|
**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.
|
|
177
183
|
|
|
184
|
+
## Web Application Deployment
|
|
185
|
+
|
|
186
|
+
When deploying a web application to the sandbox, build the app inside the sandbox before exposing it. Source code is uploaded, dependencies installed, and the framework built in the sandbox environment.
|
|
187
|
+
|
|
188
|
+
### Step 1: Detect Framework Locally
|
|
189
|
+
|
|
190
|
+
**Always call `huaweicloud_detect_framework` first** before connecting to the sandbox. It scans the local project and returns:
|
|
191
|
+
|
|
192
|
+
- `type`: `spa` | `ssr` | `ssg` | `cross-platform` | `monorepo` | `static`
|
|
193
|
+
- `framework`: framework name
|
|
194
|
+
- `packageManager`: `npm` | `yarn` | `pnpm`
|
|
195
|
+
- `installCmd` / `buildCmd` / `outputDir` / `port`
|
|
196
|
+
- For SSR: also `serveCmd` and `checkUrl`
|
|
197
|
+
- For nginx: `nginxType` (`spa` | `proxy` | `static`)
|
|
198
|
+
- For Monorepo: `subApps` list with individual framework detection
|
|
199
|
+
|
|
200
|
+
If detection returns `null`, the project is not a recognized web app. Stop and tell the developer.
|
|
201
|
+
|
|
202
|
+
If detection returns `type: "monorepo"`, show the `subApps` list to the developer and ask which sub-app to deploy. Then re-detect that sub-app's framework.
|
|
203
|
+
|
|
204
|
+
### Step 2: Connect and Upload
|
|
205
|
+
|
|
206
|
+
Follow the standard [Workflow](#workflow) steps 1-6 to connect to the sandbox, then:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"local_dir": "<projectPath>",
|
|
211
|
+
"remote_dir": "/workspace"
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The project will be extracted to `/workspace/<dirname>/`.
|
|
216
|
+
|
|
217
|
+
### Step 3: Sandbox Environment Readiness
|
|
218
|
+
|
|
219
|
+
Before installing project dependencies, verify the sandbox has the required runtime tools. Run this pre-flight check via `exec_one_shot`:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# Core tools (expected pre-installed in sandbox image)
|
|
223
|
+
echo "=== Checking core tools ==="
|
|
224
|
+
command -v node && node --version || echo "MISSING: node"
|
|
225
|
+
command -v npm && npm --version || echo "MISSING: npm"
|
|
226
|
+
command -v nginx && nginx -v 2>&1 || echo "MISSING: nginx"
|
|
227
|
+
command -v git && git --version || echo "MISSING: git"
|
|
228
|
+
command -v python3 && python3 --version || echo "MISSING: python3"
|
|
229
|
+
command -v curl && curl --version | head -1 || echo "MISSING: curl"
|
|
230
|
+
command -v wget && wget --version | head -1 || echo "MISSING: wget"
|
|
231
|
+
dpkg -l build-essential >/dev/null 2>&1 && echo "build-essential: found" || echo "MISSING: build-essential"
|
|
232
|
+
command -v lsof && lsof -v 2>&1 | head -1 || echo "MISSING: lsof"
|
|
233
|
+
command -v netstat && netstat --version 2>&1 | head -1 || echo "MISSING: net-tools"
|
|
234
|
+
command -v make && make --version | head -1 || echo "MISSING: make"
|
|
235
|
+
|
|
236
|
+
# Framework-specific tools (install on demand)
|
|
237
|
+
echo "=== Checking framework tools ==="
|
|
238
|
+
command -v pnpm && pnpm --version || echo "MISSING: pnpm"
|
|
239
|
+
command -v yarn && yarn --version || echo "MISSING: yarn"
|
|
240
|
+
command -v hugo && hugo version || echo "MISSING: hugo"
|
|
241
|
+
command -v devbridge && devbridge version || echo "MISSING: devbridge"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Install only missing tools** — parse the pre-flight output and install only tools reported as `MISSING`. Skip tools already present:
|
|
245
|
+
|
|
246
|
+
| Missing Tool | Install Command |
|
|
247
|
+
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
248
|
+
| Node.js | Follow [Node.js in the sandbox](#nodejs-in-the-sandbox) |
|
|
249
|
+
| nginx | `sudo apt-get update -qq && sudo apt-get install -y -qq nginx` |
|
|
250
|
+
| curl | `sudo apt-get update -qq && sudo apt-get install -y -qq curl` |
|
|
251
|
+
| wget | `sudo apt-get update -qq && sudo apt-get install -y -qq wget` |
|
|
252
|
+
| build-essential | `sudo apt-get update -qq && sudo apt-get install -y -qq build-essential` |
|
|
253
|
+
| lsof | `sudo apt-get update -qq && sudo apt-get install -y -qq lsof` |
|
|
254
|
+
| net-tools | `sudo apt-get update -qq && sudo apt-get install -y -qq net-tools` |
|
|
255
|
+
| make | `sudo apt-get update -qq && sudo apt-get install -y -qq make` |
|
|
256
|
+
| pnpm | `npm i -g pnpm` |
|
|
257
|
+
| yarn | `npm i -g yarn` |
|
|
258
|
+
| Hugo | `curl -fsSL https://github.com/gohugoio/hugo/releases/download/v0.140.0/hugo_extended_0.140.0_linux-amd64.tar.gz -o /tmp/hugo.tar.gz && sudo tar -xzf /tmp/hugo.tar.gz -C /usr/local/bin hugo && rm /tmp/hugo.tar.gz` |
|
|
259
|
+
| DevBridge | `curl -fsSL https://res-hd.hc-cdn.cn/sharedata/hdspace/devbridge/install.sh \| bash && export PATH=$PATH:$HOME/.huawei/bin` |
|
|
260
|
+
|
|
261
|
+
**If nginx cannot be installed**, skip to Python HTTP server fallback (see `references/nginx-templates.md`).
|
|
262
|
+
|
|
263
|
+
**If Node.js is missing**, install it first — all build workflows depend on it. Stop and report to the developer if Node.js installation fails.
|
|
264
|
+
|
|
265
|
+
### Step 4: Install and Build
|
|
266
|
+
|
|
267
|
+
Use `exec_one_shot` for the build pipeline (long-running, more stable).
|
|
268
|
+
|
|
269
|
+
**Install dependencies** — skip if `node_modules` already exists:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
cd /workspace/<dirname> && [ -d node_modules ] && echo "SKIP: node_modules exists" || <installCmd>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Wait for install to complete, then:
|
|
276
|
+
|
|
277
|
+
**Build** — only if build output doesn't already exist:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
cd /workspace/<dirname> && [ -d <outputDir> ] && echo "SKIP: <outputDir> exists" || <buildCmd>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- `cd /workspace/<dirname>/<subAppPath>` for Monorepo sub-apps.
|
|
284
|
+
- For `pnpm` projects, `node_modules` may be at the workspace root. Check both the sub-app dir and the workspace root.
|
|
285
|
+
- For Hugo/static sites where `installCmd` is `null`, skip install entirely.
|
|
286
|
+
- For static sites where `buildCmd` is `null`, skip build entirely.
|
|
287
|
+
|
|
288
|
+
**Real-time logging**: each `exec_one_shot` call returns stdout. Show build progress to the developer as it arrives.
|
|
289
|
+
|
|
290
|
+
**Timeout**: for large projects, set `timeout_ms` to 300000 (5 min) or higher.
|
|
291
|
+
|
|
292
|
+
### Step 5: Configure Nginx
|
|
293
|
+
|
|
294
|
+
Check `references/nginx-templates.md` for the correct template based on `nginxType`:
|
|
295
|
+
|
|
296
|
+
| nginxType | Template | When |
|
|
297
|
+
| --------- | ----------------------- | --------------------------- |
|
|
298
|
+
| `spa` | Template 1 (try_files) | SPA, SSG, cross-platform H5 |
|
|
299
|
+
| `proxy` | Template 2 (proxy_pass) | SSR (Next.js, Nuxt) |
|
|
300
|
+
| `static` | Template 3 (plain root) | Hugo, Hexo, static sites |
|
|
301
|
+
|
|
302
|
+
Replace `<port>`, `<project>`, `<outputDir>` (and `<nodePort>`/`<publicPort>` for SSR) with detected values.
|
|
303
|
+
|
|
304
|
+
Write the config with `sudo tee`, then reload nginx. If nginx fails, fall back to Python HTTP server (see `references/nginx-templates.md`).
|
|
305
|
+
|
|
306
|
+
### Step 6: Start the App
|
|
307
|
+
|
|
308
|
+
- **Static (SPA/SSG/cross-platform)**: nginx is already serving. Skip.
|
|
309
|
+
- **SSR**: run `<serveCmd>` via `exec_with_session` to start the Node process in background.
|
|
310
|
+
|
|
311
|
+
### Step 7: Expose via DevBridge
|
|
312
|
+
|
|
313
|
+
Follow the standard [Expose the deployed app](#expose-the-deployed-app-public-url) procedure. The app is already running on the detected port — only DevBridge tunnel setup is needed.
|
|
314
|
+
|
|
315
|
+
Use `exec_with_session` to background DevBridge. For SSR, DevBridge tunnels the nginx public port (not the Node port directly).
|
|
316
|
+
|
|
317
|
+
### Step 8: Return URL
|
|
318
|
+
|
|
319
|
+
Extract the tunnel URL from DevBridge output and return it to the developer. For cross-platform H5 apps, also mention QR code scanning on mobile.
|
|
320
|
+
|
|
321
|
+
## References
|
|
322
|
+
|
|
323
|
+
- [Framework Commands](references/framework-commands.md) — command mapping for all supported frameworks
|
|
324
|
+
- [Nginx Templates](references/nginx-templates.md) — nginx configuration templates and fallback
|
|
325
|
+
|
|
178
326
|
## Critical Warnings
|
|
179
327
|
|
|
180
328
|
| Trap | Why |
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Framework Command Mapping
|
|
2
|
+
|
|
3
|
+
Maps web frameworks to install, build, serve commands and output directories for sandbox deployment.
|
|
4
|
+
|
|
5
|
+
## SSR Frameworks
|
|
6
|
+
|
|
7
|
+
| Framework | Install | Build | Serve | Output Dir | Port | Nginx |
|
|
8
|
+
| --------- | ------------- | --------------- | ----------------------------------------------------------- | ---------- | ---- | ----- |
|
|
9
|
+
| Next.js | `npm install` | `npm run build` | `nohup npm start > /tmp/app.log 2>&1 &` | `.next` | 3000 | proxy |
|
|
10
|
+
| Nuxt | `npm install` | `npm run build` | `nohup node .output/server/index.mjs > /tmp/app.log 2>&1 &` | `.output` | 3000 | proxy |
|
|
11
|
+
|
|
12
|
+
## Static Site Generators (SSG)
|
|
13
|
+
|
|
14
|
+
| Framework | Install | Build | Serve | Output Dir | Port | Nginx |
|
|
15
|
+
| ---------- | ----------------- | -------------------- | ------------ | ----------------- | ---- | ------ |
|
|
16
|
+
| VitePress | `npm install` | `npm run docs:build` | nginx static | `.vitepress/dist` | 8080 | spa |
|
|
17
|
+
| Docusaurus | `npm install` | `npm run build` | nginx static | `build` | 8080 | spa |
|
|
18
|
+
| Hugo | (download binary) | `hugo` | nginx static | `public` | 8080 | static |
|
|
19
|
+
| Hexo | `npm install` | `npm run build` | nginx static | `public` | 8080 | static |
|
|
20
|
+
|
|
21
|
+
## SPA Frameworks
|
|
22
|
+
|
|
23
|
+
| Framework | Install | Build | Serve | Output Dir | Port | Nginx |
|
|
24
|
+
| ----------------------------- | ------------- | --------------- | --------- | ---------------- | ---- | ----- |
|
|
25
|
+
| Vite (React/Vue/Svelte/Solid) | `npm install` | `npm run build` | nginx SPA | `dist` | 8080 | spa |
|
|
26
|
+
| Create React App | `npm install` | `npm run build` | nginx SPA | `build` | 8080 | spa |
|
|
27
|
+
| Vue CLI | `npm install` | `npm run build` | nginx SPA | `dist` | 8080 | spa |
|
|
28
|
+
| Angular | `npm install` | `npm run build` | nginx SPA | `dist/<project>` | 8080 | spa |
|
|
29
|
+
|
|
30
|
+
## Cross-Platform Frameworks (H5)
|
|
31
|
+
|
|
32
|
+
| Framework | Install | Build | Serve | Output Dir | Port | Nginx |
|
|
33
|
+
| --------- | ------------- | ------------------ | --------- | --------------- | ---- | ----- |
|
|
34
|
+
| Taro | `npm install` | `npm run build:h5` | nginx SPA | `dist` | 8080 | spa |
|
|
35
|
+
| uni-app | `npm install` | `npm run build:h5` | nginx SPA | `dist/build/h5` | 8080 | spa |
|
|
36
|
+
|
|
37
|
+
## Runtime Dependencies
|
|
38
|
+
|
|
39
|
+
### Sandbox Pre-installed (expected)
|
|
40
|
+
|
|
41
|
+
These tools should be available in the sandbox image. Verify with the pre-flight check in SKILL.md Step 3.
|
|
42
|
+
|
|
43
|
+
| Tool | Min Version | Purpose |
|
|
44
|
+
| --------------- | ----------- | ----------------------------- |
|
|
45
|
+
| Node.js | 22.x | All npm-based workflows |
|
|
46
|
+
| npm | 10.x | Package manager (fallback) |
|
|
47
|
+
| nginx | 1.26.x | Primary static/SSR serving |
|
|
48
|
+
| python3 | 3.12+ | HTTP server fallback |
|
|
49
|
+
| git | 2.45.x | Code checkout |
|
|
50
|
+
| curl | 8.x | Tool downloads, health checks |
|
|
51
|
+
| build-essential | - | Native module compilation |
|
|
52
|
+
| pnpm | 10.x | Monorepo / workspace installs |
|
|
53
|
+
| lsof | 4.95.x | Port conflict detection |
|
|
54
|
+
|
|
55
|
+
### Install on Demand
|
|
56
|
+
|
|
57
|
+
Tools that may need installation in the sandbox before building:
|
|
58
|
+
|
|
59
|
+
| Tool | Trigger | Install Command |
|
|
60
|
+
| --------- | ------------------------------------ | ------------------------------------------------------------------------------------ |
|
|
61
|
+
| yarn | `yarn.lock` detected | `npm i -g yarn` |
|
|
62
|
+
| Hugo | `hugo.toml` / `config.toml` detected | Download Hugo extended binary (see below) |
|
|
63
|
+
| DevBridge | Tunnel exposure step | `curl -fsSL https://res-hd.hc-cdn.cn/sharedata/hdspace/devbridge/install.sh \| bash` |
|
|
64
|
+
|
|
65
|
+
> Hugo download: `curl -fsSL https://github.com/gohugoio/hugo/releases/download/v0.140.0/hugo_extended_0.140.0_linux-amd64.tar.gz -o /tmp/hugo.tar.gz && sudo tar -xzf /tmp/hugo.tar.gz -C /usr/local/bin hugo && rm /tmp/hugo.tar.gz`
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Nginx Configuration Templates
|
|
2
|
+
|
|
3
|
+
Nginx is the primary serving mechanism for web apps deployed to the sandbox. Python `http.server` is a fallback when nginx is unavailable.
|
|
4
|
+
|
|
5
|
+
## Nginx Setup (sandbox)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
sudo apt-get update -qq && sudo apt-get install -y -qq nginx 2>/dev/null || true
|
|
9
|
+
sudo mkdir -p /etc/nginx/sites-enabled
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Template 1: SPA (with try_files fallback)
|
|
13
|
+
|
|
14
|
+
Use for: Vite, CRA, Vue CLI, Angular, VitePress, Docusaurus, Taro H5, uni-app H5
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
sudo tee /etc/nginx/sites-enabled/app.conf > /dev/null << 'NGINX_EOF'
|
|
18
|
+
server {
|
|
19
|
+
listen <port>;
|
|
20
|
+
root /workspace/<project>/<outputDir>;
|
|
21
|
+
index index.html;
|
|
22
|
+
|
|
23
|
+
location / {
|
|
24
|
+
try_files $uri $uri/ /index.html;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
28
|
+
expires 1h;
|
|
29
|
+
add_header Cache-Control "public, immutable";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
NGINX_EOF
|
|
33
|
+
sudo nginx -s reload 2>/dev/null || sudo nginx
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Template 2: SSR Reverse Proxy
|
|
37
|
+
|
|
38
|
+
Use for: Next.js, Nuxt
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
sudo tee /etc/nginx/sites-enabled/app.conf > /dev/null << 'NGINX_EOF'
|
|
42
|
+
server {
|
|
43
|
+
listen <publicPort>;
|
|
44
|
+
server_name _;
|
|
45
|
+
|
|
46
|
+
location / {
|
|
47
|
+
proxy_pass http://127.0.0.1:<nodePort>;
|
|
48
|
+
proxy_http_version 1.1;
|
|
49
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
50
|
+
proxy_set_header Connection 'upgrade';
|
|
51
|
+
proxy_set_header Host $host;
|
|
52
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
53
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
54
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
55
|
+
proxy_cache_bypass $http_upgrade;
|
|
56
|
+
proxy_read_timeout 60s;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
NGINX_EOF
|
|
60
|
+
sudo nginx -s reload 2>/dev/null || sudo nginx
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Template 3: Static Site (no SPA routing)
|
|
64
|
+
|
|
65
|
+
Use for: Hugo, Hexo, plain static HTML
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
sudo tee /etc/nginx/sites-enabled/app.conf > /dev/null << 'NGINX_EOF'
|
|
69
|
+
server {
|
|
70
|
+
listen <port>;
|
|
71
|
+
root /workspace/<project>/<outputDir>;
|
|
72
|
+
index index.html;
|
|
73
|
+
|
|
74
|
+
location / {
|
|
75
|
+
autoindex off;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
79
|
+
expires 1h;
|
|
80
|
+
add_header Cache-Control "public, immutable";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
NGINX_EOF
|
|
84
|
+
sudo nginx -s reload 2>/dev/null || sudo nginx
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Fallback: Python HTTP Server
|
|
88
|
+
|
|
89
|
+
When nginx fails to install or start:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
cd /workspace/<project>/<outputDir> && nohup python3 -m http.server <port> > /tmp/http.log 2>&1 &
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> This does **not** support SPA client-side routing. Use only for static sites or when nginx is truly unavailable.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, readlinkSync, statSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
|
|
@@ -109,17 +109,30 @@ export function resolveCredentials(options = {}) {
|
|
|
109
109
|
return { ak, sk, securityToken, region };
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
let _parentCwd = undefined;
|
|
113
|
+
|
|
114
|
+
export function getParentCwd() {
|
|
115
|
+
if (_parentCwd !== undefined) return _parentCwd;
|
|
116
|
+
try {
|
|
117
|
+
_parentCwd = readlinkSync(`/proc/${process.ppid}/cwd`);
|
|
118
|
+
return _parentCwd;
|
|
119
|
+
} catch {
|
|
120
|
+
_parentCwd = null;
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
112
125
|
function isCodeArtsContext() {
|
|
113
126
|
return existsSync(join(process.cwd(), '.codeartsdoer')) || existsSync(join(homedir(), '.codeartsdoer'));
|
|
114
127
|
}
|
|
115
128
|
|
|
116
129
|
function readCodeArtsCredentials() {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
join(homedir(), '.codeartsdoer', 'mcp', 'mcp_settings.json'),
|
|
120
|
-
];
|
|
130
|
+
const parentCwd = getParentCwd();
|
|
131
|
+
const searchDirs = [process.env.CODEARTS_PROJECT_DIR, parentCwd, process.cwd(), homedir()];
|
|
121
132
|
|
|
122
|
-
for (const
|
|
133
|
+
for (const dir of searchDirs) {
|
|
134
|
+
if (!dir) continue;
|
|
135
|
+
const path = join(dir, '.codeartsdoer', 'mcp', 'mcp_settings.json');
|
|
123
136
|
try {
|
|
124
137
|
if (!existsSync(path)) continue;
|
|
125
138
|
const config = JSON.parse(readFileSync(path, 'utf8'));
|