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.
@@ -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": "AVAILABLE",
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.0",
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.0",
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.0",
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.0",
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.0",
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",
@@ -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.0",
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 searchPaths = [
118
- join(process.cwd(), '.codeartsdoer', 'mcp', 'mcp_settings.json'),
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 path of searchPaths) {
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'));