huaweicloud-devkit 1.0.2-dev.1 → 1.0.2-dev.12
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 +27 -3
- package/README.zh-CN.md +27 -3
- package/bin/setup.cjs +0 -0
- package/package.json +1 -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 +2 -1
- 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-ecs/SKILL.md +1 -1
- 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 +6 -0
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +135 -0
- package/plugins/huaweicloud-core/skills/huaweicloud-capability-discovery/SKILL.md +4 -0
- package/plugins/huaweicloud-core/skills/huaweicloud-cli-and-auth/SKILL.md +2 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-core/SKILL.md +20 -3
- 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/proxy/proxy-agent.mjs +155 -0
- package/plugins/huaweicloud-core/src/proxy/proxy-config.mjs +87 -0
- package/plugins/huaweicloud-core/src/sandbox/hdkitservice-api.mjs +91 -0
- package/plugins/huaweicloud-core/src/sandbox/hwlink-api.mjs +162 -0
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +112 -0
- package/plugins/huaweicloud-core/src/search-market.mjs +7 -2
- package/plugins/huaweicloud-core/src/setup-cli.mjs +662 -71
- package/plugins/huaweicloud-core/src/tools.mjs +170 -4
- 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
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
+
import { createConnection, getCredentials } from './hwlink-api.mjs';
|
|
5
|
+
import { getWebSocketImpl } from '../proxy/proxy-agent.mjs';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
export const WS_EXEC_INDEX_URL = pathToFileURL(join(__dirname, '..', 'ws-exec', 'index.js')).href;
|
|
9
|
+
|
|
10
|
+
const DEFAULT_WORKSPACE_ID = process.env.HW_WORKSPACE_ID || '0107bd9997aa4287bd2b4890b49af07d';
|
|
11
|
+
|
|
12
|
+
function resolveEnv() {
|
|
13
|
+
const env = { ...process.env };
|
|
14
|
+
env.PATH = `${env.HOME || '/root'}/.huawei/bin:${env.PATH || ''}`;
|
|
15
|
+
return env;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function runNodeExec(args, timeoutMs = 30000) {
|
|
19
|
+
const env = resolveEnv();
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
const proc = spawn('node', args, { env, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
22
|
+
let stdout = '';
|
|
23
|
+
let stderr = '';
|
|
24
|
+
proc.stdout.on('data', (d) => { stdout += d.toString(); });
|
|
25
|
+
proc.stderr.on('data', (d) => { stderr += d.toString(); });
|
|
26
|
+
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
proc.kill();
|
|
29
|
+
resolve({ error: 'timed out', exitCode: 124 });
|
|
30
|
+
}, timeoutMs);
|
|
31
|
+
|
|
32
|
+
proc.on('close', (code) => {
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
const out = stdout.trim();
|
|
35
|
+
if (out) {
|
|
36
|
+
try {
|
|
37
|
+
resolve({ ...JSON.parse(out), exitCode: code || 0 });
|
|
38
|
+
return;
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
if (code && code !== 0 && !out) {
|
|
42
|
+
resolve({ error: stderr.trim() || `exit code ${code}`, exitCode: code });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
resolve({ data: out, exitCode: code || 0 });
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const sessions = new Map();
|
|
51
|
+
|
|
52
|
+
async function getSession(workspaceId, username, timeoutMs) {
|
|
53
|
+
const key = `${workspaceId}:${username}`;
|
|
54
|
+
if (sessions.has(key)) return sessions.get(key);
|
|
55
|
+
|
|
56
|
+
const { ak, sk, securitytoken } = getCredentials();
|
|
57
|
+
const { wsUrl, source } = await createConnection(workspaceId, ak, sk, securitytoken);
|
|
58
|
+
|
|
59
|
+
const WebSocketImpl = getWebSocketImpl(wsUrl);
|
|
60
|
+
|
|
61
|
+
const { connectHwlinkTerminalSession } = await import(WS_EXEC_INDEX_URL);
|
|
62
|
+
const session = await connectHwlinkTerminalSession({
|
|
63
|
+
url: wsUrl,
|
|
64
|
+
source,
|
|
65
|
+
username,
|
|
66
|
+
timeoutMs,
|
|
67
|
+
WebSocketImpl,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
sessions.set(key, session);
|
|
71
|
+
return session;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function execOneShot(workspaceId, command, username, timeoutMs) {
|
|
75
|
+
const { ak, sk, securitytoken } = getCredentials();
|
|
76
|
+
const { wsUrl, source } = await createConnection(workspaceId, ak, sk, securitytoken);
|
|
77
|
+
|
|
78
|
+
const WebSocketImpl = getWebSocketImpl(wsUrl);
|
|
79
|
+
|
|
80
|
+
const { executeHwlinkCommand } = await import(WS_EXEC_INDEX_URL);
|
|
81
|
+
return await executeHwlinkCommand({
|
|
82
|
+
url: wsUrl,
|
|
83
|
+
source,
|
|
84
|
+
username,
|
|
85
|
+
command,
|
|
86
|
+
timeoutMs,
|
|
87
|
+
WebSocketImpl,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function execWithSession(workspaceId, command, username, timeoutMs) {
|
|
92
|
+
const session = await getSession(workspaceId, username, timeoutMs);
|
|
93
|
+
return await session.exec(command, { timeoutMs });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function closeSession(workspaceId, username) {
|
|
97
|
+
const key = `${workspaceId}:${username}`;
|
|
98
|
+
const session = sessions.get(key);
|
|
99
|
+
if (!session) return false;
|
|
100
|
+
sessions.delete(key);
|
|
101
|
+
try { session.close(); } catch {}
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function closeAllSessions() {
|
|
106
|
+
for (const [key, session] of sessions) {
|
|
107
|
+
sessions.delete(key);
|
|
108
|
+
try { session.close(); } catch {}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { DEFAULT_WORKSPACE_ID, runNodeExec };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getProxyDispatcher } from './proxy/proxy-agent.mjs';
|
|
2
|
+
|
|
1
3
|
const INDEX_URL = 'https://gitcode.com/api/v5/repos/2501_91318609/skills-for-index/contents/skills-index/index.json?ref=main';
|
|
2
4
|
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';
|
|
3
5
|
const HTTP_TIMEOUT_MS = 10000;
|
|
@@ -19,10 +21,13 @@ async function fetchJson(url, label = '') {
|
|
|
19
21
|
const controller = new AbortController();
|
|
20
22
|
const timer = setTimeout(() => controller.abort(), HTTP_TIMEOUT_MS);
|
|
21
23
|
try {
|
|
22
|
-
const
|
|
24
|
+
const dispatcher = await getProxyDispatcher(url);
|
|
25
|
+
const fetchOpts = {
|
|
23
26
|
headers: { 'User-Agent': 'huaweicloud-devkit/1.0' },
|
|
24
27
|
signal: controller.signal,
|
|
25
|
-
}
|
|
28
|
+
};
|
|
29
|
+
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
30
|
+
const resp = await fetch(url, fetchOpts);
|
|
26
31
|
const data = await resp.json();
|
|
27
32
|
if (data && data.encoding === 'base64' && data.content) {
|
|
28
33
|
const decoded = Buffer.from(data.content, 'base64').toString('utf8');
|