@kscs-inc/cli 0.3.5 → 0.4.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.
package/README.md CHANGED
@@ -5,15 +5,15 @@
5
5
  ## 安装
6
6
 
7
7
  ```sh
8
- npx @kscs-inc/cli@0.3.5 install
8
+ npx @kscs-inc/cli@0.4.0 install
9
9
  # 国内镜像(同步可能延迟)
10
- npx --registry=https://registry.npmmirror.com @kscs-inc/cli@0.3.5 install
10
+ npx --registry=https://registry.npmmirror.com @kscs-inc/cli@0.4.0 install
11
11
  # 或全局安装入口后显式安装客户端
12
- npm install -g @kscs-inc/cli@0.3.5
12
+ npm install -g @kscs-inc/cli@0.4.0
13
13
  kscs install
14
14
  ```
15
15
 
16
- 旧kscs命令可能优先于npm入口,首次推荐npx;使用官网指引核对实际路径,不使用sudo覆盖。安装默认个人模式,团队用 --mode team --config /既有私有目录/team.json;不得把秘密写在命令中。未原生验收平台须显式 --channel trial,不自动升级。
16
+ 旧kscs命令可能优先于npm入口,首次推荐npx;使用官网指引核对实际路径,不使用sudo覆盖。安装默认个人模式,团队用 --mode team --config /既有私有目录/team.json;不得把秘密写在命令中。默认按当前模式、系统和架构选择包:只安装正式目标,入口与客户端版本一致。可用 --channel stable 显式选择正式通道;缺目标时报错,不回退到试用。网络、签名或摘要错误不会切换通道。
17
17
 
18
18
  ## 验证与使用
19
19
 
@@ -23,10 +23,10 @@ kscs auth login
23
23
  kscs products list
