@zrhsh/wukong-cli 0.4.10 → 0.4.13

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.
Files changed (3) hide show
  1. package/dist/cli.js +391 -73
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +72 -72
package/dist/cli.js CHANGED
@@ -141,6 +141,7 @@ var init_config = __esm({
141
141
  DEVICE_AUTHORIZE: "/oceanet-auth/pkce/device/authorize",
142
142
  DEVICE_TOKEN: "/oceanet-auth/pkce/device/token",
143
143
  REFRESH_TOKEN: "/oceanet-auth/manage/refreshToken",
144
+ REFRESH_TOKEN_NRP: "/oceanet-auth/manage/refreshTokenNRP",
144
145
  LOGOUT: "/oceanet-auth/manage/logout"
145
146
  },
146
147
  API: {
@@ -491,14 +492,18 @@ var init_device_flow_service = __esm({
491
492
  refresh_token,
492
493
  expires_in,
493
494
  token_type,
494
- scope
495
+ scope,
496
+ yst_access_token,
497
+ yst_refresh_token
495
498
  } = data.result;
496
499
  return {
497
500
  accessToken: access_token,
498
501
  refreshToken: refresh_token,
499
502
  expiresIn: expires_in,
500
503
  tokenType: token_type,
501
- scope: Array.isArray(scope) ? scope : [scope || ""]
504
+ scope: Array.isArray(scope) ? scope : [scope || ""],
505
+ ...yst_access_token ? { ystAccessToken: yst_access_token } : {},
506
+ ...yst_refresh_token ? { ystRefreshToken: yst_refresh_token } : {}
502
507
  };
503
508
  }
504
509
  throw new Error("Authorization timed out. Please try again.");
@@ -733,19 +738,31 @@ var init_token_cache = __esm({
733
738
  MemoryTokenCache = class {
734
739
  accessToken = null;
735
740
  refreshToken = null;
741
+ ystAccessToken = null;
742
+ ystRefreshToken = null;
736
743
  getAccessToken() {
737
744
  return this.accessToken;
738
745
  }
739
746
  getRefreshToken() {
740
747
  return this.refreshToken;
741
748
  }
742
- setTokens(accessToken, refreshToken) {
749
+ getYstAccessToken() {
750
+ return this.ystAccessToken;
751
+ }
752
+ getYstRefreshToken() {
753
+ return this.ystRefreshToken;
754
+ }
755
+ setTokens(accessToken, refreshToken, ystAccessToken, ystRefreshToken) {
743
756
  if (accessToken !== null) this.accessToken = accessToken;
744
757
  if (refreshToken !== null) this.refreshToken = refreshToken;
758
+ if (ystAccessToken !== void 0 && ystAccessToken !== null) this.ystAccessToken = ystAccessToken;
759
+ if (ystRefreshToken !== void 0 && ystRefreshToken !== null) this.ystRefreshToken = ystRefreshToken;
745
760
  }
746
761
  clear() {
747
762
  this.accessToken = null;
748
763
  this.refreshToken = null;
764
+ this.ystAccessToken = null;
765
+ this.ystRefreshToken = null;
749
766
  }
750
767
  hasAccessToken() {
751
768
  return this.accessToken !== null && this.accessToken.length > 0;
@@ -1106,27 +1123,21 @@ init_oceanet();
1106
1123
  init_debug();
1107
1124
  import ora2 from "ora";
1108
1125
  var TokenManager = class {
1109
- /**
1110
- * 构造函数
1111
- * @param credentialStore 凭据存储实例
1112
- * @param tokenCache token 缓存实例
1113
- */
1114
1126
  constructor(credentialStore, tokenCache) {
1115
1127
  this.credentialStore = credentialStore;
1116
1128
  this.tokenCache = tokenCache;
1117
1129
  }
1118
- /**
1119
- * 保存 Token
1120
- */
1121
- async saveToken(accessToken, refreshToken) {
1130
+ async saveToken(options) {
1122
1131
  const config = getOceanetConfig();
1123
- await this.credentialStore.setPassword(config.SERVICE_NAME, "access_token", accessToken);
1124
- await this.credentialStore.setPassword(config.SERVICE_NAME, "refresh_token", refreshToken);
1125
- this.tokenCache.setTokens(accessToken, refreshToken);
1132
+ const { accessToken, refreshToken, ystAccessToken, ystRefreshToken } = options;
1133
+ await Promise.all([
1134
+ this.credentialStore.setPassword(config.SERVICE_NAME, "access_token", accessToken),
1135
+ this.credentialStore.setPassword(config.SERVICE_NAME, "refresh_token", refreshToken),
1136
+ ...ystAccessToken ? [this.credentialStore.setPassword(config.SERVICE_NAME, "yst_access_token", ystAccessToken)] : [],
1137
+ ...ystRefreshToken ? [this.credentialStore.setPassword(config.SERVICE_NAME, "yst_refresh_token", ystRefreshToken)] : []
1138
+ ]);
1139
+ this.tokenCache.setTokens(accessToken, refreshToken, ystAccessToken ?? null, ystRefreshToken ?? null);
1126
1140
  }
1127
- /**
1128
- * 获取 Access Token
1129
- */
1130
1141
  async getAccessToken() {
1131
1142
  const cached = this.tokenCache.getAccessToken();
1132
1143
  if (cached) {
@@ -1139,9 +1150,6 @@ var TokenManager = class {
1139
1150
  }
1140
1151
  return token;
1141
1152
  }
1142
- /**
1143
- * 获取 Refresh Token
1144
- */
1145
1153
  async getRefreshToken() {
1146
1154
  const cached = this.tokenCache.getRefreshToken();
1147
1155
  if (cached) {
@@ -1154,9 +1162,30 @@ var TokenManager = class {
1154
1162
  }
1155
1163
  return token;
1156
1164
  }
1157
- /**
1158
- * 刷新 Token
1159
- */
1165
+ async getYstAccessToken() {
1166
+ const cached = this.tokenCache.getYstAccessToken();
1167
+ if (cached) {
1168
+ return cached;
1169
+ }
1170
+ const config = getOceanetConfig();
1171
+ const token = await this.credentialStore.getPassword(config.SERVICE_NAME, "yst_access_token");
1172
+ if (token) {
1173
+ this.tokenCache.setTokens(null, null, token, null);
1174
+ }
1175
+ return token;
1176
+ }
1177
+ async getYstRefreshToken() {
1178
+ const cached = this.tokenCache.getYstRefreshToken();
1179
+ if (cached) {
1180
+ return cached;
1181
+ }
1182
+ const config = getOceanetConfig();
1183
+ const token = await this.credentialStore.getPassword(config.SERVICE_NAME, "yst_refresh_token");
1184
+ if (token) {
1185
+ this.tokenCache.setTokens(null, null, null, token);
1186
+ }
1187
+ return token;
1188
+ }
1160
1189
  async refreshAccessToken(refreshToken) {
1161
1190
  const spinner = ora2("Refreshing access token...").start();
1162
1191
  try {
@@ -1185,7 +1214,9 @@ var TokenManager = class {
1185
1214
  refresh_token: new_refresh_token,
1186
1215
  expires_in,
1187
1216
  token_type,
1188
- scope
1217
+ scope,
1218
+ yst_access_token,
1219
+ yst_refresh_token: yst_new_refresh_token
1189
1220
  } = data.result;
1190
1221
  spinner.succeed("Token refreshed");
1191
1222
  return {
@@ -1193,38 +1224,78 @@ var TokenManager = class {
1193
1224
  refreshToken: new_refresh_token,
1194
1225
  expiresIn: expires_in,
1195
1226
  tokenType: token_type,
1196
- scope: Array.isArray(scope) ? scope : [scope || ""]
1227
+ scope: Array.isArray(scope) ? scope : [scope || ""],
1228
+ ...yst_access_token ? { ystAccessToken: yst_access_token } : {},
1229
+ ...yst_new_refresh_token ? { ystRefreshToken: yst_new_refresh_token } : {}
1197
1230
  };
1198
1231
  } catch (error) {
1199
1232
  spinner.fail("Token refresh error");
1200
1233
  throw error;
1201
1234
  }
1202
1235
  }
1203
- /**
1204
- * 清除本地 Token
1205
- */
1236
+ async refreshYstAccessToken(ystRefreshToken) {
1237
+ const spinner = ora2("Refreshing YST access token...").start();
1238
+ try {
1239
+ const config = getOceanetConfig();
1240
+ const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN_NRP}`;
1241
+ const requestHeaders = {
1242
+ "Content-Type": "application/json"
1243
+ };
1244
+ const requestBody = { param: ystRefreshToken };
1245
+ debugRequest("POST", url, requestHeaders, requestBody);
1246
+ const startTime = Date.now();
1247
+ const response = await fetch(url, {
1248
+ method: "POST",
1249
+ headers: requestHeaders,
1250
+ body: JSON.stringify(requestBody)
1251
+ });
1252
+ const duration = Date.now() - startTime;
1253
+ const data = await response.json();
1254
+ debugResponse(response.status, response.statusText, data, duration);
1255
+ if (data.code !== 200) {
1256
+ spinner.fail("YST token refresh failed");
1257
+ throw new Error(data.message || "YST refresh token failed");
1258
+ }
1259
+ const { access_token, refresh_token } = data.result;
1260
+ spinner.succeed("YST token refreshed");
1261
+ return {
1262
+ ystAccessToken: access_token,
1263
+ ystRefreshToken: refresh_token
1264
+ };
1265
+ } catch (error) {
1266
+ spinner.fail("YST token refresh error");
1267
+ throw error;
1268
+ }
1269
+ }
1206
1270
  async clearTokens() {
1207
1271
  const config = getOceanetConfig();
1208
- await this.credentialStore.deletePassword(config.SERVICE_NAME, "access_token");
1209
- await this.credentialStore.deletePassword(config.SERVICE_NAME, "refresh_token");
1272
+ await Promise.all([
1273
+ this.credentialStore.deletePassword(config.SERVICE_NAME, "access_token"),
1274
+ this.credentialStore.deletePassword(config.SERVICE_NAME, "refresh_token"),
1275
+ this.credentialStore.deletePassword(config.SERVICE_NAME, "yst_access_token"),
1276
+ this.credentialStore.deletePassword(config.SERVICE_NAME, "yst_refresh_token")
1277
+ ]);
1210
1278
  this.tokenCache.clear();
1211
1279
  }
1212
- /**
1213
- * 退出登录
1214
- */
1215
- async logout(accessToken) {
1280
+ async logout(accessToken, ocAccessToken) {
1216
1281
  try {
1217
1282
  const config = getOceanetConfig();
1218
1283
  const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`;
1219
1284
  const requestHeaders = {
1220
- "Content-Type": "application/json",
1221
- "Authorization": `Bearer ${accessToken}`
1285
+ "Content-Type": "application/json"
1222
1286
  };
1223
- debugRequest("POST", url, requestHeaders);
1287
+ const requestBody = {
1288
+ access_token: accessToken
1289
+ };
1290
+ if (ocAccessToken) {
1291
+ requestBody.oc_access_token = ocAccessToken;
1292
+ }
1293
+ debugRequest("POST", url, requestHeaders, requestBody);
1224
1294
  const startTime = Date.now();
1225
1295
  const response = await fetch(url, {
1226
1296
  method: "POST",
1227
- headers: requestHeaders
1297
+ headers: requestHeaders,
1298
+ body: JSON.stringify(requestBody)
1228
1299
  });
1229
1300
  const duration = Date.now() - startTime;
1230
1301
  let data;
@@ -1237,18 +1308,21 @@ var TokenManager = class {
1237
1308
  }
1238
1309
  await this.clearTokens();
1239
1310
  }
1240
- /**
1241
- * 初始化 Token 缓存
1242
- * 从持久化存储加载 token 到内存缓存
1243
- */
1244
1311
  async initTokenCache() {
1245
1312
  const config = getOceanetConfig();
1246
- const [accessToken, refreshToken] = await Promise.all([
1313
+ const [accessToken, refreshToken, ystAccessToken, ystRefreshToken] = await Promise.all([
1247
1314
  this.credentialStore.getPassword(config.SERVICE_NAME, "access_token"),
1248
- this.credentialStore.getPassword(config.SERVICE_NAME, "refresh_token")
1315
+ this.credentialStore.getPassword(config.SERVICE_NAME, "refresh_token"),
1316
+ this.credentialStore.getPassword(config.SERVICE_NAME, "yst_access_token"),
1317
+ this.credentialStore.getPassword(config.SERVICE_NAME, "yst_refresh_token")
1249
1318
  ]);
1250
- if (accessToken || refreshToken) {
1251
- this.tokenCache.setTokens(accessToken || null, refreshToken || null);
1319
+ if (accessToken || refreshToken || ystAccessToken || ystRefreshToken) {
1320
+ this.tokenCache.setTokens(
1321
+ accessToken || null,
1322
+ refreshToken || null,
1323
+ ystAccessToken || null,
1324
+ ystRefreshToken || null
1325
+ );
1252
1326
  }
1253
1327
  }
1254
1328
  };
@@ -1263,17 +1337,30 @@ function getTokenManager() {
1263
1337
  }
1264
1338
  return tokenManagerInstance;
1265
1339
  }
1266
- async function saveToken(accessToken, refreshToken) {
1340
+ async function saveToken(accessTokenOrOptions, refreshToken) {
1267
1341
  const manager = getTokenManager();
1268
- await manager.saveToken(accessToken, refreshToken);
1342
+ const options = typeof accessTokenOrOptions === "string" ? { accessToken: accessTokenOrOptions, refreshToken } : accessTokenOrOptions;
1343
+ await manager.saveToken(options);
1269
1344
  }
1270
1345
  async function getAccessToken() {
1271
1346
  const manager = getTokenManager();
1272
1347
  return await manager.getAccessToken();
1273
1348
  }
1274
- async function logout(accessToken) {
1349
+ async function getRefreshToken() {
1350
+ const manager = getTokenManager();
1351
+ return await manager.getRefreshToken();
1352
+ }
1353
+ async function getYstAccessToken() {
1354
+ const manager = getTokenManager();
1355
+ return await manager.getYstAccessToken();
1356
+ }
1357
+ async function getYstRefreshToken() {
1275
1358
  const manager = getTokenManager();
1276
- await manager.logout(accessToken);
1359
+ return await manager.getYstRefreshToken();
1360
+ }
1361
+ async function logout(accessToken, ocAccessToken) {
1362
+ const manager = getTokenManager();
1363
+ await manager.logout(accessToken, ocAccessToken);
1277
1364
  }
1278
1365
 
1279
1366
  // src/core/http/client.ts
@@ -1511,7 +1598,6 @@ function createRetokenInstance(credentialStore, tokenCache) {
1511
1598
  refreshEndpoint: {
1512
1599
  url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,
1513
1600
  method: "POST",
1514
- // Oceanet API 要求: { "param": "refresh_token_string" }
1515
1601
  buildBody: (token) => JSON.stringify({ param: token }),
1516
1602
  headers: {
1517
1603
  "Content-Type": "application/json"
@@ -1547,18 +1633,18 @@ function createRetokenInstance(credentialStore, tokenCache) {
1547
1633
  }
1548
1634
  return {
1549
1635
  accessToken: result.access_token || result.accessToken,
1550
- refreshToken: result.refresh_token || result.refreshToken
1636
+ refreshToken: result.refresh_token || result.refreshToken,
1637
+ ...result.yst_access_token ? { ystAccessToken: result.yst_access_token } : {},
1638
+ ...result.yst_refresh_token ? { ystRefreshToken: result.yst_refresh_token } : {}
1551
1639
  };
1552
1640
  }
1553
1641
  },
1554
- // 从缓存获取 token(同步函数)
1555
1642
  getAccessToken: () => {
1556
1643
  return cache.getAccessToken();
1557
1644
  },
1558
1645
  getRefreshToken: () => {
1559
1646
  return cache.getRefreshToken();
1560
1647
  },
1561
- // 保存 token 到持久化存储和缓存
1562
1648
  setTokens: (tokens) => {
1563
1649
  const accessToken = tokens?.accessToken;
1564
1650
  const refreshToken = tokens?.refreshToken;
@@ -1566,10 +1652,17 @@ function createRetokenInstance(credentialStore, tokenCache) {
1566
1652
  throw new Error("Invalid tokens: missing access_token or refresh_token");
1567
1653
  }
1568
1654
  const cfg = getOceanetConfig();
1569
- cache.setTokens(accessToken, refreshToken);
1655
+ cache.setTokens(
1656
+ accessToken,
1657
+ refreshToken,
1658
+ tokens?.ystAccessToken ?? null,
1659
+ tokens?.ystRefreshToken ?? null
1660
+ );
1570
1661
  void Promise.all([
1571
1662
  store.setPassword(cfg.SERVICE_NAME, "access_token", accessToken),
1572
- store.setPassword(cfg.SERVICE_NAME, "refresh_token", refreshToken)
1663
+ store.setPassword(cfg.SERVICE_NAME, "refresh_token", refreshToken),
1664
+ ...tokens?.ystAccessToken ? [store.setPassword(cfg.SERVICE_NAME, "yst_access_token", tokens.ystAccessToken)] : [],
1665
+ ...tokens?.ystRefreshToken ? [store.setPassword(cfg.SERVICE_NAME, "yst_refresh_token", tokens.ystRefreshToken)] : []
1573
1666
  ]).catch((error) => {
1574
1667
  if (cfg.DEBUG || global.__debugMode) {
1575
1668
  console.log("");
@@ -1583,26 +1676,36 @@ function createRetokenInstance(credentialStore, tokenCache) {
1583
1676
  console.log("=== Token Saved ===");
1584
1677
  console.log("Access token saved (length:", accessToken.length, ")");
1585
1678
  console.log("Refresh token saved (length:", refreshToken.length, ")");
1679
+ if (tokens?.ystAccessToken) {
1680
+ console.log("YST access token saved (length:", tokens.ystAccessToken.length, ")");
1681
+ }
1682
+ if (tokens?.ystRefreshToken) {
1683
+ console.log("YST refresh token saved (length:", tokens.ystRefreshToken.length, ")");
1684
+ }
1586
1685
  console.log("");
1587
1686
  }
1588
1687
  },
1589
- // 清除 token
1590
1688
  clearTokens: async () => {
1591
1689
  const cfg = getOceanetConfig();
1592
- await store.deletePassword(cfg.SERVICE_NAME, "access_token");
1593
- await store.deletePassword(cfg.SERVICE_NAME, "refresh_token");
1690
+ await Promise.all([
1691
+ store.deletePassword(cfg.SERVICE_NAME, "access_token"),
1692
+ store.deletePassword(cfg.SERVICE_NAME, "refresh_token"),
1693
+ store.deletePassword(cfg.SERVICE_NAME, "yst_access_token"),
1694
+ store.deletePassword(cfg.SERVICE_NAME, "yst_refresh_token")
1695
+ ]);
1594
1696
  cache.clear();
1595
1697
  },
1596
- // 提前 1 分钟(60 秒)主动刷新
1597
1698
  expirationLeeway: 60,
1598
- // 401 时触发重试
1599
1699
  retryStatuses: [401],
1600
- // 认证完全失败时的回调
1601
1700
  onAuthFailure: async () => {
1602
1701
  const cfg = getOceanetConfig();
1603
1702
  try {
1604
- await store.deletePassword(cfg.SERVICE_NAME, "access_token");
1605
- await store.deletePassword(cfg.SERVICE_NAME, "refresh_token");
1703
+ await Promise.all([
1704
+ store.deletePassword(cfg.SERVICE_NAME, "access_token"),
1705
+ store.deletePassword(cfg.SERVICE_NAME, "refresh_token"),
1706
+ store.deletePassword(cfg.SERVICE_NAME, "yst_access_token"),
1707
+ store.deletePassword(cfg.SERVICE_NAME, "yst_refresh_token")
1708
+ ]);
1606
1709
  cache.clear();
1607
1710
  } catch {
1608
1711
  }
@@ -1659,9 +1762,19 @@ var AuthenticatingHttpClient = class {
1659
1762
  async refreshTokenAndPersist(retoken = getRetoken()) {
1660
1763
  const tokens = await retoken.refreshToken();
1661
1764
  if (tokens?.accessToken && tokens?.refreshToken) {
1662
- this.tokenCache.setTokens(tokens.accessToken, tokens.refreshToken);
1765
+ this.tokenCache.setTokens(
1766
+ tokens.accessToken,
1767
+ tokens.refreshToken,
1768
+ tokens.ystAccessToken ?? null,
1769
+ tokens.ystRefreshToken ?? null
1770
+ );
1663
1771
  const tokenManager = getTokenManager();
1664
- await tokenManager.saveToken(tokens.accessToken, tokens.refreshToken);
1772
+ await tokenManager.saveToken({
1773
+ accessToken: tokens.accessToken,
1774
+ refreshToken: tokens.refreshToken,
1775
+ ystAccessToken: tokens.ystAccessToken,
1776
+ ystRefreshToken: tokens.ystRefreshToken
1777
+ });
1665
1778
  }
1666
1779
  }
1667
1780
  /**
@@ -1954,7 +2067,12 @@ authCommands.command("login").description("Login using Device Authorization Flow
1954
2067
  console.log(chalk5.dim("\u2550".repeat(50)));
1955
2068
  console.log("");
1956
2069
  const tokens = await adapter.pollToken(deviceCode);
1957
- await saveToken(tokens.accessToken, tokens.refreshToken);
2070
+ await saveToken({
2071
+ accessToken: tokens.accessToken,
2072
+ refreshToken: tokens.refreshToken,
2073
+ ystAccessToken: tokens.ystAccessToken,
2074
+ ystRefreshToken: tokens.ystRefreshToken
2075
+ });
1958
2076
  console.log("");
1959
2077
  console.log(chalk5.bgGreen.black.bold(" [OK] Login Successful "));
1960
2078
  console.log("");
@@ -1985,8 +2103,9 @@ authCommands.command("logout").description("Logout and clear saved tokens").acti
1985
2103
  const envConfig = allEnvs[env];
1986
2104
  try {
1987
2105
  const accessToken = await getAccessToken();
2106
+ const ystAccessToken = await getYstAccessToken();
1988
2107
  if (accessToken) {
1989
- await logout(accessToken);
2108
+ await logout(accessToken, ystAccessToken ?? void 0);
1990
2109
  }
1991
2110
  console.log("");
1992
2111
  console.log(chalk5.green(`[OK] Logged out from ${env}`), chalk5.dim(`(${envConfig.displayName})`));
@@ -2099,6 +2218,165 @@ authCommands.command("status").description("Show authentication status").action(
2099
2218
  console.log("");
2100
2219
  }
2101
2220
  });
2221
+ authCommands.command("token").description("Display current token structure and JWT payload claims").action(async () => {
2222
+ console.log("");
2223
+ const env = getCurrentEnvironment();
2224
+ const allEnvs = getAllEnvironments();
2225
+ setCurrentEnvironment(env);
2226
+ const envConfig = allEnvs[env];
2227
+ try {
2228
+ let decodeJwt2 = function(token) {
2229
+ try {
2230
+ const parts = token.split(".");
2231
+ if (parts.length !== 3) return null;
2232
+ const header = JSON.parse(Buffer.from(parts[0], "base64url").toString("utf-8"));
2233
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf-8"));
2234
+ return { header, payload };
2235
+ } catch {
2236
+ return null;
2237
+ }
2238
+ };
2239
+ var decodeJwt = decodeJwt2;
2240
+ const config = getOceanetConfig();
2241
+ const accessToken = await getAccessToken();
2242
+ const refreshToken = await getRefreshToken();
2243
+ if (!accessToken) {
2244
+ console.log(chalk5.yellow("[ERROR] Not authenticated"));
2245
+ console.log("");
2246
+ printEnvironmentInfo(env, envConfig.displayName);
2247
+ console.log(chalk5.dim("Run: wukong-cli auth login"));
2248
+ console.log("");
2249
+ return;
2250
+ }
2251
+ console.log(chalk5.bgGreen.black.bold(" Token Information "));
2252
+ console.log("");
2253
+ printEnvironmentInfo(env, envConfig.displayName);
2254
+ console.log("");
2255
+ const decoded = decodeJwt2(accessToken);
2256
+ if (!decoded) {
2257
+ console.log(chalk5.yellow("[WARNING] Access token is not a valid JWT"));
2258
+ console.log("");
2259
+ console.log(chalk5.dim("Access Token (raw):"), chalk5.cyan(accessToken.substring(0, 40) + "..."));
2260
+ if (refreshToken) {
2261
+ console.log(chalk5.dim("Refresh Token:"), chalk5.cyan(refreshToken.substring(0, 20) + "..." + refreshToken.slice(-4)));
2262
+ }
2263
+ console.log("");
2264
+ return;
2265
+ }
2266
+ console.log(chalk5.bold("JWT Header:"));
2267
+ console.log(chalk5.dim(" alg:"), chalk5.cyan(String(decoded.header.alg ?? "N/A")));
2268
+ console.log(chalk5.dim(" typ:"), chalk5.cyan(String(decoded.header.typ ?? "N/A")));
2269
+ console.log("");
2270
+ console.log(chalk5.bold("JWT Payload:"));
2271
+ const skipKeys = /* @__PURE__ */ new Set(["exp", "iat", "nbf", "jti"]);
2272
+ for (const [key, value] of Object.entries(decoded.payload)) {
2273
+ if (skipKeys.has(key)) continue;
2274
+ console.log(chalk5.dim(` ${key}:`), chalk5.cyan(String(value)));
2275
+ }
2276
+ console.log("");
2277
+ const now = Date.now();
2278
+ const exp = typeof decoded.payload.exp === "number" ? decoded.payload.exp * 1e3 : null;
2279
+ const iat = typeof decoded.payload.iat === "number" ? decoded.payload.iat * 1e3 : null;
2280
+ console.log(chalk5.bold("Expiration:"));
2281
+ if (exp) {
2282
+ const expDate = new Date(exp);
2283
+ const diffMs = exp - now;
2284
+ if (diffMs <= 0) {
2285
+ console.log(chalk5.dim(" Status:"), chalk5.red("EXPIRED"));
2286
+ console.log(chalk5.dim(" Expired at:"), chalk5.red(expDate.toLocaleString()));
2287
+ } else if (diffMs < 5 * 60 * 1e3) {
2288
+ console.log(chalk5.dim(" Status:"), chalk5.yellow("Expiring soon"));
2289
+ console.log(chalk5.dim(" Expires at:"), chalk5.yellow(expDate.toLocaleString()));
2290
+ console.log(chalk5.dim(" Remaining:"), chalk5.yellow(`${Math.floor(diffMs / 6e4)} minutes`));
2291
+ } else {
2292
+ console.log(chalk5.dim(" Status:"), chalk5.green("Valid"));
2293
+ console.log(chalk5.dim(" Expires at:"), chalk5.green(expDate.toLocaleString()));
2294
+ console.log(chalk5.dim(" Remaining:"), chalk5.green(`${Math.floor(diffMs / 6e4)} minutes`));
2295
+ }
2296
+ } else {
2297
+ console.log(chalk5.dim(" exp:"), chalk5.yellow("N/A"));
2298
+ }
2299
+ if (iat) {
2300
+ console.log(chalk5.dim(" Issued at:"), chalk5.cyan(new Date(iat).toLocaleString()));
2301
+ }
2302
+ console.log("");
2303
+ if (refreshToken) {
2304
+ console.log(chalk5.bold("Refresh Token:"));
2305
+ console.log(chalk5.dim(" Token:"), chalk5.cyan(refreshToken.substring(0, 20) + "..." + refreshToken.slice(-4)));
2306
+ console.log(chalk5.dim(" Length:"), chalk5.cyan(`${refreshToken.length} characters`));
2307
+ console.log("");
2308
+ } else {
2309
+ console.log(chalk5.dim("Refresh Token:"), chalk5.yellow("Not available"));
2310
+ console.log("");
2311
+ }
2312
+ const ystAccessToken = await getYstAccessToken();
2313
+ const ystRefreshToken = await getYstRefreshToken();
2314
+ if (ystAccessToken || ystRefreshToken) {
2315
+ console.log(chalk5.bold("YST Token (NRP):"));
2316
+ if (ystAccessToken) {
2317
+ console.log(chalk5.dim(" Access Token:"), chalk5.cyan(ystAccessToken.substring(0, 20) + "..." + ystAccessToken.slice(-4)));
2318
+ console.log(chalk5.dim(" Length:"), chalk5.cyan(`${ystAccessToken.length} characters`));
2319
+ const ystDecoded = decodeJwt2(ystAccessToken);
2320
+ if (ystDecoded) {
2321
+ const ystExp = typeof ystDecoded.payload.exp === "number" ? ystDecoded.payload.exp * 1e3 : null;
2322
+ if (ystExp) {
2323
+ const ystDiffMs = ystExp - now;
2324
+ if (ystDiffMs <= 0) {
2325
+ console.log(chalk5.dim(" JWT Status:"), chalk5.red("EXPIRED"));
2326
+ console.log(chalk5.dim(" Expires at:"), chalk5.red(new Date(ystExp).toLocaleString()));
2327
+ } else if (ystDiffMs < 5 * 60 * 1e3) {
2328
+ console.log(chalk5.dim(" JWT Status:"), chalk5.yellow("Expiring soon"));
2329
+ console.log(chalk5.dim(" Expires at:"), chalk5.yellow(new Date(ystExp).toLocaleString()));
2330
+ } else {
2331
+ console.log(chalk5.dim(" JWT Status:"), chalk5.green("Valid"));
2332
+ console.log(chalk5.dim(" Expires at:"), chalk5.green(new Date(ystExp).toLocaleString()));
2333
+ console.log(chalk5.dim(" Remaining:"), chalk5.green(`${Math.floor(ystDiffMs / 6e4)} minutes`));
2334
+ }
2335
+ }
2336
+ }
2337
+ console.log(chalk5.dim(" Server:"));
2338
+ try {
2339
+ const ystVerifyUrl = `${config.API_BASE_URL}/yst-system/sys/users/current`;
2340
+ const ystResponse = await fetch(ystVerifyUrl, {
2341
+ headers: { "Authorization": `Bearer ${ystAccessToken}` }
2342
+ });
2343
+ if (ystResponse.ok) {
2344
+ console.log(chalk5.dim(" Status:"), chalk5.green("Valid (server verified)"));
2345
+ } else {
2346
+ const ystErrText = await ystResponse.text().catch(() => "");
2347
+ console.log(chalk5.dim(" Status:"), chalk5.red(`Invalid (HTTP ${ystResponse.status})`));
2348
+ if (ystErrText) {
2349
+ console.log(chalk5.dim(" Error:"), chalk5.red(ystErrText.substring(0, 100)));
2350
+ }
2351
+ }
2352
+ } catch (ystVerifyError) {
2353
+ console.log(chalk5.dim(" Status:"), chalk5.yellow("Unable to verify (network error)"));
2354
+ }
2355
+ } else {
2356
+ console.log(chalk5.dim(" Access Token:"), chalk5.yellow("Not available"));
2357
+ }
2358
+ if (ystRefreshToken) {
2359
+ console.log(chalk5.dim(" Refresh Token:"), chalk5.cyan(ystRefreshToken.substring(0, 20) + "..." + ystRefreshToken.slice(-4)));
2360
+ console.log(chalk5.dim(" Refresh Length:"), chalk5.cyan(`${ystRefreshToken.length} characters`));
2361
+ } else {
2362
+ console.log(chalk5.dim(" Refresh Token:"), chalk5.yellow("Not available"));
2363
+ }
2364
+ console.log("");
2365
+ }
2366
+ } catch (error) {
2367
+ if (error instanceof ConfigFileError) {
2368
+ console.log("");
2369
+ console.log(chalk5.red("[ERROR] Configuration Error"));
2370
+ console.log("");
2371
+ console.log(chalk5.red(error.toUserMessage()));
2372
+ console.log("");
2373
+ return;
2374
+ }
2375
+ console.log("");
2376
+ console.log(chalk5.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
2377
+ console.log("");
2378
+ }
2379
+ });
2102
2380
 
2103
2381
  // src/commands/http.ts
2104
2382
  init_esm_shims();
@@ -2158,8 +2436,48 @@ async function executeRequest(method, url, options) {
2158
2436
  }
2159
2437
  const fullUrl = buildUrl2(url, options.baseUrl);
2160
2438
  const customHeaders = parseHeaders(options.headers);
2161
- const client = getClient();
2162
2439
  const requestData = options.data ? JSON.parse(options.data) : void 0;
2440
+ const isYstRequest = fullUrl.includes("/yst-");
2441
+ if (isYstRequest) {
2442
+ const ystAccessToken = await getYstAccessToken();
2443
+ if (!ystAccessToken) {
2444
+ spinner.fail("YST token not available");
2445
+ console.error(chalk6.red("YST token not found. Please re-login: wukong-cli auth login"));
2446
+ process.exit(1);
2447
+ }
2448
+ spinner.text = `${method} ${chalk6.cyan(fullUrl)} (using YST token)`;
2449
+ const startTime2 = Date.now();
2450
+ const fetchOptions = {
2451
+ method: method.toUpperCase(),
2452
+ headers: {
2453
+ "Authorization": `Bearer ${ystAccessToken}`,
2454
+ "Content-Type": "application/json",
2455
+ ...customHeaders
2456
+ }
2457
+ };
2458
+ if (requestData) {
2459
+ fetchOptions.body = JSON.stringify(requestData);
2460
+ }
2461
+ const response = await fetch(fullUrl + parseParams(options.params), fetchOptions);
2462
+ const duration2 = Date.now() - startTime2;
2463
+ if (!response.ok) {
2464
+ const errText = await response.text().catch(() => "");
2465
+ spinner.fail(`Request failed (${response.status})`);
2466
+ console.error(chalk6.red(`HTTP ${response.status}: ${errText.substring(0, 200)}`));
2467
+ process.exit(1);
2468
+ }
2469
+ const data2 = await response.json();
2470
+ spinner.succeed("Response received");
2471
+ console.log("");
2472
+ console.log(chalk6.dim("Status:"), `${response.status} ${response.statusText}`);
2473
+ console.log(chalk6.dim("Token:"), "YST");
2474
+ console.log(chalk6.dim("Duration:"), `${duration2}ms`);
2475
+ console.log("");
2476
+ console.log(chalk6.dim("Response:"));
2477
+ console.log(JSON.stringify(data2, null, 2));
2478
+ return;
2479
+ }
2480
+ const client = getClient();
2163
2481
  spinner.text = `${method} ${chalk6.cyan(fullUrl)}`;
2164
2482
  const startTime = Date.now();
2165
2483
  let data;
@@ -2387,7 +2705,7 @@ async function runUpdateCommand({
2387
2705
  }
2388
2706
  var updateCommand = new Command4("update").description("Update wukong-cli to the latest npm version").action(async () => {
2389
2707
  const exitCode = await runUpdateCommand({
2390
- currentVersion: "0.4.10",
2708
+ currentVersion: "0.4.13",
2391
2709
  versionProvider: new NpmVersionProvider(
2392
2710
  "@zrhsh/wukong-cli",
2393
2711
  "https://registry.npmjs.org"
@@ -2402,7 +2720,7 @@ var updateCommand = new Command4("update").description("Update wukong-cli to the
2402
2720
 
2403
2721
  // src/cli.ts
2404
2722
  var program = new Command5();
2405
- program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.10").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
2723
+ program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.13").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
2406
2724
  const options = thisCommand.opts();
2407
2725
  if (options.debug === true) {
2408
2726
  setDebugMode(true, true);
@@ -2420,7 +2738,7 @@ if (process.argv.length === 2) {
2420
2738
  program.parse();
2421
2739
  setImmediate(() => {
2422
2740
  try {
2423
- const versionChecker = getVersionChecker("0.4.10");
2741
+ const versionChecker = getVersionChecker("0.4.13");
2424
2742
  const notifier = new ConsoleNotifier();
2425
2743
  versionChecker.checkInBackground(notifier).catch(() => {
2426
2744
  });