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.29";
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
- console.error(`${RED$3}获取 SSO_TICKET 失败: ${errorData.error || errorData.code || "Unknown error"}${RESET$3}`);
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, { stopOnAlibabaLoginRedirect: true });
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)) return {
6094
- response,
6095
- responseBody: await response.text(),
6096
- sawAlibabaLoginRedirect
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: Token 已失效,请重新登录${RESET$2}`);
6181
- console.log(`${TEXT$2}执行: npx ali-skills login${RESET$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";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ali/cli-skills",
3
- "version": "2.0.29",
3
+ "version": "2.0.30",
4
4
  "description": "The open agent skills ecosystem",
5
5
  "type": "module",
6
6
  "bin": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ali-skills",
3
- "version": "0.0.28",
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.29"
34
+ "@ali/cli-skills": "^2.0.30"
35
35
  },
36
36
  "bundleDependencies": [
37
37
  "@ali/cli-skills"