24
24
  ```
25
25
 
26
- 安装成功不代表已登录或有业务权限。终端未识别命令时新开终端,或使用回执给出的绝对入口。
26
+ 安装成功不代表已登录或有业务权限。安装后可直接使用回执给出的带引号绝对入口,无需重开终端;要在当前终端使用kscs短命令,复制执行回执中的激活语句。命令登记不等于当前终端PATH已经刷新。
27
27
 
28
28
  ## 安全与更新
29
29
 
30
- 入口版本0.3.5固定对应发行目标,验证Ed25519签名及SHA256后调用同一安装事务。客户端自带Node,后续使用kscs update check/status/apply;npm仅更新入口。npm uninstall -g @kscs-inc/cli只删除npm入口,不删除实际客户端、配置和Skill。业务请求直接到公司CLI服务,不经过npm或镜像。
30
+ 入口版本0.4.0固定对应发行目标,验证Ed25519签名及SHA256后调用同一安装事务。客户端自带Node,后续使用kscs update check/status/apply;npm仅更新入口。npm uninstall -g @kscs-inc/cli只删除npm入口,不删除实际客户端、配置和Skill。业务请求直接到公司CLI服务,不经过npm或镜像。
31
31
 
32
32
  如安装中断,保留原客户端与身份,按中文错误提示恢复;不关闭TLS或签名校验。镜像不可用时从npm官方源重试或使用官网安装方式。内联第三方代码许可见THIRD-PARTY-NOTICES.txt。
package/bin/kscs.mjs CHANGED
@@ -1379,6 +1379,115 @@ var require_yauzl = __commonJS({
1379
1379
  import { dirname as dirname2, resolve as resolve3 } from "node:path";
1380
1380
  import { fileURLToPath } from "node:url";
1381
1381
 
1382
+ // cli/src/common/cli.error.ts
1383
+ var CliError = class extends Error {
1384
+ constructor(code, message, nextAction = "FIX_INPUT", details, requestId, retryable = false, category) {
1385
+ super(message);
1386
+ this.code = code;
1387
+ this.nextAction = nextAction;
1388
+ this.details = details;
1389
+ this.requestId = requestId;
1390
+ this.retryable = retryable;
1391
+ this.category = category;
1392
+ }
1393
+ };
1394
+
1395
+ // cli/src/common/cli-output.formatter.ts
1396
+ var CATEGORY_EXIT = {
1397
+ /** 接口或业务拒绝。 */
1398
+ api: 1,
1399
+ /** 命令参数无效。 */
1400
+ validation: 2,
1401
+ /** 身份认证未完成。 */
1402
+ authentication: 3,
1403
+ /** 当前身份无权限。 */
1404
+ authorization: 3,
1405
+ /** 本机配置或客户端版本不满足要求。 */
1406
+ config: 3,
1407
+ /** 网络连接、传输或超时失败。 */
1408
+ network: 4,
1409
+ /** 客户端内部或响应契约异常。 */
1410
+ internal: 5,
1411
+ /** 执行策略拒绝。 */
1412
+ policy: 6,
1413
+ /** 执行前需要确认。 */
1414
+ confirmation: 10
1415
+ };
1416
+ var ERROR_CATEGORY = {
1417
+ INVALID_ARGUMENT: "validation",
1418
+ IDEMPOTENCY_KEY_REQUIRED: "validation",
1419
+ IDEMPOTENCY_CONFLICT: "validation",
1420
+ AUTH_REQUIRED: "authentication",
1421
+ SESSION_REVOKED: "authentication",
1422
+ TOKEN_EXPIRED: "authentication",
1423
+ CLI_SCOPE_DENIED: "authorization",
1424
+ PRODUCT_PERMISSION_DENIED: "authorization",
1425
+ RESULT_ACCESS_REVOKED: "authorization",
1426
+ CONFIG_ERROR: "config",
1427
+ ACCOUNT_MAPPING_REQUIRED: "config",
1428
+ ACCOUNT_MAPPING_CONFLICT: "config",
1429
+ CLIENT_UPGRADE_REQUIRED: "config",
1430
+ ACTION_NOT_FOUND: "api",
1431
+ ACTION_VERSION_CHANGED: "api",
1432
+ ACTION_DISABLED: "api",
1433
+ ACTION_UNAVAILABLE: "api",
1434
+ OPERATION_LOOKUP_EXPIRED: "api",
1435
+ RATE_LIMITED: "api",
1436
+ UPSTREAM_ERROR: "api",
1437
+ AUTH_DEPENDENCY_UNAVAILABLE: "api",
1438
+ WRITE_REJECTED: "api",
1439
+ OPERATION_LOOKUP_UNAVAILABLE: "api",
1440
+ OUTCOME_UNKNOWN: "api",
1441
+ NETWORK_ERROR: "network",
1442
+ UPSTREAM_TIMEOUT: "network",
1443
+ UPSTREAM_RESPONSE_INVALID: "internal",
1444
+ INTERNAL_ERROR: "internal",
1445
+ INSTALLATION_FAILED: "internal",
1446
+ INSTALLATION_INCOMPLETE: "internal"
1447
+ };
1448
+ var HINTS = {
1449
+ UPGRADE_CLIENT: "\u5148\u5347\u7EA7CLI\u548C\u968F\u5305Skill\u5E76\u6838\u5BF9\u7248\u672C\uFF0C\u518D\u7EE7\u7EED\u5C1A\u672A\u53D1\u9001\u7684\u4EFB\u52A1\uFF1B\u5DF2\u53D1\u9001\u5199\u5165\u53EA\u67E5\u8BE2\u539F\u7ED3\u679C\u3002",
1450
+ FIX_INPUT: "\u6309 schema \u5B57\u6BB5\u8BF4\u660E\u4FEE\u6B63\u53C2\u6570\u3002",
1451
+ LOGIN: "\u8BF7\u5458\u5DE5\u91CD\u65B0\u5B8C\u6210\u98DE\u4E66\u767B\u5F55\u6388\u6743\u3002",
1452
+ REQUEST_PERMISSION: "\u7533\u8BF7\u6240\u9700 CLI \u6216\u539F\u4EA7\u54C1\u6743\u9650\u540E\u518D\u64CD\u4F5C\u3002",
1453
+ LIST_ACTIONS: "\u91CD\u65B0\u67E5\u770B\u5F53\u524D\u6709\u6743\u4F7F\u7528\u7684\u80FD\u529B\u6E05\u5355\u3002",
1454
+ DESCRIBE_ACTION: "\u91CD\u65B0\u8FD0\u884C kscs schema\uFF0C\u6309\u65B0\u5B9A\u4E49\u6838\u5BF9\u53C2\u6570\u3002",
1455
+ STOP: "\u505C\u6B62\u672C\u6B21\u8C03\u7528\uFF0C\u6309\u4E1A\u52A1\u6216\u6743\u9650\u6D41\u7A0B\u5904\u7406\u3002",
1456
+ RETRY_LATER: "\u7A0D\u540E\u6838\u5B9E\u72B6\u6001\uFF1B\u5199\u5165\u7ED3\u679C\u672A\u77E5\u65F6\u53EA\u67E5\u539F\u7ED3\u679C\u3002",
1457
+ CONTACT_SUPPORT: "\u63D0\u4F9B request_id \u6216\u539F\u64CD\u4F5C\u5B9A\u4F4D\uFF0C\u8BF7\u7EDF\u4E00 CLI \u6216\u4EA7\u54C1\u56E2\u961F\u6838\u5B9E\u3002",
1458
+ REFRESH_AUTH: "\u4EC5\u5728\u660E\u786E\u4E1A\u52A1\u6267\u884C\u524D\u62D2\u7EDD\u65F6\u7EED\u671F\uFF0C\u5E76\u4FDD\u6301\u539F\u5E42\u7B49\u952E\u3002",
1459
+ CHECK_OPERATION: "\u4F7F\u7528\u539F\u80FD\u529B\u3001\u539F\u7248\u672C\u548C\u539F\u5E42\u7B49\u952E\u67E5\u8BE2\u7ED3\u679C\uFF0C\u4E0D\u91CD\u53D1\u5199\u5165\u3002"
1460
+ };
1461
+ function diagnosticHint(error) {
1462
+ if (error.code === "UPSTREAM_ERROR" && error.details?.failure_kind === "business_rejection")
1463
+ return "\u8BF7\u4E1A\u52A1\u8D1F\u8D23\u4EBA\u5904\u7406\u4E0A\u8FF0\u539F\u56E0\u540E\u91CD\u65B0\u67E5\u8BE2\uFF1B\u91CD\u590D\u91CD\u8BD5\u6216\u91CD\u65B0\u767B\u5F55\u4E0D\u4F1A\u8865\u9F50\u4E1A\u52A1\u6570\u636E\u3002";
1464
+ if (error.code === "UPSTREAM_RESPONSE_INVALID" && error.details?.failure_kind === "response_schema_mismatch")
1465
+ return "\u8BF7\u63A5\u53E3\u63D0\u4F9B\u65B9\u4E0E\u63A5\u5165\u7EF4\u62A4\u65B9\u6838\u5BF9\u5B57\u6BB5\u7EA6\u5B9A\uFF1B\u672C\u6B21\u7ED3\u679C\u672A\u6210\u529F\u8FD4\u56DE\uFF0C\u4E0D\u53EF\u4F5C\u4E3A\u5B8C\u6574\u7ED3\u679C\u4F7F\u7528\u3002";
1466
+ return void 0;
1467
+ }
1468
+ function failure(cause) {
1469
+ const error = cause instanceof CliError ? cause : new CliError("INTERNAL_ERROR", "\u5BA2\u6237\u7AEF\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u652F\u6301\u4EBA\u5458\u3002", "CONTACT_SUPPORT");
1470
+ const category = error.category ?? (Object.hasOwn(ERROR_CATEGORY, error.code) ? ERROR_CATEGORY[error.code] : "internal");
1471
+ const exit = CATEGORY_EXIT[category];
1472
+ const result = {
1473
+ exit,
1474
+ envelope: {
1475
+ identity: "user",
1476
+ ...error.requestId ? { request_id: error.requestId } : {},
1477
+ error: {
1478
+ type: category,
1479
+ subtype: error.code,
1480
+ message: error.message,
1481
+ hint: error.details?.auth_context === "company_login" ? error.details.login_owner === "BOUND_EMPLOYEE" ? "\u7531\u56E2\u961F\u7ED1\u5B9A\u5458\u5DE5\u5728\u672C\u4EBA\u7535\u8111\u6267\u884C kscs auth company-login\uFF1B\u5176\u4ED6\u63D0\u95EE\u8005\u65E0\u9700\u767B\u5F55\u3002" : "\u6267\u884C kscs auth company-login --complete \u5B8C\u6210\u5DF2\u53D1\u8D77\u767B\u5F55\uFF0C\u6216\u7528 kscs auth company-login --no-wait \u83B7\u53D6\u5165\u53E3\uFF1B\u5B8C\u6210\u540E\u91CD\u65B0\u67E5\u8BE2\u3002" : diagnosticHint(error) ?? (Object.hasOwn(HINTS, error.nextAction) ? HINTS[error.nextAction] : HINTS.CONTACT_SUPPORT),
1482
+ retryable: error.retryable,
1483
+ next_action: error.nextAction,
1484
+ ...error.details ? { details: error.details } : {}
1485
+ }
1486
+ }
1487
+ };
1488
+ return result;
1489
+ }
1490
+
1382
1491
  // cli/src/common/config/release-trust.config.ts
1383
1492
  var RELEASE_TRUST = Object.freeze({
1384
1493
  /** 唯一信任根标识;未知标识拒绝,不接受远端下发公钥。 */
@@ -1391,11 +1500,19 @@ var NPM_PACKAGE_NAME = "@kscs-inc/cli";
1391
1500
  // cli/src/service/installation/npm-bootstrap.service.ts
1392
1501
  import { spawn } from "node:child_process";
1393
1502
  import { createHash as createHash3 } from "node:crypto";
1394
- import { lstat as lstat2, mkdtemp, readFile, realpath as realpath2, rm } from "node:fs/promises";
1503
+ import { lstat as lstat2, mkdtemp, readFile, realpath as realpath2 } from "node:fs/promises";
1395
1504
  import { tmpdir } from "node:os";
1396
1505
  import { join as join3, resolve as resolve2 } from "node:path";
1397
1506
  import { parseArgs } from "node:util";
1398
1507
 
1508
+ // cli/src/common/process-exit.ts
1509
+ import { constants } from "node:os";
1510
+ function childExitStatus(code, signal) {
1511
+ if (code !== null) return code;
1512
+ const number = signal ? constants.signals[signal] : void 0;
1513
+ return typeof number === "number" ? 128 + number : 5;
1514
+ }
1515
+
1399
1516
  // cli/src/common/client/installation-download.client.ts
1400
1517
  import { createHash as createHash2, randomUUID } from "node:crypto";
1401
1518
  import { createReadStream, createWriteStream } from "node:fs";
@@ -1538,11 +1655,20 @@ async function downloadVerifiedRelease(url, limit, allowLocal = false, timeoutMs
1538
1655
  // cli/src/common/client/installation-archive.client.ts
1539
1656
  var import_yauzl = __toESM(require_yauzl(), 1);
1540
1657
  import { createWriteStream as createWriteStream2 } from "node:fs";
1541
- import { chmod, lstat, mkdir, open as open2, readdir, realpath } from "node:fs/promises";
1658
+ import { chmod, lstat, mkdir, open as open2, readdir, realpath, rm } from "node:fs/promises";
1542
1659
  import { dirname, join, resolve } from "node:path";
1543
1660
  import { pipeline as pipeline2 } from "node:stream/promises";
1544
1661
  var MAX_ARCHIVE_FILES = 3e4;
1545
1662
  var MAX_EXPANDED_BYTES = 1024 * 1024 * 1024;
1663
+ async function cleanupInstallationStaging(directory) {
1664
+ try {
1665
+ await rm(directory, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
1666
+ } catch (error) {
1667
+ const message = error instanceof Error ? error.message : String(error);
1668
+ process.stderr.write(`\u5B89\u88C5\u4E34\u65F6\u76EE\u5F55\u5F85\u6E05\u7406\uFF1A${directory}\uFF1B${message}
1669
+ `);
1670
+ }
1671
+ }
1546
1672
  function validateArchivePath(name) {
1547
1673
  const parts = name.replace(/\/$/, "").split("/");
1548
1674
  if (!name || /[\\:\x00-\x1f]/.test(name) || parts.some(
@@ -1768,10 +1894,10 @@ async function readNpmRelease(directory) {
1768
1894
  const targets = value.targets.map((target) => {
1769
1895
  if (!target || typeof target !== "object") throw new Error("npm\u53D1\u884C\u76EE\u6807\u65E0\u6548");
1770
1896
  const item = target;
1771
- if (!INSTALL_MODES.includes(item.mode) || !INSTALL_PLATFORMS.includes(item.platform) || !INSTALL_ARCHITECTURES.includes(item.arch) || !["stable", "trial"].includes(String(item.channel)) || typeof item.manifest !== "string" || typeof item.manifest_sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item.manifest_sha256) || typeof item.build_id !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,100}$/.test(item.build_id))
1897
+ if (!INSTALL_MODES.includes(item.mode) || !INSTALL_PLATFORMS.includes(item.platform) || !INSTALL_ARCHITECTURES.includes(item.arch) || item.channel !== "stable" || typeof item.manifest !== "string" || typeof item.manifest_sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item.manifest_sha256) || typeof item.build_id !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,100}$/.test(item.build_id))
1772
1898
  throw new Error("npm\u53D1\u884C\u76EE\u6807\u5B57\u6BB5\u65E0\u6548");
1773
1899
  const url = new URL(item.manifest);
1774
- if (url.origin !== "https://cli.xaweiju.com" || url.username || url.password || url.hash || url.search || !url.pathname.startsWith("/downloads/cli/node/") || !url.pathname.endsWith("/manifest.json"))
1900
+ if (url.origin !== "https://cli.xaweiju.com" || url.username || url.password || url.hash || url.search || !url.pathname.startsWith("/downloads/cli/node/") || url.pathname.startsWith("/downloads/cli/node/trial/") || !url.pathname.endsWith("/manifest.json"))
1775
1901
  throw new Error("npm\u53D1\u884C\u76EE\u6807\u6765\u6E90\u65E0\u6548");
1776
1902
  const key = `${item.mode}/${item.platform}/${item.arch}/${item.channel}`;
1777
1903
  if (keys.has(key)) throw new Error("npm\u53D1\u884C\u76EE\u6807\u91CD\u590D");
@@ -1809,7 +1935,7 @@ async function runNpmChild(command, argumentsList) {
1809
1935
  });
1810
1936
  child.once("exit", (code, signal) => {
1811
1937
  cleanup();
1812
- accept(code ?? (signal === "SIGINT" ? 130 : 143));
1938
+ accept(childExitStatus(code, signal));
1813
1939
  });
1814
1940
  });
1815
1941
  }
@@ -1849,32 +1975,35 @@ async function installFromNpm(release, argv, onFormat) {
1849
1975
  args: argv,
1850
1976
  options: {
1851
1977
  mode: { type: "string", default: "personal" },
1852
- channel: { type: "string", default: "stable" },
1978
+ channel: { type: "string" },
1853
1979
  root: { type: "string" },
1854
1980
  config: { type: "string" },
1855
1981
  "skill-dir": { type: "string", multiple: true },
1856
1982
  "update-policy": { type: "string" },
1857
1983
  "no-path": { type: "boolean" },
1858
1984
  "verify-connection": { type: "boolean" },
1985
+ "adopt-update-source": { type: "boolean" },
1859
1986
  json: { type: "boolean" },
1860
1987
  human: { type: "boolean" }
1861
1988
  }
1862
1989
  });
1863
1990
  onFormat?.(values.json === true);
1864
1991
  if (values.json && values.human) throw new Error("--json\u4E0E--human\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
1865
- if (!INSTALL_MODES.includes(values.mode) || !["stable", "trial"].includes(values.channel))
1866
- throw new Error("\u5B89\u88C5\u6A21\u5F0F\u6216\u901A\u9053\u65E0\u6548");
1992
+ if (values["adopt-update-source"] && !values.channel)
1993
+ throw new Error("\u8FC1\u79FB\u66F4\u65B0\u6E90\u5FC5\u987B\u663E\u5F0F\u9009\u62E9 --channel stable");
1994
+ if (!INSTALL_MODES.includes(values.mode) || values.channel !== void 0 && values.channel !== "stable")
1995
+ throw new Error("\u5B89\u88C5\u6A21\u5F0F\u6216\u901A\u9053\u65E0\u6548\uFF1B\u5F53\u524D\u5165\u53E3\u4EC5\u5B89\u88C5\u6B63\u5F0F\u7248\u672C\uFF08stable\uFF09");
1867
1996
  const arch = await nativeArchitecture();
1868
1997
  const matches = release.targets.filter(
1869
- (target2) => target2.mode === values.mode && target2.platform === process.platform && target2.arch === arch && target2.channel === values.channel
1998
+ (target2) => target2.mode === values.mode && target2.platform === process.platform && target2.arch === arch
1870
1999
  );
1871
- if (matches.length !== 1)
2000
+ if (new Set(matches.map((target2) => target2.channel)).size !== matches.length)
2001
+ throw new Error("npm\u53D1\u884C\u76EE\u6807\u91CD\u590D\uFF0C\u505C\u6B62\u5B89\u88C5");
2002
+ const target = matches.find((candidate) => candidate.channel === "stable");
2003
+ if (!target)
1872
2004
  throw new Error(
1873
- "\u5F53\u524D\u5E73\u53F0\u6CA1\u6709\u6B63\u5F0F\u76EE\u6807\uFF1B\u5982\u786E\u8BA4\u63A5\u53D7\u672A\u5B8C\u6210\u539F\u751F\u9A8C\u6536\u7684\u8BD5\u7528\u5305\uFF0C\u8BF7\u663E\u5F0F\u4F7F\u7528 --channel trial\u3002\u7F51\u7EDC\u9519\u8BEF\u4E0D\u4F1A\u81EA\u52A8\u5207\u6362\u901A\u9053\u3002"
2005
+ values.channel ? `\u5F53\u524D\u5E73\u53F0\u5728\u6307\u5B9A\u901A\u9053 ${values.channel} \u6CA1\u6709\u53EF\u7528\u5B89\u88C5\u76EE\u6807\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u5207\u6362\u901A\u9053\u3002` : "\u5F53\u524D\u5E73\u53F0\u6CA1\u6709\u53EF\u7528\u5B89\u88C5\u76EE\u6807\uFF0C\u8BF7\u6838\u5BF9\u5B89\u88C5\u6A21\u5F0F\u3001\u7CFB\u7EDF\u67B6\u6784\u4E0Enpm\u5165\u53E3\u7248\u672C\u3002"
1874
2006
  );
1875
- const target = matches[0];
1876
- if (target.channel === "trial")
1877
- process.stderr.write("\u6CE8\u610F\uFF1A\u5F53\u524D\u76EE\u6807\u4E3A\u8BD5\u7528\u901A\u9053\uFF0C\u539F\u751F\u9A8C\u6536\u672A\u5B8C\u6210\uFF0C\u4E0D\u542F\u7528\u81EA\u52A8\u5347\u7EA7\u3002\n");
1878
2007
  const root = resolve2(values.root ?? defaultInstallRoot(target.mode));
1879
2008
  const previous = await readPrivateInstallationFile(root);
1880
2009
  process.stderr.write(
@@ -1888,6 +2017,8 @@ async function installFromNpm(release, argv, onFormat) {
1888
2017
  if (data.schema_version !== 1 || !Array.isArray(data.artifacts) || data.artifacts.length !== 1)
1889
2018
  throw new Error("\u56FA\u5B9A\u6E05\u5355\u5FC5\u987B\u53EA\u6709\u4E00\u4E2A\u76EE\u6807");
1890
2019
  const artifact = validateArtifact(data.artifacts[0]);
2020
+ if (artifact.version !== release.version)
2021
+ throw new Error("npm\u5165\u53E3\u4E0E\u5BA2\u6237\u7AEF\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u505C\u6B62\u5B89\u88C5");
1891
2022
  if (artifact.build_id !== target.build_id || artifact.mode !== target.mode || artifact.platform !== target.platform || artifact.arch !== target.arch)
1892
2023
  throw new Error("npm\u76EE\u6807\u4E0E\u5236\u54C1\u8EAB\u4EFD\u4E0D\u4E00\u81F4");
1893
2024
  if (previous && Number(previous.release_sequence) > artifact.release_sequence)
@@ -1930,10 +2061,7 @@ async function installFromNpm(release, argv, onFormat) {
1930
2061
  installerArguments.push("--skill-dir", directory);
1931
2062
  if (values["no-path"]) installerArguments.push("--no-path");
1932
2063
  if (values["verify-connection"]) installerArguments.push("--verify-connection");
1933
- if (target.channel === "trial") {
1934
- if (values["update-policy"] === "auto") throw new Error("\u8BD5\u7528\u76EE\u6807\u7981\u6B62\u81EA\u52A8\u5347\u7EA7");
1935
- installerArguments.push("--update-policy", "off");
1936
- }
2064
+ if (values["adopt-update-source"]) installerArguments.push("--adopt-update-source");
1937
2065
  const status = await runNpmChild(
1938
2066
  join3(application, process.platform === "win32" ? "runtime/node.exe" : "runtime/node"),
1939
2067
  [join3(application, "dist/service/installation/install.entry.js"), ...installerArguments]
@@ -1944,7 +2072,7 @@ async function installFromNpm(release, argv, onFormat) {
1944
2072
  throw new Error("\u5B89\u88C5\u56DE\u6267\u4E0E\u76EE\u6807\u4E0D\u4E00\u81F4");
1945
2073
  return 0;
1946
2074
  } finally {
1947
- await rm(stage, { recursive: true, force: true });
2075
+ await cleanupInstallationStaging(stage);
1948
2076
  }
1949
2077
  }
1950
2078
  async function forwardNpmCommand(argv) {
@@ -1963,8 +2091,7 @@ async function forwardNpmCommand(argv) {
1963
2091
  const application = await realpath2(
1964
2092
  process.platform === "win32" ? expectedApplication : join3(root, "current")
1965
2093
  );
1966
- if (application !== expectedApplication)
1967
- throw new Error("\u7248\u672C\u6307\u9488\u4E0E\u56DE\u6267\u4E0D\u4E00\u81F4");
2094
+ if (application !== expectedApplication) throw new Error("\u7248\u672C\u6307\u9488\u4E0E\u56DE\u6267\u4E0D\u4E00\u81F4");
1968
2095
  return runNpmChild(
1969
2096
  join3(application, process.platform === "win32" ? "runtime/node.exe" : "runtime/node"),
1970
2097
  [join3(application, "dist/service/installation/update.entry.js"), "--root", root, "--", ...argv]
@@ -1985,9 +2112,11 @@ async function main() {
1985
2112
  process.stdout.write(
1986
2113
  `\u65F7\u4E16\u4F20\u58F0 CLI \u5B89\u88C5\u5165\u53E3
