ali-skills 0.0.28 → 0.0.29
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.
|
@@ -2340,7 +2340,7 @@ function logSkillParseFailures(failures) {
|
|
|
2340
2340
|
if (f.hint) M.message(import_picocolors.default.yellow(` 提示: ${f.hint}`));
|
|
2341
2341
|
}
|
|
2342
2342
|
}
|
|
2343
|
-
var version$1 = "2.0.
|
|
2343
|
+
var version$1 = "2.0.30";
|
|
2344
2344
|
const isCancelled$1 = (value) => typeof value === "symbol";
|
|
2345
2345
|
function redactSensitiveText(text) {
|
|
2346
2346
|
return text.replace(/(https?:\/\/)([^/\s:@]+)(?::([^@/\s]*))?@/gi, "$1").replace(/([?&](?:private_token|access_token|token|api_key|access_key|secret|password)=)[^&\s]+/gi, "$1***");
|
|
@@ -5597,7 +5597,12 @@ async function ensureSsoTicket() {
|
|
|
5597
5597
|
}
|
|
5598
5598
|
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
5599
5599
|
gatewayDebugLog(`sso-ticket failed: code=${errorData.code ?? "n/a"}, error=${errorData.error ?? "Unknown error"}`);
|
|
5600
|
-
|
|
5600
|
+
if (response.status === 401 && errorData.code === "INVALID_TOKEN") {
|
|
5601
|
+
console.error(`${RED$3}ali-skills CLI 会话凭证(Gateway private token)已失效,无法获取 BUC SSO_TICKET${RESET$3}`);
|
|
5602
|
+
console.log(`${TEXT$3}请重新登录: npx ali-skills login${RESET$3}`);
|
|
5603
|
+
return null;
|
|
5604
|
+
}
|
|
5605
|
+
console.error(`${RED$3}获取 BUC SSO_TICKET 失败: ${errorData.error || errorData.code || "Unknown error"}${RESET$3}`);
|
|
5601
5606
|
return null;
|
|
5602
5607
|
} catch (error) {
|
|
5603
5608
|
gatewayDebugLog(`sso-ticket fetch exception: ${error.message}`);
|
|
@@ -5620,6 +5625,70 @@ const RESET$2 = "\x1B[0m";
|
|
|
5620
5625
|
const GREEN$1 = "\x1B[32m";
|
|
5621
5626
|
const RED$2 = "\x1B[31m";
|
|
5622
5627
|
const YELLOW$2 = "\x1B[33m";
|
|
5628
|
+
const STREAM_TOTAL_TIMEOUT = 300 * 1e3;
|
|
5629
|
+
const STREAM_IDLE_TIMEOUT = 120 * 1e3;
|
|
5630
|
+
async function streamResponseBody(response, outputPath) {
|
|
5631
|
+
if (!response.body) return;
|
|
5632
|
+
const reader = response.body.getReader();
|
|
5633
|
+
let idleTimer;
|
|
5634
|
+
let idleRejectFn;
|
|
5635
|
+
const idlePromise = new Promise((_, reject) => {
|
|
5636
|
+
idleRejectFn = reject;
|
|
5637
|
+
});
|
|
5638
|
+
const resetIdle = () => {
|
|
5639
|
+
clearTimeout(idleTimer);
|
|
5640
|
+
idleTimer = setTimeout(() => idleRejectFn(/* @__PURE__ */ new Error("STREAM_IDLE_TIMEOUT")), STREAM_IDLE_TIMEOUT);
|
|
5641
|
+
};
|
|
5642
|
+
const totalTimer = setTimeout(() => idleRejectFn(/* @__PURE__ */ new Error("STREAM_TOTAL_TIMEOUT")), STREAM_TOTAL_TIMEOUT);
|
|
5643
|
+
const readChunk = () => Promise.race([reader.read(), idlePromise]);
|
|
5644
|
+
try {
|
|
5645
|
+
if (outputPath) {
|
|
5646
|
+
const { createWriteStream } = await import("fs");
|
|
5647
|
+
const ws = createWriteStream(outputPath);
|
|
5648
|
+
const done$ = new Promise((resolve, reject) => {
|
|
5649
|
+
ws.on("finish", resolve);
|
|
5650
|
+
ws.on("error", reject);
|
|
5651
|
+
});
|
|
5652
|
+
resetIdle();
|
|
5653
|
+
for (;;) {
|
|
5654
|
+
const { done, value } = await readChunk();
|
|
5655
|
+
if (done) {
|
|
5656
|
+
ws.end();
|
|
5657
|
+
break;
|
|
5658
|
+
}
|
|
5659
|
+
resetIdle();
|
|
5660
|
+
ws.write(value);
|
|
5661
|
+
}
|
|
5662
|
+
await done$;
|
|
5663
|
+
return;
|
|
5664
|
+
}
|
|
5665
|
+
const decoder = new TextDecoder();
|
|
5666
|
+
resetIdle();
|
|
5667
|
+
for (;;) {
|
|
5668
|
+
const { done, value } = await readChunk();
|
|
5669
|
+
if (done) break;
|
|
5670
|
+
resetIdle();
|
|
5671
|
+
process.stdout.write(decoder.decode(value, { stream: true }));
|
|
5672
|
+
}
|
|
5673
|
+
const tail = decoder.decode();
|
|
5674
|
+
if (tail) process.stdout.write(tail);
|
|
5675
|
+
} catch (err) {
|
|
5676
|
+
reader.cancel();
|
|
5677
|
+
if (err?.message === "STREAM_IDLE_TIMEOUT") {
|
|
5678
|
+
process.stderr.write(`\n${RED$2}流式超时:超过 ${STREAM_IDLE_TIMEOUT / 1e3}s 未收到数据${RESET$2}\n`);
|
|
5679
|
+
process.exit(1);
|
|
5680
|
+
}
|
|
5681
|
+
if (err?.message === "STREAM_TOTAL_TIMEOUT") {
|
|
5682
|
+
process.stderr.write(`\n${RED$2}流式超时:总时长超过 ${STREAM_TOTAL_TIMEOUT / 1e3}s${RESET$2}\n`);
|
|
5683
|
+
process.exit(1);
|
|
5684
|
+
}
|
|
5685
|
+
throw err;
|
|
5686
|
+
} finally {
|
|
5687
|
+
clearTimeout(idleTimer);
|
|
5688
|
+
clearTimeout(totalTimer);
|
|
5689
|
+
reader.releaseLock();
|
|
5690
|
+
}
|
|
5691
|
+
}
|
|
5623
5692
|
function openBrowser$1(url) {
|
|
5624
5693
|
const platform = process.platform;
|
|
5625
5694
|
spawn(platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open", [url], {
|
|
@@ -5713,7 +5782,7 @@ async function sendO2SdkRequest(targetUrl, options, withSsoTicket) {
|
|
|
5713
5782
|
ssoTicket = await ensureSsoTicket();
|
|
5714
5783
|
if (ssoTicket) ssoTicketSource = "gateway";
|
|
5715
5784
|
}
|
|
5716
|
-
if (!ssoTicket) throw new Error("无法获取 SSO_TICKET
|
|
5785
|
+
if (!ssoTicket) throw new Error("无法获取 BUC SSO_TICKET,请执行 npx ali-skills login 重新登录后重试");
|
|
5717
5786
|
headers.SSO_TICKET = ssoTicket;
|
|
5718
5787
|
}
|
|
5719
5788
|
let O2ClientCtor;
|
|
@@ -5850,7 +5919,7 @@ async function sendDirectRequest(targetUrl, platform, token, options) {
|
|
|
5850
5919
|
const controller = new AbortController();
|
|
5851
5920
|
const timeout = options.timeout || 3e4;
|
|
5852
5921
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
5853
|
-
const { response, responseBody } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet);
|
|
5922
|
+
const { response, responseBody } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet, { stream: options.stream });
|
|
5854
5923
|
clearTimeout(timeoutId);
|
|
5855
5924
|
if (!options.quiet) {
|
|
5856
5925
|
const statusColor = response.ok ? GREEN$1 : RED$2;
|
|
@@ -5864,6 +5933,14 @@ async function sendDirectRequest(targetUrl, platform, token, options) {
|
|
|
5864
5933
|
console.log();
|
|
5865
5934
|
}
|
|
5866
5935
|
}
|
|
5936
|
+
if (options.stream) {
|
|
5937
|
+
if (options.output) {
|
|
5938
|
+
await streamResponseBody(response, options.output);
|
|
5939
|
+
if (!options.quiet) console.log(`${GREEN$1}✓ 已保存到 ${options.output}${RESET$2}`);
|
|
5940
|
+
} else await streamResponseBody(response);
|
|
5941
|
+
if (!response.ok) process.exit(1);
|
|
5942
|
+
return;
|
|
5943
|
+
}
|
|
5867
5944
|
let outputBody = responseBody;
|
|
5868
5945
|
if (!options.raw && options.pretty !== false) try {
|
|
5869
5946
|
const json = JSON.parse(responseBody);
|
|
@@ -5928,7 +6005,10 @@ async function sendSsoCookieDirectRequest(targetUrl, options) {
|
|
|
5928
6005
|
const controller = new AbortController();
|
|
5929
6006
|
const timeout = options.timeout || 3e4;
|
|
5930
6007
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
5931
|
-
const { response, responseBody, loginRedirectUrl } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet, {
|
|
6008
|
+
const { response, responseBody, loginRedirectUrl } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet, {
|
|
6009
|
+
stopOnAlibabaLoginRedirect: true,
|
|
6010
|
+
stream: options.stream
|
|
6011
|
+
});
|
|
5932
6012
|
clearTimeout(timeoutId);
|
|
5933
6013
|
if (!options.quiet) {
|
|
5934
6014
|
const statusColor = response.ok ? GREEN$1 : RED$2;
|
|
@@ -5950,6 +6030,21 @@ async function sendSsoCookieDirectRequest(targetUrl, options) {
|
|
|
5950
6030
|
});
|
|
5951
6031
|
console.log();
|
|
5952
6032
|
}
|
|
6033
|
+
if (options.stream) {
|
|
6034
|
+
if (!response.ok) {
|
|
6035
|
+
if (options.quiet && (loginRedirectUrl || response.headers.get("location"))) {
|
|
6036
|
+
const location = loginRedirectUrl || response.headers.get("location") || "(empty)";
|
|
6037
|
+
console.error(`HTTP ${response.status} ${response.statusText} (Location: ${location})`);
|
|
6038
|
+
printReauthAndRetryHint(location, true);
|
|
6039
|
+
}
|
|
6040
|
+
process.exit(1);
|
|
6041
|
+
}
|
|
6042
|
+
if (options.output) {
|
|
6043
|
+
await streamResponseBody(response, options.output);
|
|
6044
|
+
if (!options.quiet) console.log(`${GREEN$1}✓ 已保存到 ${options.output}${RESET$2}`);
|
|
6045
|
+
} else await streamResponseBody(response);
|
|
6046
|
+
return;
|
|
6047
|
+
}
|
|
5953
6048
|
let outputBody = responseBody;
|
|
5954
6049
|
if (!options.raw && options.pretty !== false) try {
|
|
5955
6050
|
const json = JSON.parse(responseBody);
|
|
@@ -6006,12 +6101,20 @@ async function sendSsoTicketDirectRequest(targetUrl, options) {
|
|
|
6006
6101
|
const controller = new AbortController();
|
|
6007
6102
|
const timeout = options.timeout || 3e4;
|
|
6008
6103
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
6009
|
-
const { response, responseBody } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet);
|
|
6104
|
+
const { response, responseBody } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet, { stream: options.stream });
|
|
6010
6105
|
clearTimeout(timeoutId);
|
|
6011
6106
|
if (!options.quiet) {
|
|
6012
6107
|
const statusColor = response.ok ? GREEN$1 : RED$2;
|
|
6013
6108
|
console.log(`${statusColor}${response.status} ${response.statusText}${RESET$2}`);
|
|
6014
6109
|
}
|
|
6110
|
+
if (options.stream) {
|
|
6111
|
+
if (options.output) {
|
|
6112
|
+
await streamResponseBody(response, options.output);
|
|
6113
|
+
if (!options.quiet) console.log(`${GREEN$1}✓ 已保存到 ${options.output}${RESET$2}`);
|
|
6114
|
+
} else await streamResponseBody(response);
|
|
6115
|
+
if (!response.ok) process.exit(1);
|
|
6116
|
+
return;
|
|
6117
|
+
}
|
|
6015
6118
|
let outputBody = responseBody;
|
|
6016
6119
|
if (!options.raw && options.pretty !== false) try {
|
|
6017
6120
|
const json = JSON.parse(responseBody);
|
|
@@ -6039,7 +6142,7 @@ async function sendPlainDirectRequest(targetUrl, options, allowSsoCookieFallback
|
|
|
6039
6142
|
console.log(`${DIM$2}→ 直接请求 (No Auth)${RESET$2}`);
|
|
6040
6143
|
}
|
|
6041
6144
|
const timeout = options.timeout || 3e4;
|
|
6042
|
-
const { response, responseBody, sawAlibabaLoginRedirect } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet);
|
|
6145
|
+
const { response, responseBody, sawAlibabaLoginRedirect } = await fetchWithRedirects(targetUrl, options.method.toUpperCase(), requestHeaders, body, timeout, options.quiet, { stream: options.stream });
|
|
6043
6146
|
if (allowSsoCookieFallback && sawAlibabaLoginRedirect) {
|
|
6044
6147
|
if (!options.quiet) {
|
|
6045
6148
|
console.log(`${YELLOW$2}检测到请求被重定向到 login.alibaba-inc.com,目标接口可能需要登录鉴权${RESET$2}`);
|
|
@@ -6063,6 +6166,14 @@ async function sendPlainDirectRequest(targetUrl, options, allowSsoCookieFallback
|
|
|
6063
6166
|
console.log();
|
|
6064
6167
|
}
|
|
6065
6168
|
}
|
|
6169
|
+
if (options.stream) {
|
|
6170
|
+
if (options.output) {
|
|
6171
|
+
await streamResponseBody(response, options.output);
|
|
6172
|
+
if (!options.quiet) console.log(`${GREEN$1}✓ 已保存到 ${options.output}${RESET$2}`);
|
|
6173
|
+
} else await streamResponseBody(response);
|
|
6174
|
+
if (!response.ok) process.exit(1);
|
|
6175
|
+
return;
|
|
6176
|
+
}
|
|
6066
6177
|
let outputBody = responseBody;
|
|
6067
6178
|
if (!options.raw && options.pretty !== false) try {
|
|
6068
6179
|
const json = JSON.parse(responseBody);
|
|
@@ -6090,11 +6201,18 @@ async function fetchWithRedirects(initialUrl, method, headers, body, timeout, qu
|
|
|
6090
6201
|
signal: controller.signal,
|
|
6091
6202
|
redirect: "manual"
|
|
6092
6203
|
});
|
|
6093
|
-
if (!REDIRECT_STATUS_CODES.has(response.status))
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6204
|
+
if (!REDIRECT_STATUS_CODES.has(response.status)) {
|
|
6205
|
+
if (opts?.stream) return {
|
|
6206
|
+
response,
|
|
6207
|
+
responseBody: "",
|
|
6208
|
+
sawAlibabaLoginRedirect
|
|
6209
|
+
};
|
|
6210
|
+
return {
|
|
6211
|
+
response,
|
|
6212
|
+
responseBody: await response.text(),
|
|
6213
|
+
sawAlibabaLoginRedirect
|
|
6214
|
+
};
|
|
6215
|
+
}
|
|
6098
6216
|
const location = response.headers.get("location");
|
|
6099
6217
|
if (!location) return {
|
|
6100
6218
|
response,
|
|
@@ -6177,13 +6295,36 @@ async function sendGatewayRequest(targetUrl, platformKey, options, authMode = "g
|
|
|
6177
6295
|
error: "Unauthorized",
|
|
6178
6296
|
code: "UNKNOWN"
|
|
6179
6297
|
}))).code === "INVALID_TOKEN") {
|
|
6180
|
-
console.error(`${RED$2}Error:
|
|
6181
|
-
console.log(`${TEXT$2}
|
|
6298
|
+
console.error(`${RED$2}Error: ali-skills CLI 会话凭证(Gateway private token)已失效${RESET$2}`);
|
|
6299
|
+
console.log(`${TEXT$2}请重新登录: npx ali-skills login${RESET$2}`);
|
|
6182
6300
|
process.exit(1);
|
|
6183
6301
|
}
|
|
6184
6302
|
}
|
|
6185
|
-
const responseBody = await response.text();
|
|
6186
6303
|
const requestId = response.headers.get("X-Gateway-Request-Id");
|
|
6304
|
+
if (options.stream) {
|
|
6305
|
+
if (!options.quiet) {
|
|
6306
|
+
const statusColor = response.ok ? GREEN$1 : RED$2;
|
|
6307
|
+
console.log(`${statusColor}${response.status} ${response.statusText}${RESET$2}`);
|
|
6308
|
+
if (requestId) console.log(`${DIM$2}Request ID: ${requestId}${RESET$2}`);
|
|
6309
|
+
if (options.includeHeaders) {
|
|
6310
|
+
console.log();
|
|
6311
|
+
console.log(`${TEXT$2}Response Headers:${RESET$2}`);
|
|
6312
|
+
response.headers.forEach((value, key) => console.log(` ${key}: ${value}`));
|
|
6313
|
+
console.log();
|
|
6314
|
+
}
|
|
6315
|
+
}
|
|
6316
|
+
if (!response.ok) {
|
|
6317
|
+
const errBody = await response.text().catch(() => "");
|
|
6318
|
+
if (errBody) process.stderr.write(errBody + "\n");
|
|
6319
|
+
process.exit(1);
|
|
6320
|
+
}
|
|
6321
|
+
if (options.output) {
|
|
6322
|
+
await streamResponseBody(response, options.output);
|
|
6323
|
+
if (!options.quiet) console.log(`${GREEN$1}✓ 已保存到 ${options.output}${RESET$2}`);
|
|
6324
|
+
} else await streamResponseBody(response);
|
|
6325
|
+
return;
|
|
6326
|
+
}
|
|
6327
|
+
const responseBody = await response.text();
|
|
6187
6328
|
if (!options.quiet) {
|
|
6188
6329
|
const statusColor = response.ok ? GREEN$1 : RED$2;
|
|
6189
6330
|
console.log(`${statusColor}${response.status} ${response.statusText}${RESET$2}`);
|
|
@@ -6839,6 +6980,7 @@ ${BOLD}Request Options:${RESET}
|
|
|
6839
6980
|
-t, --timeout <ms> Request timeout (default: 30000)
|
|
6840
6981
|
--pretty Pretty print JSON output (default: true)
|
|
6841
6982
|
--raw Raw output without formatting
|
|
6983
|
+
--stream Stream response body as it arrives (useful for SSE / LLM APIs)
|
|
6842
6984
|
-q, --quiet Quiet mode, only output response body
|
|
6843
6985
|
|
|
6844
6986
|
${BOLD}Examples:${RESET}
|
|
@@ -6988,6 +7130,9 @@ function parseRequestOptions(args) {
|
|
|
6988
7130
|
case "--raw":
|
|
6989
7131
|
options.raw = true;
|
|
6990
7132
|
break;
|
|
7133
|
+
case "--stream":
|
|
7134
|
+
options.stream = true;
|
|
7135
|
+
break;
|
|
6991
7136
|
case "--auth-mode":
|
|
6992
7137
|
case "--auth":
|
|
6993
7138
|
options.authMode = args[++i] ?? "auto";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ali-skills",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "The open agent skills ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"author": "",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ali/cli-skills": "^2.0.
|
|
34
|
+
"@ali/cli-skills": "^2.0.30"
|
|
35
35
|
},
|
|
36
36
|
"bundleDependencies": [
|
|
37
37
|
"@ali/cli-skills"
|