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.
@@ -25,13 +25,8 @@ function workbuddySkillsDir() {
25
25
  const home = homedir();
26
26
  return join(home, '.workbuddy', 'skills');
27
27
  }
28
- function dshSkillsDir() {
29
- const home = process.env.DSH_HOME || join(homedir(), '.dsh');
30
- return join(home, 'skills');
31
- }
32
28
  function resolveSkillsRoot() {
33
29
  if (existsSync(SKILLS_ROOT_DEV)) return SKILLS_ROOT_DEV;
34
- if (existsSync(dshSkillsDir())) return dshSkillsDir();
35
30
  if (existsSync(codeartsSkillsDir())) return codeartsSkillsDir();
36
31
  if (existsSync(opencodeSkillsDir())) return opencodeSkillsDir();
37
32
  if (existsSync(workbuddySkillsDir())) return workbuddySkillsDir();
@@ -300,7 +295,7 @@ export const TOOL_DEFINITIONS = [
300
295
  inputSchema: {
301
296
  type: 'object',
302
297
  properties: {
303
- target: { type: 'string', description: 'Agent target to check: opencode, codex, codex-desktop, codearts, workbuddy, dsh, or all (default).' },
298
+ target: { type: 'string', description: 'Agent target to check: opencode, codex, codex-desktop, codearts, workbuddy, or all (default).' },
304
299
  },
305
300
  },
306
301
  },
@@ -310,7 +305,7 @@ export const TOOL_DEFINITIONS = [
310
305
  inputSchema: {
311
306
  type: 'object',
312
307
  properties: {
313
- target: { type: 'string', description: 'Agent target to report after sync: opencode, codex, codex-desktop, codearts, workbuddy, dsh, or all (default).' },
308
+ target: { type: 'string', description: 'Agent target to report after sync: opencode, codex, codex-desktop, codearts, workbuddy, or all (default).' },
314
309
  },
315
310
  },
316
311
  },
@@ -341,7 +336,7 @@ export const TOOL_DEFINITIONS = [
341
336
  },
342
337
  {
343
338
  name: 'huaweicloud_sandbox_check_user',
344
- description: 'Check if the current user has completed real-name verification and signed the required agreements. Returns realnameVerified and agreementSigned status.',
339
+ description: 'Check if the current user has completed real-name verification and signed the required agreements. Returns realname_verified and agreement_signed status.',
345
340
  inputSchema: {
346
341
  type: 'object',
347
342
  properties: {},
@@ -349,7 +344,7 @@ export const TOOL_DEFINITIONS = [
349
344
  },
350
345
  {
351
346
  name: 'huaweicloud_sandbox_sign_agreement',
352
- description: 'Sign all unsigned or outdated agreements for the current user. Required before huaweicloud_sandbox_connect if check-user returns agreementSigned=false. CRITICAL: only call after the user explicitly consents to signing — never sign agreements on the user\'s behalf without their explicit request.',
347
+ description: 'Sign all unsigned or outdated agreements for the current user. Required before huaweicloud_sandbox_connect if check-user returns agreement_signed=false.',
353
348
  inputSchema: {
354
349
  type: 'object',
355
350
  properties: {},
@@ -714,29 +709,19 @@ function serviceCatalog(intent = '') {
714
709
  { keywords: ['cts', 'audit', 'trace', 'tracker'], skills: ['huawei-cts'], services: ['CTS'] },
715
710
  { keywords: ['cbr', 'backup', 'restore', 'vault', 'snapshot'], skills: ['huawei-cbr'], services: ['CBR'] },
716
711
  { keywords: ['deployment', 'deploy', 'ci/cd', 'pipeline', 'release'], skills: ['huawei-deployment'], services: ['CloudDeploy'] },
717
- { keywords: ['sandbox', 'devstation', 'workspace', 'terminal', 'preview', 'hwlink', 'website', 'web app', 'webapp', 'hosting', '网站', '网页', '静态'], skills: ['huawei-sandbox'], services: ['Sandbox', 'DevStation'] },
712
+ { keywords: ['sandbox', 'devstation', 'workspace', 'terminal', 'preview', 'hwlink'], skills: ['huawei-sandbox'], services: ['Sandbox', 'DevStation'] },
718
713
  { keywords: ['dds', 'dcs', 'mongodb', 'redis', 'memcached', 'cache', 'document db'], skills: ['huawei-dds-dcs'], services: ['DDS', 'DCS'] },
719
714
  ];
720
715
  const matched = [];
721
716
  const tokens = it.split(/[\s,./-]+/).filter((t) => t.length > 0);
722
- const cjk = /[\u4e00-\u9fff]/;
723
717
  for (const route of routeMap) {
724
- if (route.keywords.some((kw) => (kw.includes(' ') || cjk.test(kw)) ? it.includes(kw) : tokens.includes(kw))) {
718
+ if (route.keywords.some((kw) => tokens.includes(kw))) {
725
719
  matched.push(route);
726
720
  }
727
721
  }
728
722
  const recommendedSkills = [...new Set(matched.flatMap((r) => r.skills))];
729
723
  const recommendedServices = [...new Set(matched.flatMap((r) => r.services))].slice(0, 5);
730
724
 
731
- // Deployment intent (deploy/host/publish a web app or static website) must never
732
- // default to a storage/other service — recommend the sandbox first.
733
- const deploymentIntent = /deploy|host|hosting|publish|website|web app|preview|部署|托管|发布|网站|网页/.test(it);
734
- if (deploymentIntent && recommendedSkills.includes('huawei-sandbox')) {
735
- const idx = recommendedSkills.indexOf('huawei-sandbox');
736
- recommendedSkills.splice(idx, 1);
737
- recommendedSkills.unshift('huawei-sandbox');
738
- }
739
-
740
725
  return {
741
726
  intent,
742
727
  recommendedSkills: recommendedSkills.length ? recommendedSkills : ['Use huaweicloud-core to route intent.'],
@@ -1,155 +0,0 @@
1
- import { getProxyUrlForTarget } from './proxy-config.mjs';
2
-
3
- let cachedDispatcher = undefined;
4
- let cachedDispatcherProxyUrl = null;
5
-
6
- export async function getProxyDispatcher(targetUrl) {
7
- const proxyUrl = getProxyUrlForTarget(targetUrl);
8
- if (!proxyUrl) return undefined;
9
-
10
- if (cachedDispatcher && cachedDispatcherProxyUrl === proxyUrl) {
11
- return cachedDispatcher;
12
- }
13
-
14
- const { ProxyAgent } = await import('undici');
15
- cachedDispatcher = new ProxyAgent(proxyUrl);
16
- cachedDispatcherProxyUrl = proxyUrl;
17
- return cachedDispatcher;
18
- }
19
-
20
- export function clearProxyDispatcherCache() {
21
- cachedDispatcher = undefined;
22
- cachedDispatcherProxyUrl = null;
23
- }
24
-
25
- export async function createProxyWebSocket(url, protocols) {
26
- const proxyUrl = getProxyUrlForTarget(url);
27
- if (!proxyUrl) {
28
- return new globalThis.WebSocket(url, protocols);
29
- }
30
-
31
- const dispatcher = await getProxyDispatcher(url);
32
- const { WebSocket: UndiciWebSocket } = await import('undici');
33
-
34
- const wsOptions = { dispatcher };
35
- if (protocols) {
36
- if (Array.isArray(protocols)) {
37
- wsOptions.protocols = protocols;
38
- } else {
39
- wsOptions.protocols = [protocols];
40
- }
41
- }
42
-
43
- return new UndiciWebSocket(url, wsOptions);
44
- }
45
-
46
- export function getWebSocketImpl(targetUrl) {
47
- const proxyUrl = getProxyUrlForTarget(targetUrl);
48
- if (!proxyUrl) return globalThis.WebSocket;
49
-
50
- return (url, protocols) => {
51
- const proxyUrlForTarget = getProxyUrlForTarget(url);
52
- if (!proxyUrlForTarget) {
53
- return new globalThis.WebSocket(url, protocols);
54
- }
55
-
56
- const wsPromise = (async () => {
57
- const dispatcher = await getProxyDispatcher(url);
58
- const { WebSocket: UndiciWebSocket } = await import('undici');
59
-
60
- const wsOptions = { dispatcher };
61
- if (protocols) {
62
- if (Array.isArray(protocols)) {
63
- wsOptions.protocols = protocols;
64
- } else {
65
- wsOptions.protocols = [protocols];
66
- }
67
- }
68
-
69
- return new UndiciWebSocket(url, wsOptions);
70
- })();
71
-
72
- return createSyncProxyWebSocketWrapper(wsPromise);
73
- };
74
- }
75
-
76
- function createSyncProxyWebSocketWrapper(wsPromise) {
77
- const pendingEvents = [];
78
- const eventHandlers = new Map();
79
- let ws = null;
80
- let settled = false;
81
- let readyState = 0;
82
- let binaryType = 'arraybuffer';
83
-
84
- const wrapper = {
85
- get readyState() { return ws ? ws.readyState : readyState; },
86
- get url() { return ws ? ws.url : ''; },
87
- get protocol() { return ws ? ws.protocol : ''; },
88
- get binaryType() { return ws ? ws.binaryType : binaryType; },
89
- set binaryType(v) {
90
- binaryType = v;
91
- if (ws) ws.binaryType = v;
92
- },
93
-
94
- send(data, callback) {
95
- if (ws) {
96
- if (ws.send.length >= 2) return ws.send(data, callback);
97
- try { ws.send(data); if (callback) callback(null); } catch (e) { if (callback) callback(e); }
98
- return;
99
- }
100
- pendingEvents.push({ type: 'send', data, callback });
101
- },
102
-
103
- close(code, reason) {
104
- if (ws) { ws.close(code, reason); return; }
105
- readyState = 3;
106
- pendingEvents.push({ type: 'close', code, reason });
107
- },
108
-
109
- addEventListener(type, handler) {
110
- if (!eventHandlers.has(type)) eventHandlers.set(type, new Set());
111
- eventHandlers.get(type).add(handler);
112
- if (ws) ws.addEventListener(type, handler);
113
- },
114
-
115
- removeEventListener(type, handler) {
116
- const handlers = eventHandlers.get(type);
117
- if (handlers) handlers.delete(handler);
118
- if (ws) ws.removeEventListener(type, handler);
119
- },
120
-
121
- on(type, handler) { wrapper.addEventListener(type, handler); },
122
- off(type, handler) { wrapper.removeEventListener(type, handler); },
123
- };
124
-
125
- function flushPendingEvents() {
126
- for (const evt of pendingEvents) {
127
- if (evt.type === 'send') {
128
- if (ws.send.length >= 2) ws.send(evt.data, evt.callback);
129
- else { try { ws.send(evt.data); if (evt.callback) evt.callback(null); } catch (e) { if (evt.callback) evt.callback(e); } }
130
- } else if (evt.type === 'close') {
131
- ws.close(evt.code, evt.reason);
132
- }
133
- }
134
- pendingEvents.length = 0;
135
- }
136
-
137
- wsPromise.then((resolvedWs) => {
138
- ws = resolvedWs;
139
- if ('binaryType' in ws) ws.binaryType = binaryType;
140
- for (const [type, handlers] of eventHandlers) {
141
- for (const handler of handlers) {
142
- ws.addEventListener(type, handler);
143
- }
144
- }
145
- flushPendingEvents();
146
- }).catch((err) => {
147
- readyState = 3;
148
- const handlers = eventHandlers.get('error');
149
- if (handlers) for (const h of handlers) h(err instanceof Error ? err : new Error(String(err)));
150
- const closeHandlers = eventHandlers.get('close');
151
- if (closeHandlers) for (const h of closeHandlers) h({ code: 1006, reason: err.message || String(err) });
152
- });
153
-
154
- return wrapper;
155
- }
@@ -1,87 +0,0 @@
1
- import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
2
- import { dirname, join } from 'node:path';
3
- import { homedir } from 'node:os';
4
-
5
- function baseHome() {
6
- return process.env.HUAWEICLOUD_HOME || homedir();
7
- }
8
-
9
- export function proxyConfigPath() {
10
- return join(baseHome(), '.config', 'huaweicloud', 'proxy.json');
11
- }
12
-
13
- export function readProxyConfig() {
14
- const path = proxyConfigPath();
15
- if (!existsSync(path)) return null;
16
- try {
17
- return JSON.parse(readFileSync(path, 'utf8'));
18
- } catch {
19
- return null;
20
- }
21
- }
22
-
23
- export function writeProxyConfig(config = {}) {
24
- const path = proxyConfigPath();
25
- mkdirSync(dirname(path), { recursive: true });
26
- const payload = {
27
- https_proxy: String(config.https_proxy || ''),
28
- http_proxy: String(config.http_proxy || ''),
29
- no_proxy: String(config.no_proxy || ''),
30
- };
31
- writeFileSync(path, JSON.stringify(payload, null, 2), { encoding: 'utf8' });
32
- return path;
33
- }
34
-
35
- export function clearProxyConfig() {
36
- const path = proxyConfigPath();
37
- if (!existsSync(path)) return false;
38
- rmSync(path);
39
- return true;
40
- }
41
-
42
- function shouldBypassProxy(hostname, noProxyList) {
43
- if (!noProxyList.length) return false;
44
- const lower = hostname.toLowerCase();
45
- for (const pattern of noProxyList) {
46
- const p = pattern.trim().toLowerCase();
47
- if (!p) continue;
48
- if (p === lower) return true;
49
- if (p === '*') return true;
50
- if (p.startsWith('.') && lower.endsWith(p)) return true;
51
- if (lower.endsWith('.' + p)) return true;
52
- }
53
- return false;
54
- }
55
-
56
- export function getProxySettings(targetUrl) {
57
- const envHttps = process.env.HTTPS_PROXY || process.env.https_proxy || '';
58
- const envHttp = process.env.HTTP_PROXY || process.env.http_proxy || '';
59
- const envNoProxy = process.env.NO_PROXY || process.env.no_proxy || '';
60
-
61
- const fileConfig = readProxyConfig();
62
-
63
- const https_proxy = envHttps || (fileConfig?.https_proxy || '');
64
- const http_proxy = envHttp || (fileConfig?.http_proxy || '');
65
- const no_proxy = envNoProxy || (fileConfig?.no_proxy || '');
66
-
67
- if (!https_proxy && !http_proxy) return null;
68
-
69
- const noProxyList = no_proxy.split(',').map((s) => s.trim()).filter(Boolean);
70
-
71
- if (targetUrl) {
72
- const parsed = new URL(targetUrl);
73
- if (shouldBypassProxy(parsed.hostname, noProxyList)) return null;
74
- const isHttps = parsed.protocol === 'https:';
75
- const proxyUrl = isHttps ? https_proxy : http_proxy;
76
- if (!proxyUrl) return null;
77
- return { proxyUrl, noProxyList, targetProtocol: parsed.protocol };
78
- }
79
-
80
- return { https_proxy, http_proxy, no_proxy, noProxyList };
81
- }
82
-
83
- export function getProxyUrlForTarget(targetUrl) {
84
- const settings = getProxySettings(targetUrl);
85
- if (!settings) return null;
86
- return settings.proxyUrl || null;
87
- }