1987
2114
 
1988
- \u7528\u6CD5\uFF1Anpx ${NPM_PACKAGE_NAME}@latest install [--mode personal|team] [--channel stable|trial]
2115
+ \u7528\u6CD5\uFF1Anpx ${NPM_PACKAGE_NAME}@latest install [--mode personal|team] [--channel stable]
1989
2116
  \u53EF\u9009\uFF1A--root \u79C1\u6709\u76EE\u5F55 --config \u5DF2\u6709\u914D\u7F6E --skill-dir \u6280\u80FD\u76EE\u5F55 --update-policy off|notify|auto --no-path
2117
+ \u8FC1\u79FB\u66F4\u65B0\u6E90\uFF1A--adopt-update-source\uFF08\u5FC5\u987B\u540C\u65F6\u6307\u5B9A --channel stable\uFF09
1990
2118
 
2119
+ \u9ED8\u8BA4\u5B89\u88C5\u5168\u90E8\u968F\u5305Skill\uFF1BAI\u987B\u6309\u56DE\u6267\u6838\u9A8C\u5BBF\u4E3B\u542F\u7528\u5E76\u8BFB\u53D6\u65B0\u7248SKILL.md\u3002
1991
2120
  \u5B89\u88C5\u540E\uFF1Akscs --version\uFF1Bkscs auth login\uFF1Bkscs products list
1992
2121
  \u65E0\u9700Python\u3001Java\u6216\u7F16\u8BD1\u5668\u3002\u6CA1\u6709Node\u8BF7\u8BBF\u95EE https://cli.xaweiju.com/install/
1993
2122
  \u5378\u8F7Dnpm\u5165\u53E3\u4E0D\u4F1A\u5220\u9664\u5B9E\u9645\u5BA2\u6237\u7AEF\u3001\u8EAB\u4EFD\u914D\u7F6E\u6216Skill\u3002
@@ -2006,10 +2135,9 @@ async function main() {
2006
2135
  });
2007
2136
  }
2008
2137
  void main().catch((error) => {
2009
- const message = error instanceof Error ? error.message : String(error);
2010
- process.stderr.write(
2011
- jsonOutput ? JSON.stringify({ installed: false, status: "installation_failed", message }) + "\n" : `\u5B89\u88C5\u5165\u53E3\u5931\u8D25\uFF1A${message}
2012
- `
2013
- );
2014
- process.exitCode = 1;
2138
+ const result = failure(error instanceof CliError ? error : new CliError("INSTALLATION_FAILED", error instanceof Error ? error.message : "\u5B89\u88C5\u5165\u53E3\u5931\u8D25", "CONTACT_SUPPORT"));
2139
+ const errorOutput = result.envelope.error;
2140
+ const message = errorOutput.message.replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
2141
+ process.stderr.write(jsonOutput ? JSON.stringify(result.envelope) + "\n" : "\u9519\u8BEF\uFF1A" + message + "\n");
2142
+ process.exitCode = result.exit;
2015
2143
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kscs-inc/cli",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "description": "旷世传声 CLI 官方安装入口:中文引导、签名校验、公司客户端安装。",
5
5
  "type": "module",
6
6
  "bin": {
package/release.json CHANGED
@@ -1,79 +1,79 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "name": "@kscs-inc/cli",
4
- "version": "0.3.5",
4
+ "version": "0.4.0",
5
5
  "targets": [
6
6
  {
7
7
  "mode": "personal",
8
8
  "platform": "darwin",
9
- "arch": "x64",
10
- "channel": "stable",
11
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261025-094324-6a216831/manifest.json",
12
- "manifest_sha256": "509dc77014d55a99f037ced9e468f537c7f3e1584ce9fba0590437221fb87204",
13
- "build_id": "20261025-094324-6a216831"
14
- },
15
- {
16
- "mode": "team",
17
- "platform": "linux",
18
- "arch": "x64",
9
+ "arch": "arm64",
19
10
  "channel": "stable",
20
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261025-094459-bffbfb5d/manifest.json",
21
- "manifest_sha256": "71412b4b44a05135b3d9911c2c5dd9d99a430b57c8d011802b39cf623fbc3552",
22
- "build_id": "20261025-094459-bffbfb5d"
11
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003210-a6be6f68/manifest.json",
12
+ "manifest_sha256": "1ab7e67891349798e303b89f305b75ec74a2e0dae49ead8142f4efb923aeec51",
13
+ "build_id": "20261027-003210-a6be6f68"
23
14
  },
24
15
  {
25
16
  "mode": "personal",
26
17
  "platform": "darwin",
27
- "arch": "arm64",
28
- "channel": "trial",
29
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/trial/20261025-094313-47d1ddfd/manifest.json",
30
- "manifest_sha256": "6fd6d2aed977b9911e76619b06b30bde542a75a3b261e456c022c430e50b6caf",
31
- "build_id": "20261025-094313-47d1ddfd"
18
+ "arch": "x64",
19
+ "channel": "stable",
20
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003218-f6c9db82/manifest.json",
21
+ "manifest_sha256": "e4fe53150f2e509be8a94a68e2ff95f3cd47529b1c593dd548665391de4677c0",
22
+ "build_id": "20261027-003218-f6c9db82"
32
23
  },
33
24
  {
34
25
  "mode": "personal",
35
26
  "platform": "linux",
36
27
  "arch": "arm64",
37
- "channel": "trial",
38
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/trial/20261025-094340-4e3697dd/manifest.json",
39
- "manifest_sha256": "a163360a975210639ae6b44752530ddcbad88c085e5c7c1101c7f396fd696fb7",
40
- "build_id": "20261025-094340-4e3697dd"
28
+ "channel": "stable",
29
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003229-d40918cc/manifest.json",
30
+ "manifest_sha256": "f5b064923e98e836b4ddc9452556257a2edf121227c70fe3c147a14b4e844ac8",
31
+ "build_id": "20261027-003229-d40918cc"
41
32
  },
42
33
  {
43
34
  "mode": "personal",
44
35
  "platform": "linux",
45
36
  "arch": "x64",
46
- "channel": "trial",
47
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/trial/20261025-094358-3996bdc3/manifest.json",
48
- "manifest_sha256": "8e11b1749d968fcca2b0177654cb26ef07fe11a4b5dd5a8314cfce6ba33dfc7d",
49
- "build_id": "20261025-094358-3996bdc3"
37
+ "channel": "stable",
38
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003236-7cebb69c/manifest.json",
39
+ "manifest_sha256": "20fa4cf52b7a362e30f0f9f7b3bf1e630e683b24645ceedffeb5e8f44e062c17",
40
+ "build_id": "20261027-003236-7cebb69c"
50
41
  },
51
42
  {
52
43
  "mode": "personal",
53
44
  "platform": "win32",
54
45
  "arch": "arm64",
55
- "channel": "trial",
56
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/trial/20261025-094414-cc841444/manifest.json",
57
- "manifest_sha256": "d8a0388075fee005133c47c7b66ca0644280b6b27c3f4f67c1ae88917cd7e6b9",
58
- "build_id": "20261025-094414-cc841444"
46
+ "channel": "stable",
47
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003243-28937214/manifest.json",
48
+ "manifest_sha256": "38d45bf0b962308bc79b5e2c6acc8d941217f2586184f117c9cbd9aa1aa1ee7b",
49
+ "build_id": "20261027-003243-28937214"
59
50
  },
60
51
  {
61
52
  "mode": "personal",
62
53
  "platform": "win32",
63
54
  "arch": "x64",
64
- "channel": "trial",
65
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/trial/20261025-094430-72e23d4c/manifest.json",
66
- "manifest_sha256": "c0e4345068a4a88b05400fb015be6af4a9e0fe3cd94c664a9d8648e6703e08cc",
67
- "build_id": "20261025-094430-72e23d4c"
55
+ "channel": "stable",
56
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003249-7394c20b/manifest.json",
57
+ "manifest_sha256": "572a7940dacc0bade3a3e9cf23fde31fccc2bbef33517ebbdc605d716d791f47",
58
+ "build_id": "20261027-003249-7394c20b"
68
59
  },
69
60
  {
70
61
  "mode": "team",
71
62
  "platform": "linux",
72
63
  "arch": "arm64",
73
- "channel": "trial",
74
- "manifest": "https://cli.xaweiju.com/downloads/cli/node/trial/20261025-094444-62377ef8/manifest.json",
75
- "manifest_sha256": "23482fcd6de75844b428b9dd12277e4f6108b7ce6e4542f7d1c137b3f4edaf83",
76
- "build_id": "20261025-094444-62377ef8"
64
+ "channel": "stable",
65
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003255-61679633/manifest.json",
66
+ "manifest_sha256": "1d3f672a0c12035e7b313620fc426c12b6d9c0927d3ac8f82407a0960974926f",
67
+ "build_id": "20261027-003255-61679633"
68
+ },
69
+ {
70
+ "mode": "team",
71
+ "platform": "linux",
72
+ "arch": "x64",
73
+ "channel": "stable",
74
+ "manifest": "https://cli.xaweiju.com/downloads/cli/node/20261027-003302-ae379fe0/manifest.json",
75
+ "manifest_sha256": "8627a3dd783342d88890d2dc81579fa75cbbfd97eacbbd67eb2997aa001ce9e0",
76
+ "build_id": "20261027-003302-ae379fe0"
77
77
  }
78
78
  ]
79
79
  }
@@ -1 +1 @@
1
- {"algorithm":"Ed25519","key_id":"kscs-release-20261023","payload":"eyJzY2hlbWFfdmVyc2lvbiI6MSwicGF0aCI6Ii9kb3dubG9hZHMvY2xpL25vZGUvbnBtLzAuMy41L3JlbGVhc2UuanNvbiIsInNoYTI1NiI6IjRiZjgzZjNhMzJjMGUyNTU5MDk1ZDI4ODkzZGZkZTlkNjYyNjZhYmRmNWM2MjRhOTliZWM5NWY5ZjE2MjAxNGYiLCJpc3N1ZWRfYXQiOjE3OTI4OTMyNzAsImV4cGlyZXNfYXQiOjE4MjQ0MjkyNzB9","signature":"SMsSTUAzimrmORP3Pss+V45hq56iFhTmeJICUTl5Tz9SfTP3HX/qOoe0uIiZZ2d9YrW0kFDDSyHlR+s9ozh1CQ=="}
1
+ {"algorithm":"Ed25519","key_id":"kscs-release-20261023","payload":"eyJzY2hlbWFfdmVyc2lvbiI6MSwicGF0aCI6Ii9kb3dubG9hZHMvY2xpL25vZGUvbnBtLzAuNC4wL3JlbGVhc2UuanNvbiIsInNoYTI1NiI6ImI0N2NiMDBkY2Y4Y2MzOGI3MzY4ZGFhNTI4NmFhN2MwMWM5NjM4NDZjMmEzOTIxMjNhYWYzMjhlMWM1MTVhMGUiLCJpc3N1ZWRfYXQiOjE3OTMwNjk2MzgsImV4cGlyZXNfYXQiOjE4MjQ2MDU2Mzh9","signature":"ltNXDwF/fmQ4JCbSbAq6zp3SiuwsazEShBI1BYavDkqerWMl+lUEtJZo5jTFO8IGElqd8aVNLj2n3z0KtmbnDA=="}