@zrhsh/wukong-cli 0.2.1 → 0.3.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
@@ -32,6 +32,38 @@ wukong-cli auth status
32
32
  wukong-cli http get "/oceanet-auth/web/userInfo"
33
33
  ```
34
34
 
35
+ ## Development
36
+
37
+ ```bash
38
+ # Clone repository
39
+ git clone <repository-url>
40
+ cd wukong-ts-cli
41
+
42
+ # Install dependencies (自动构建项目)
43
+ npm install
44
+
45
+ # Development mode (直接运行 TypeScript)
46
+ npm run dev <args>
47
+
48
+ # Build for production
49
+ npm run build
50
+
51
+ # Link globally for testing
52
+ npm run link
53
+
54
+ # Run tests
55
+ npm test
56
+
57
+ # Verify before publishing
58
+ npm run verify
59
+ ```
60
+
61
+ **注意**:项目配置了自动构建脚本(`prepare` 和 `prepack`),在 `npm install` 和 `npm publish` 时会自动构建。如果遇到 `MODULE_NOT_FOUND` 错误,请运行 `npm run build` 手动构建。
62
+
63
+ ## Deprecation Notices
64
+
65
+ ⚠️ **Device Flow API**: 某些内部 API 已标记为弃用,将在 v1.0.0 中移除。这不会影响终端用户的使用。详见 [弃用文档](./docs/deprecation/)。
66
+
35
67
  ## Commands
36
68
 
37
69
  ### Configuration Commands
@@ -116,7 +148,7 @@ wukong-cli init # Creates or resets configuration file
116
148
  },
117
149
  "dev": {
118
150
  "authBaseUrl": "https://portal-dev.zrhsh.com",
119
- "apiBaseUrl": "https://nrp-recode-dev.zrhsh.com",
151
+ "apiBaseUrl": "https://nrp-dev.zrhsh.com",
120
152
  "clientId": "wukong-cli-dev"
121
153
  }
122
154
  }
package/dist/cli.js CHANGED
@@ -363,7 +363,7 @@ var init_environments = __esm({
363
363
  name: "dev",
364
364
  displayName: "Development",
365
365
  authBaseUrl: "https://portal-dev.zrhsh.com",
366
- apiBaseUrl: "https://nrp-recode-dev.zrhsh.com",
366
+ apiBaseUrl: "https://nrp-dev.zrhsh.com",
367
367
  clientId: "wukong-cli-dev"
368
368
  },
369
369
  beta: {
@@ -432,12 +432,6 @@ function getProjectRoot() {
432
432
  return process.cwd();
433
433
  }
434
434
  function findConfigFile() {
435
- for (const filename of CONFIG_FILENAMES) {
436
- const localPath = join(process.cwd(), filename);
437
- if (existsSync(localPath)) {
438
- return localPath;
439
- }
440
- }
441
435
  const userConfigPath = getUserConfigPath();
442
436
  if (existsSync(userConfigPath)) {
443
437
  return userConfigPath;
@@ -521,18 +515,12 @@ function getDefaultEnvironment() {
521
515
  }
522
516
  return DEFAULT_ENVIRONMENT;
523
517
  }
524
- var CONFIG_FILENAMES;
525
518
  var init_config_loader = __esm({
526
519
  "src/config/config-loader.ts"() {
527
520
  "use strict";
528
521
  init_esm_shims();
529
522
  init_environments();
530
523
  init_config_file_error();
531
- CONFIG_FILENAMES = [
532
- "wukong-cli.json",
533
- ".wukong-cli.json",
534
- ".wukongclirc"
535
- ];
536
524
  }
537
525
  });
538
526
 
@@ -991,7 +979,7 @@ function getVersionChecker() {
991
979
  // src/commands/auth.ts
992
980
  init_esm_shims();
993
981
  import { Command } from "commander";
994
- import chalk5 from "chalk";
982
+ import chalk4 from "chalk";
995
983
  import ora3 from "ora";
996
984
 
997
985
  // src/utils/environment.ts
@@ -1013,11 +1001,6 @@ function printEnvironmentInfo(env, displayName) {
1013
1001
  // src/commands/auth.ts
1014
1002
  init_config_file_error();
1015
1003
 
1016
- // src/core/auth/device-flow.ts
1017
- init_esm_shims();
1018
- init_oceanet();
1019
- import chalk3 from "chalk";
1020
-
1021
1004
  // src/adapters/cli-device-flow.ts
1022
1005
  init_esm_shims();
1023
1006
  var CliDeviceFlowAdapter = class {
@@ -1067,39 +1050,6 @@ function createCliDeviceFlowAdapter() {
1067
1050
  return new CliDeviceFlowAdapter(deviceFlow, ui);
1068
1051
  }
1069
1052
 
1070
- // src/core/auth/device-flow.ts
1071
- init_device_flow_service();
1072
-
1073
- // src/adapters/ui-callbacks.ts
1074
- init_esm_shims();
1075
-
1076
- // src/core/auth/device-flow.ts
1077
- init_ora_ui_callbacks();
1078
- async function getDeviceCode() {
1079
- const config = getOceanetConfig();
1080
- const adapter = createCliDeviceFlowAdapter();
1081
- if (config.DEBUG) {
1082
- console.log("");
1083
- console.log(chalk3.dim("=== Debug Info ==="));
1084
- console.log(chalk3.dim("Getting device authorization..."));
1085
- console.log(chalk3.dim("Client ID:"), chalk3.yellow(config.CLIENT_ID));
1086
- console.log("");
1087
- }
1088
- const result = await adapter.getDeviceCode();
1089
- if (config.DEBUG) {
1090
- console.log(chalk3.dim("=== Response ==="));
1091
- console.log(chalk3.dim("Device Code:"), chalk3.yellow(result.deviceCode));
1092
- console.log(chalk3.dim("Verification URI:"), chalk3.cyan(result.verificationUri));
1093
- console.log(chalk3.dim("Expires In:"), chalk3.yellow(result.expiresIn));
1094
- console.log("");
1095
- }
1096
- return result;
1097
- }
1098
- async function pollToken(deviceCode) {
1099
- const adapter = createCliDeviceFlowAdapter();
1100
- return adapter.pollToken(deviceCode);
1101
- }
1102
-
1103
1053
  // src/core/auth/token-manager.ts
1104
1054
  init_esm_shims();
1105
1055
  init_oceanet();
@@ -1378,7 +1328,7 @@ init_esm_shims();
1378
1328
 
1379
1329
  // src/core/http/api-error-handler.ts
1380
1330
  init_esm_shims();
1381
- import chalk4 from "chalk";
1331
+ import chalk3 from "chalk";
1382
1332
  var ApiError = class extends Error {
1383
1333
  constructor(code, message, retryable = false) {
1384
1334
  super(message);
@@ -1458,12 +1408,12 @@ var ApiErrorHandler = class {
1458
1408
  async tryRecover(error, recoverFunction) {
1459
1409
  if (error instanceof ApiError && error.retryable) {
1460
1410
  console.log("");
1461
- console.log(chalk4.yellow("\u26A0 Token expired, attempting refresh..."));
1411
+ console.log(chalk3.yellow("\u26A0 Token expired, attempting refresh..."));
1462
1412
  try {
1463
1413
  return await recoverFunction();
1464
1414
  } catch (refreshError) {
1465
1415
  console.log("");
1466
- console.log(chalk4.yellow("\u26A0 Auto-refresh failed:"), chalk4.dim(refreshError.message));
1416
+ console.log(chalk3.yellow("\u26A0 Auto-refresh failed:"), chalk3.dim(refreshError.message));
1467
1417
  throw new ApiError(
1468
1418
  error.code,
1469
1419
  `${error.message} (Auto-refresh failed)`
@@ -1852,62 +1802,63 @@ authCommands.command("login").description("Login using Device Authorization Flow
1852
1802
  const config = getOceanetConfig();
1853
1803
  const envConfig = allEnvs[env];
1854
1804
  console.log("");
1855
- console.log(chalk5.bgBlue.white.bold(" Wukong CLI Login "));
1805
+ console.log(chalk4.bgBlue.white.bold(" Wukong CLI Login "));
1856
1806
  console.log("");
1857
1807
  printEnvironmentInfo(env, envConfig.displayName);
1858
1808
  console.log("");
1859
- const { verificationUri, deviceCode, expiresIn, interval } = await getDeviceCode();
1809
+ const adapter = createCliDeviceFlowAdapter();
1810
+ const { verificationUri, deviceCode, expiresIn, interval } = await adapter.getDeviceCode();
1860
1811
  console.log("");
1861
- console.log(chalk5.bold("=".repeat(50)));
1862
- console.log(chalk5.bold(" Please complete authorization"));
1863
- console.log(chalk5.bold("=".repeat(50)));
1812
+ console.log(chalk4.bold("=".repeat(50)));
1813
+ console.log(chalk4.bold(" Please complete authorization"));
1814
+ console.log(chalk4.bold("=".repeat(50)));
1864
1815
  console.log("");
1865
- console.log(chalk5.green(" Authorization URL:"));
1816
+ console.log(chalk4.green(" Authorization URL:"));
1866
1817
  console.log("");
1867
- console.log(chalk5.cyan(` ${verificationUri}`));
1818
+ console.log(chalk4.cyan(` ${verificationUri}`));
1868
1819
  console.log("");
1869
- console.error(chalk5.yellow.bold(">>> Please open this link in your browser <<<"));
1870
- console.error(chalk5.cyan(verificationUri));
1820
+ console.error(chalk4.yellow.bold(">>> Please open this link in your browser <<<"));
1821
+ console.error(chalk4.cyan(verificationUri));
1871
1822
  console.error("");
1872
1823
  const open = await import("open").catch(() => null);
1873
1824
  if (open) {
1874
1825
  try {
1875
1826
  await open.default(verificationUri);
1876
- console.log(chalk5.dim(" Browser opened automatically"));
1827
+ console.log(chalk4.dim(" Browser opened automatically"));
1877
1828
  } catch {
1878
- console.log(chalk5.dim(" Please copy link to browser"));
1829
+ console.log(chalk4.dim(" Please copy link to browser"));
1879
1830
  }
1880
1831
  } else {
1881
- console.log(chalk5.dim(" Please copy link to browser"));
1832
+ console.log(chalk4.dim(" Please copy link to browser"));
1882
1833
  }
1883
1834
  console.log("");
1884
- console.log(chalk5.dim("\u2550".repeat(50)));
1885
- console.log(chalk5.dim(` Device Code: ${deviceCode}`));
1886
- console.log(chalk5.dim(` Expires in: ${expiresIn} seconds`));
1887
- console.log(chalk5.dim("\u2550".repeat(50)));
1835
+ console.log(chalk4.dim("\u2550".repeat(50)));
1836
+ console.log(chalk4.dim(` Device Code: ${deviceCode}`));
1837
+ console.log(chalk4.dim(` Expires in: ${expiresIn} seconds`));
1838
+ console.log(chalk4.dim("\u2550".repeat(50)));
1888
1839
  console.log("");
1889
- const tokens = await pollToken(deviceCode);
1840
+ const tokens = await adapter.pollToken(deviceCode);
1890
1841
  await saveToken(tokens.accessToken, tokens.refreshToken);
1891
1842
  console.log("");
1892
- console.log(chalk5.bgGreen.black.bold(" [OK] Login Successful "));
1843
+ console.log(chalk4.bgGreen.black.bold(" [OK] Login Successful "));
1893
1844
  console.log("");
1894
- console.log(chalk5.green("[OK] Tokens saved securely"));
1845
+ console.log(chalk4.green("[OK] Tokens saved securely"));
1895
1846
  printEnvironmentInfo(env, envConfig.displayName);
1896
- console.log(chalk5.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));
1847
+ console.log(chalk4.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));
1897
1848
  console.log("");
1898
- console.log(chalk5.dim("Next:"), chalk5.cyan("wukong-cli auth status"));
1849
+ console.log(chalk4.dim("Next:"), chalk4.cyan("wukong-cli auth status"));
1899
1850
  console.log("");
1900
1851
  } catch (error) {
1901
1852
  if (error instanceof ConfigFileError) {
1902
1853
  console.log("");
1903
- console.log(chalk5.red(`[ERROR] Configuration Error`));
1854
+ console.log(chalk4.red(`[ERROR] Configuration Error`));
1904
1855
  console.log("");
1905
- console.log(chalk5.red(error.toUserMessage()));
1856
+ console.log(chalk4.red(error.toUserMessage()));
1906
1857
  console.log("");
1907
1858
  return;
1908
1859
  }
1909
1860
  console.log("");
1910
- console.log(chalk5.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1861
+ console.log(chalk4.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1911
1862
  console.log("");
1912
1863
  }
1913
1864
  });
@@ -1922,11 +1873,11 @@ authCommands.command("logout").description("Logout and clear saved tokens").acti
1922
1873
  await logout(accessToken);
1923
1874
  }
1924
1875
  console.log("");
1925
- console.log(chalk5.green(`[OK] Logged out from ${env}`), chalk5.dim(`(${envConfig.displayName})`));
1876
+ console.log(chalk4.green(`[OK] Logged out from ${env}`), chalk4.dim(`(${envConfig.displayName})`));
1926
1877
  console.log("");
1927
1878
  } catch {
1928
1879
  console.log("");
1929
- console.log(chalk5.yellow(`\u25CB Already logged out from ${env}`), chalk5.dim(`(${envConfig.displayName})`));
1880
+ console.log(chalk4.yellow(`\u25CB Already logged out from ${env}`), chalk4.dim(`(${envConfig.displayName})`));
1930
1881
  console.log("");
1931
1882
  }
1932
1883
  });
@@ -1939,10 +1890,10 @@ authCommands.command("refresh").description("Manually refresh access token").act
1939
1890
  const accessToken = await getAccessToken();
1940
1891
  if (!accessToken) {
1941
1892
  console.log("");
1942
- console.log(chalk5.yellow("[ERROR] Not authenticated"));
1893
+ console.log(chalk4.yellow("[ERROR] Not authenticated"));
1943
1894
  printEnvironmentInfo(env, envConfig.displayName);
1944
1895
  console.log("");
1945
- console.log(chalk5.dim(`Run: wukong-cli auth login`));
1896
+ console.log(chalk4.dim(`Run: wukong-cli auth login`));
1946
1897
  console.log("");
1947
1898
  return;
1948
1899
  }
@@ -1953,7 +1904,7 @@ authCommands.command("refresh").description("Manually refresh access token").act
1953
1904
  spinner.succeed("Token refreshed successfully!");
1954
1905
  console.log("");
1955
1906
  printEnvironmentInfo(env, envConfig.displayName);
1956
- console.log(chalk5.dim("New tokens saved securely"));
1907
+ console.log(chalk4.dim("New tokens saved securely"));
1957
1908
  console.log("");
1958
1909
  } catch (error) {
1959
1910
  spinner.fail("Token refresh failed");
@@ -1962,18 +1913,18 @@ authCommands.command("refresh").description("Manually refresh access token").act
1962
1913
  } catch (error) {
1963
1914
  if (error instanceof ConfigFileError) {
1964
1915
  console.log("");
1965
- console.log(chalk5.red(`[ERROR] Configuration Error`));
1916
+ console.log(chalk4.red(`[ERROR] Configuration Error`));
1966
1917
  console.log("");
1967
- console.log(chalk5.red(error.toUserMessage()));
1918
+ console.log(chalk4.red(error.toUserMessage()));
1968
1919
  console.log("");
1969
1920
  return;
1970
1921
  }
1971
1922
  console.log("");
1972
- console.log(chalk5.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1923
+ console.log(chalk4.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1973
1924
  console.log("");
1974
1925
  printEnvironmentInfo(env, envConfig.displayName);
1975
- console.log(chalk5.dim(`Your session may have expired. Please run:`));
1976
- console.log(chalk5.dim(` wukong-cli auth login`));
1926
+ console.log(chalk4.dim(`Your session may have expired. Please run:`));
1927
+ console.log(chalk4.dim(` wukong-cli auth login`));
1977
1928
  console.log("");
1978
1929
  }
1979
1930
  });
@@ -1987,10 +1938,10 @@ authCommands.command("status").description("Show authentication status").action(
1987
1938
  const config = getOceanetConfig();
1988
1939
  const accessToken = await getAccessToken();
1989
1940
  if (!accessToken) {
1990
- console.log(chalk5.yellow(`[ERROR] Not authenticated`));
1941
+ console.log(chalk4.yellow(`[ERROR] Not authenticated`));
1991
1942
  console.log("");
1992
1943
  printEnvironmentInfo(env, envConfig.displayName);
1993
- console.log(chalk5.dim(`Run: wukong-cli auth login`));
1944
+ console.log(chalk4.dim(`Run: wukong-cli auth login`));
1994
1945
  console.log("");
1995
1946
  return;
1996
1947
  }
@@ -1998,37 +1949,37 @@ authCommands.command("status").description("Show authentication status").action(
1998
1949
  const client = getClient();
1999
1950
  const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;
2000
1951
  const userInfo = await client.get(userInfoUrl);
2001
- console.log(chalk5.green("[OK] Authenticated"));
1952
+ console.log(chalk4.green("[OK] Authenticated"));
2002
1953
  console.log("");
2003
1954
  const displayUser = userInfo.firstName ? `${userInfo.firstName} (${userInfo.username})` : userInfo.username || "N/A";
2004
1955
  printEnvironmentInfo(env, envConfig.displayName);
2005
- console.log(chalk5.dim("User:"), chalk5.cyan(displayUser));
2006
- console.log(chalk5.dim("Email:"), chalk5.cyan(userInfo.email || "N/A"));
2007
- console.log(chalk5.dim("OrgCode:"), chalk5.cyan(userInfo.ouCode || "N/A"));
2008
- console.log(chalk5.dim("OrgName:"), chalk5.cyan(userInfo.ouName || "N/A"));
1956
+ console.log(chalk4.dim("User:"), chalk4.cyan(displayUser));
1957
+ console.log(chalk4.dim("Email:"), chalk4.cyan(userInfo.email || "N/A"));
1958
+ console.log(chalk4.dim("OrgCode:"), chalk4.cyan(userInfo.ouCode || "N/A"));
1959
+ console.log(chalk4.dim("OrgName:"), chalk4.cyan(userInfo.ouName || "N/A"));
2009
1960
  console.log("");
2010
1961
  } catch (error) {
2011
1962
  const errorMsg = error instanceof Error ? error.message : String(error);
2012
- console.log(chalk5.yellow(`[ERROR] Not authenticated`));
1963
+ console.log(chalk4.yellow(`[ERROR] Not authenticated`));
2013
1964
  console.log("");
2014
- console.log(chalk5.red("Error:"), chalk5.dim(errorMsg));
1965
+ console.log(chalk4.red("Error:"), chalk4.dim(errorMsg));
2015
1966
  console.log("");
2016
1967
  printEnvironmentInfo(env, envConfig.displayName);
2017
- console.log(chalk5.dim(`Run: wukong-cli auth login`));
1968
+ console.log(chalk4.dim(`Run: wukong-cli auth login`));
2018
1969
  console.log("");
2019
1970
  }
2020
1971
  } catch (error) {
2021
1972
  if (error instanceof ConfigFileError) {
2022
- console.log(chalk5.red(`[ERROR] Configuration Error`));
1973
+ console.log(chalk4.red(`[ERROR] Configuration Error`));
2023
1974
  console.log("");
2024
- console.log(chalk5.red(error.toUserMessage()));
1975
+ console.log(chalk4.red(error.toUserMessage()));
2025
1976
  console.log("");
2026
1977
  return;
2027
1978
  }
2028
- console.log(chalk5.yellow(`\u2717 Not authenticated`));
1979
+ console.log(chalk4.yellow(`\u2717 Not authenticated`));
2029
1980
  console.log("");
2030
1981
  printEnvironmentInfo(env, envConfig.displayName);
2031
- console.log(chalk5.dim(`Run: wukong-cli auth login`));
1982
+ console.log(chalk4.dim(`Run: wukong-cli auth login`));
2032
1983
  console.log("");
2033
1984
  }
2034
1985
  });
@@ -2037,7 +1988,7 @@ authCommands.command("status").description("Show authentication status").action(
2037
1988
  init_esm_shims();
2038
1989
  import { Command as Command2 } from "commander";
2039
1990
  import ora4 from "ora";
2040
- import chalk6 from "chalk";
1991
+ import chalk5 from "chalk";
2041
1992
  init_oceanet();
2042
1993
  init_debug();
2043
1994
  init_config_file_error();
@@ -2077,7 +2028,7 @@ async function executeRequest(method, url, options) {
2077
2028
  const accessToken = await getAccessToken();
2078
2029
  if (!accessToken) {
2079
2030
  spinner.fail("Not authenticated");
2080
- console.error(chalk6.red("Please run: wukong-cli auth login"));
2031
+ console.error(chalk5.red("Please run: wukong-cli auth login"));
2081
2032
  process.exit(1);
2082
2033
  }
2083
2034
  const fullUrl = buildUrl2(url, options.baseUrl);
@@ -2094,7 +2045,7 @@ async function executeRequest(method, url, options) {
2094
2045
  headers["Content-Type"] = "application/json";
2095
2046
  }
2096
2047
  }
2097
- spinner.text = `${method} ${chalk6.cyan(fullUrl)}`;
2048
+ spinner.text = `${method} ${chalk5.cyan(fullUrl)}`;
2098
2049
  debugRequest(method, fullUrl, headers, options.data ? JSON.parse(options.data) : void 0);
2099
2050
  const startTime = Date.now();
2100
2051
  const response = await fetch(fullUrl, {
@@ -2107,22 +2058,22 @@ async function executeRequest(method, url, options) {
2107
2058
  debugResponse(response.status, response.statusText, data, duration);
2108
2059
  spinner.succeed("Response received");
2109
2060
  console.log("");
2110
- console.log(chalk6.dim("Status:"), response.status, response.statusText);
2061
+ console.log(chalk5.dim("Status:"), response.status, response.statusText);
2111
2062
  console.log("");
2112
- console.log(chalk6.dim("Response:"));
2063
+ console.log(chalk5.dim("Response:"));
2113
2064
  console.log(JSON.stringify(data, null, 2));
2114
2065
  } catch (error) {
2115
2066
  spinner.fail("Request failed");
2116
2067
  if (error instanceof ConfigFileError) {
2117
2068
  console.log("");
2118
- console.log(chalk6.red(`[ERROR] Configuration Error`));
2069
+ console.log(chalk5.red(`[ERROR] Configuration Error`));
2119
2070
  console.log("");
2120
- console.log(chalk6.red(error.toUserMessage()));
2071
+ console.log(chalk5.red(error.toUserMessage()));
2121
2072
  console.log("");
2122
2073
  process.exit(1);
2123
2074
  }
2124
2075
  if (error instanceof Error) {
2125
- console.error(chalk6.red(error.message));
2076
+ console.error(chalk5.red(error.message));
2126
2077
  }
2127
2078
  process.exit(1);
2128
2079
  }
@@ -2149,7 +2100,7 @@ import { writeFileSync as writeFileSync3, existsSync as existsSync3, readFileSyn
2149
2100
  import { join as join3, dirname as dirname3 } from "path";
2150
2101
  import { homedir as homedir3 } from "os";
2151
2102
  import { fileURLToPath as fileURLToPath3 } from "url";
2152
- import chalk7 from "chalk";
2103
+ import chalk6 from "chalk";
2153
2104
  function getProjectRoot2() {
2154
2105
  let currentDir = dirname3(fileURLToPath3(import.meta.url));
2155
2106
  while (currentDir !== dirname3(currentDir)) {
@@ -2164,32 +2115,32 @@ async function executeInit() {
2164
2115
  const configPath = join3(homedir3(), "wukong-cli.json");
2165
2116
  const templatePath = join3(getProjectRoot2(), "wukong-cli.json.template");
2166
2117
  if (!existsSync3(templatePath)) {
2167
- console.error(chalk7.red("\u274C Template configuration file not found"));
2168
- console.error(chalk7.yellow(`Expected location: ${templatePath}`));
2118
+ console.error(chalk6.red("\u274C Template configuration file not found"));
2119
+ console.error(chalk6.yellow(`Expected location: ${templatePath}`));
2169
2120
  process.exit(1);
2170
2121
  }
2171
2122
  try {
2172
2123
  const templateContent = readFileSync3(templatePath, "utf-8");
2173
2124
  const configExists = existsSync3(configPath);
2174
2125
  if (configExists) {
2175
- console.log(chalk7.yellow("\u26A0\uFE0F Existing configuration file will be overwritten"));
2126
+ console.log(chalk6.yellow("\u26A0\uFE0F Existing configuration file will be overwritten"));
2176
2127
  }
2177
2128
  writeFileSync3(configPath, templateContent, "utf-8");
2178
- console.log(chalk7.green("\u2705 Configuration file created successfully"));
2179
- console.log(chalk7.gray(`Location: ${configPath}`));
2129
+ console.log(chalk6.green("\u2705 Configuration file created successfully"));
2130
+ console.log(chalk6.gray(`Location: ${configPath}`));
2180
2131
  if (configExists) {
2181
- console.log(chalk7.yellow("Previous configuration has been overwritten"));
2132
+ console.log(chalk6.yellow("Previous configuration has been overwritten"));
2182
2133
  }
2183
2134
  try {
2184
2135
  const config = JSON.parse(templateContent);
2185
- console.log(chalk7.gray("\nConfiguration preview:"));
2186
- console.log(chalk7.gray(` Default Environment: ${config.defaultEnv}`));
2187
- console.log(chalk7.gray(` Configured Environments: ${Object.keys(config.environments).join(", ")}`));
2136
+ console.log(chalk6.gray("\nConfiguration preview:"));
2137
+ console.log(chalk6.gray(` Default Environment: ${config.defaultEnv}`));
2138
+ console.log(chalk6.gray(` Configured Environments: ${Object.keys(config.environments).join(", ")}`));
2188
2139
  } catch (parseError) {
2189
2140
  }
2190
2141
  } catch (error) {
2191
- console.error(chalk7.red("\u274C Failed to create configuration file"));
2192
- console.error(chalk7.yellow(`Error: ${error}`));
2142
+ console.error(chalk6.red("\u274C Failed to create configuration file"));
2143
+ console.error(chalk6.yellow(`Error: ${error}`));
2193
2144
  process.exit(1);
2194
2145
  }
2195
2146
  }
@@ -2199,7 +2150,7 @@ var initCommand = new Command3("init").description("Initialize configuration fil
2199
2150
 
2200
2151
  // src/cli.ts
2201
2152
  var program = new Command4();
2202
- program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.2.1").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
2153
+ program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.3.0").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
2203
2154
  const options = thisCommand.opts();
2204
2155
  if (options.debug === true) {
2205
2156
  setDebugMode(true, true);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/debug.ts","../src/utils/version/cache.ts","../src/utils/version/provider.ts","../src/utils/version/checker.ts","../src/config/errors/config-file-error.ts","../src/constants/config.ts","../src/config/environments.ts","../src/config/config-loader.ts","../src/config/oceanet.ts","../src/core/auth/device-flow-service.ts","../src/adapters/ora-ui-callbacks.ts","../src/core/auth/keytar-adapter.ts","../src/providers/file-credential-store.ts","../src/providers/credential-store.ts","../src/core/auth/token-cache.ts","../src/cli.ts","../src/utils/version/index.ts","../src/commands/auth.ts","../src/utils/environment.ts","../src/core/auth/device-flow.ts","../src/adapters/cli-device-flow.ts","../src/adapters/ui-callbacks.ts","../src/core/auth/token-manager.ts","../src/core/http/client.ts","../src/core/http/base-http-client.ts","../src/core/http/authenticating-http-client.ts","../src/core/http/api-error-handler.ts","../src/core/http/interceptors.ts","../src/commands/http.ts","../src/commands/init.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Debug utilities for HTTP request/response logging\n */\n\nimport chalk from 'chalk';\n\nlet debugMode: boolean | null = null;\nlet explicitSet = false; // 标记是否显式设置过\n\n/**\n * 启用调试模式\n * @param enabled 是否启用调试模式\n * @param explicit 是否显式设置(命令行参数),默认为 true\n */\nexport function setDebugMode(enabled: boolean, explicit: boolean = true): void {\n if (explicit) {\n debugMode = enabled;\n explicitSet = true;\n }\n // 同时设置全局变量供其他模块使用\n (global as any).__debugMode = enabled;\n}\n\n/**\n * 检查是否在调试模式\n * 优先级:命令行参数(显式设置)> 环境变量 > 默认关闭\n */\nexport function isDebugMode(): boolean {\n // 如果已显式通过命令行参数设置,优先使用\n if (explicitSet) {\n return debugMode === true;\n }\n\n // 检查全局变量\n if ((global as any).__debugMode === true) {\n return true;\n }\n\n // 检查环境变量 WUKONG_CLI_DEBUG\n return process.env.WUKONG_CLI_DEBUG === 'true';\n}\n\n/**\n * 打印 HTTP 请求\n */\nexport function debugRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n): void {\n if (!isDebugMode()) return;\n\n console.log('');\n console.log(chalk.dim('=== HTTP Request ==='));\n console.log(chalk.cyan(`${method} ${url}`));\n\n if (headers) {\n console.log(chalk.dim('Headers:'));\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization') {\n // 只显示 token 的前 50 个字符\n const truncated = value.length > 50\n ? value.substring(0, 50) + '...'\n : value;\n console.log(chalk.dim(` ${key}: ${truncated}`));\n } else {\n console.log(chalk.dim(` ${key}: ${value}`));\n }\n }\n }\n\n if (body) {\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n }\n console.log('');\n}\n\n/**\n * 打印 HTTP 响应\n */\nexport function debugResponse(\n status: number,\n statusText: string,\n body: any,\n duration: number\n): void {\n if (!isDebugMode()) return;\n\n const statusColor = status >= 200 && status < 300 ? chalk.green : chalk.red;\n\n console.log(chalk.dim('=== HTTP Response') + chalk.dim(` (${duration}ms) ===`));\n console.log(statusColor(`Status: ${status} ${statusText}`));\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n console.log('');\n}\n","/**\n * Version Cache\n * Manages caching of version check results\n */\n\nexport class VersionCache {\n private lastCheckTime: number = 0;\n private cachedVersion: string | null = null;\n private checkInterval: number;\n\n /**\n * Constructor\n * @param checkInterval - Check interval in milliseconds (default: 24 hours)\n */\n constructor(checkInterval: number = 24 * 60 * 60 * 1000) {\n this.checkInterval = checkInterval;\n }\n\n /**\n * Check if a new version check should be performed\n */\n shouldCheck(): boolean {\n const now = Date.now();\n return now - this.lastCheckTime >= this.checkInterval;\n }\n\n /**\n * Get cached version\n */\n get(): string | null {\n return this.cachedVersion;\n }\n\n /**\n * Set cached version with timestamp\n */\n set(version: string): void {\n this.cachedVersion = version;\n this.lastCheckTime = Date.now();\n }\n\n /**\n * Clear cache\n */\n clear(): void {\n this.lastCheckTime = 0;\n this.cachedVersion = null;\n }\n\n /**\n * Get time since last check\n */\n getTimeSinceLastCheck(): number {\n if (this.lastCheckTime === 0) {\n return 0;\n }\n return Date.now() - this.lastCheckTime;\n }\n}\n","/**\n * Version Provider Interface\n * Abstract source of version information\n */\n\nexport interface IVersionProvider {\n /**\n * Get the latest available version\n */\n getLatestVersion(): Promise<string | null>;\n}\n\n/**\n * NPM Version Provider\n * Fetches latest version from npm registry\n */\n\nexport class NpmVersionProvider implements IVersionProvider {\n private readonly timeout: number;\n\n constructor(\n private readonly packageName: string,\n private readonly registryUrl: string\n ) {\n this.timeout = 5000; // 5 second timeout\n }\n\n /**\n * Get latest version from npm\n */\n async getLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(`${this.registryUrl}/${this.packageName}`, {\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n return null;\n }\n\n const data = await response.json();\n return data['dist-tags']?.latest || null;\n\n } catch (error) {\n // Fail silently on network errors or timeout\n return null;\n }\n }\n}\n","/**\n * Version Checker\n * Coordinates version checking with caching\n */\n\nimport type { IVersionProvider } from './provider.js';\nimport { VersionCache } from './cache.js';\n\nexport interface UpdateResult {\n hasUpdate: boolean;\n currentVersion: string;\n latestVersion: string | null;\n}\n\n/**\n * Version Checker\n * Orchestrates version checking with caching\n */\nexport class VersionChecker {\n private readonly cache: VersionCache;\n\n constructor(\n private readonly provider: IVersionProvider,\n private readonly currentVersion: string,\n cache?: VersionCache\n ) {\n this.cache = cache || new VersionCache();\n }\n\n /**\n * Compare two version strings\n * Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if equal\n */\n private compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map(Number);\n const parts2 = v2.split('.').map(Number);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n }\n\n /**\n * Check for update (cached or fresh)\n */\n async checkForUpdate(): Promise<UpdateResult> {\n // Use cached result if still valid\n if (!this.cache.shouldCheck()) {\n const cached = this.cache.get();\n if (cached) {\n return {\n hasUpdate: this.compareVersions(cached, this.currentVersion) > 0,\n currentVersion: this.currentVersion,\n latestVersion: cached,\n };\n }\n }\n\n // Perform fresh check\n const latestVersion = await this.provider.getLatestVersion();\n\n if (!latestVersion) {\n return {\n hasUpdate: false,\n currentVersion: this.currentVersion,\n latestVersion: null,\n };\n }\n\n // Update cache\n this.cache.set(latestVersion);\n\n return {\n hasUpdate: this.compareVersions(latestVersion, this.currentVersion) > 0,\n currentVersion: this.currentVersion,\n latestVersion,\n };\n }\n\n /**\n * Check in background (for async execution)\n */\n async checkInBackground(): Promise<void> {\n try {\n await this.checkForUpdate();\n } catch (error) {\n // Silently fail - result is cached, will be shown on next run\n }\n }\n\n /**\n * Clear cached data\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Get current cache info\n */\n getCacheInfo(): {\n lastCheckTime: number;\n cachedVersion: string | null;\n } {\n return {\n lastCheckTime: this.cache.lastCheckTime,\n cachedVersion: this.cache.cachedVersion,\n };\n }\n}\n","/**\n * Configuration file error types\n */\n\n/**\n * Configuration error types\n */\nexport enum ConfigErrorType {\n CONFIG_FILE_MISSING = 'CONFIG_FILE_MISSING',\n ENVIRONMENT_MISSING = 'ENVIRONMENT_MISSING',\n REQUIRED_FIELD_MISSING = 'REQUIRED_FIELD_MISSING',\n}\n\n/**\n * Structured configuration error\n * Provides actionable guidance for users\n */\nexport class ConfigFileError extends Error {\n constructor(\n public type: ConfigErrorType,\n message: string,\n public environment?: string,\n public missingFields?: string[],\n public fixSuggestion?: string\n ) {\n super(message);\n this.name = 'ConfigFileError';\n }\n\n /**\n * Format error message for user display\n */\n toUserMessage(): string {\n let message = `\\n${this.message}\\n`;\n\n if (this.environment) {\n message += `Environment: ${this.environment}\\n`;\n }\n\n if (this.missingFields && this.missingFields.length > 0) {\n message += `Missing fields: ${this.missingFields.join(', ')}\\n`;\n }\n\n if (this.fixSuggestion) {\n message += `\\n${this.fixSuggestion}\\n`;\n }\n\n return message;\n }\n}\n","/**\n * 配置常量\n * 只包含常量定义,不包含环境配置\n */\n\n/**\n * 配置文件名\n */\nexport const CONFIG_FILE = '.wukong-cli.json';\n\n/**\n * Keytar 服务名\n */\nexport const KEYTAR_SERVICE = 'wukong-cli';\n\n/**\n * Keytar 账户名\n */\nexport const KEYTAR_ACCOUNTS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n} as const;\n\n/**\n * API 端点路径\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n DEVICE_AUTHORIZE: '/oceanet-auth/pkce/device/authorize',\n DEVICE_TOKEN: '/oceanet-auth/pkce/device/token',\n REFRESH_TOKEN: '/oceanet-auth/manage/refreshToken',\n LOGOUT: '/oceanet-auth/manage/logout',\n },\n API: {\n USER_INFO: '/oceanet-auth/web/userInfo',\n },\n} as const;\n\n/**\n * 轮询配置\n */\nexport const POLL_CONFIG = {\n INTERVAL: 3, // 轮询间隔(秒)\n TIMEOUT: 300, // 轮询超时(秒)\n} as const;\n","/**\n * 多环境配置支持\n * 支持 dev/beta/uat/prod 四套环境\n */\n\nexport type Environment = 'dev' | 'beta' | 'uat' | 'prod';\n\nexport interface EnvironmentConfig {\n name: Environment;\n displayName: string;\n authBaseUrl: string;\n apiBaseUrl: string;\n clientId: string;\n}\n\n/**\n * 环境配置表(默认值)\n * 可通过配置文件或环境变量覆盖\n */\nexport const ENVIRONMENTS: Record<Environment, EnvironmentConfig> = {\n dev: {\n name: 'dev',\n displayName: 'Development',\n authBaseUrl: 'https://portal-dev.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode-dev.zrhsh.com',\n clientId: 'wukong-cli-dev',\n },\n beta: {\n name: 'beta',\n displayName: 'Testing',\n authBaseUrl: 'https://portal-beta.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode.zrhsh.com',\n clientId: 'wukong-cli-beta',\n },\n uat: {\n name: 'uat',\n displayName: 'UAT (User Acceptance Testing)',\n authBaseUrl: 'https://portal-uat.zrhsh.com',\n apiBaseUrl: 'https://nrp-pd.zrhsh.com',\n clientId: 'wukong-cli-uat',\n },\n prod: {\n name: 'prod',\n displayName: 'Production',\n authBaseUrl: 'https://portal.zrhsh.com',\n apiBaseUrl: 'https://nrp.zrhsh.com',\n clientId: 'wukong-cli-prod',\n },\n};\n\n/**\n * 默认环境\n */\nexport const DEFAULT_ENVIRONMENT: Environment = 'prod';\n\n/**\n * 验证环境名称\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env in ENVIRONMENTS;\n}\n","/**\n * 配置文件加载器\n * 支持从 wukong-cli.json 加载环境配置\n * 首次运行时自动创建默认配置文件\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport { Environment, EnvironmentConfig, ENVIRONMENTS, DEFAULT_ENVIRONMENT, isValidEnvironment } from './environments.js';\nimport { ConfigFileError, ConfigErrorType } from './errors/config-file-error.js';\n\n/**\n * 用户自定义环境配置\n */\nexport interface CustomEnvironmentConfig {\n authBaseUrl?: string;\n apiBaseUrl?: string;\n clientId?: string;\n}\n\nexport interface WukongCliConfig {\n /** 默认环境 */\n defaultEnv?: Environment;\n /** 环境配置覆盖 */\n environments?: Record<string, CustomEnvironmentConfig>;\n /** 自定义环境(非标准环境) */\n customEnvironments?: Record<string, EnvironmentConfig & { displayName: string }>;\n}\n\nconst CONFIG_FILENAMES = [\n 'wukong-cli.json',\n '.wukong-cli.json',\n '.wukongclirc',\n];\n\n/**\n * 获取用户主目录下的配置文件路径\n */\nexport function getUserConfigPath(): string {\n return join(homedir(), 'wukong-cli.json');\n}\n\n/**\n * 创建默认配置文件\n * 从模板文件读取默认配置\n */\nexport function createDefaultConfig(): void {\n const configPath = getUserConfigPath();\n\n // 如果配置文件已存在,不覆盖\n if (existsSync(configPath)) {\n return;\n }\n\n try {\n // 读取模板文件\n const templatePath = join(getProjectRoot(), 'wukong-cli.json.template');\n\n if (!existsSync(templatePath)) {\n console.warn(`Warning: Template config not found: ${templatePath}`);\n return;\n }\n\n const templateContent = readFileSync(templatePath, 'utf-8');\n const defaultConfig = JSON.parse(templateContent) as WukongCliConfig;\n\n // 确保目录存在\n const dir = dirname(configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // 写入配置文件\n writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');\n } catch (error) {\n // 静默失败,不影响程序运行\n // console.warn(`Warning: Failed to create default config: ${error}`);\n }\n}\n\n/**\n * 获取项目根目录\n */\nfunction getProjectRoot(): string {\n // 从当前文件的路径向上查找,直到找到 package.json\n let currentDir = dirname(fileURLToPath(import.meta.url));\n\n while (currentDir !== dirname(currentDir)) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = dirname(currentDir);\n }\n\n // 如果找不到,返回当前工作目录\n return process.cwd();\n}\n\n/**\n * 查找配置文件\n * 优先级:当前目录 > 用户主目录\n */\nfunction findConfigFile(): string | null {\n // 1. 当前工作目录\n for (const filename of CONFIG_FILENAMES) {\n const localPath = join(process.cwd(), filename);\n if (existsSync(localPath)) {\n return localPath;\n }\n }\n\n // 2. 用户主目录\n const userConfigPath = getUserConfigPath();\n if (existsSync(userConfigPath)) {\n return userConfigPath;\n }\n\n return null;\n}\n\n/**\n * 加载配置文件\n * 如果用户主目录下没有配置文件,自动创建默认配置\n */\nexport function loadConfig(): WukongCliConfig {\n const configPath = findConfigFile();\n\n if (!configPath) {\n // 首次运行,创建默认配置\n createDefaultConfig();\n return {};\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content) as WukongCliConfig;\n return config;\n } catch (error) {\n console.warn(`Warning: Failed to load config from ${configPath}: ${error}`);\n return {};\n }\n}\n\n/**\n * 获取环境配置(支持fallback到默认配置)\n * 优先级:配置文件 > 默认配置 > 错误\n */\nexport function getMergedEnvironmentConfig(env: Environment): EnvironmentConfig {\n const config = loadConfig();\n\n // 检查环境是否有默认配置\n const defaultEnvConfig = ENVIRONMENTS[env];\n if (!defaultEnvConfig) {\n // 环境不在默认配置中,真正未知\n throw new ConfigFileError(\n ConfigErrorType.ENVIRONMENT_MISSING,\n `Unknown environment: '${env}'`,\n env,\n undefined,\n `Valid environments: ${Object.keys(ENVIRONMENTS).join(', ')}`\n );\n }\n\n // 如果配置文件中有该环境的配置,合并\n if (config.environments && env in config.environments) {\n const envConfig = config.environments[env];\n\n // 检查必需字段\n const requiredFields = ['authBaseUrl', 'apiBaseUrl', 'clientId'];\n const missingFields = requiredFields.filter(field => !(field in envConfig));\n\n if (missingFields.length > 0) {\n throw new ConfigFileError(\n ConfigErrorType.REQUIRED_FIELD_MISSING,\n `Incomplete configuration for environment '${env}'`,\n env,\n missingFields,\n `Edit your wukong-cli.json or run 'wukong-cli init' to reset`\n );\n }\n\n // 返回合并后的配置\n return {\n name: env,\n displayName: defaultEnvConfig.displayName,\n authBaseUrl: envConfig.authBaseUrl!,\n apiBaseUrl: envConfig.apiBaseUrl!,\n clientId: envConfig.clientId!,\n };\n }\n\n // 配置文件中没有该环境,使用默认配置\n // 这允许用户只配置需要的环境,其他使用默认值\n return defaultEnvConfig;\n}\n\n/**\n * 获取所有可用环境(包括自定义环境)\n */\nexport function getAllEnvironments(): Record<string, EnvironmentConfig & { displayName: string }> {\n const config = loadConfig();\n const result: Record<string, EnvironmentConfig & { displayName: string }> = { ...ENVIRONMENTS };\n\n // 添加自定义环境\n if (config.customEnvironments) {\n for (const [name, customEnv] of Object.entries(config.customEnvironments)) {\n result[name] = {\n name: name as Environment,\n displayName: customEnv.displayName || name,\n authBaseUrl: customEnv.authBaseUrl,\n apiBaseUrl: customEnv.apiBaseUrl,\n clientId: customEnv.clientId,\n };\n }\n }\n\n return result;\n}\n\n/**\n * 获取默认环境\n */\nexport function getDefaultEnvironment(): Environment {\n // 优先级:环境变量 > 配置文件 > 默认值\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n\n const config = loadConfig();\n if (config.defaultEnv && isValidEnvironment(config.defaultEnv)) {\n return config.defaultEnv;\n }\n\n return DEFAULT_ENVIRONMENT;\n}","/**\n * Oceanet Auth 配置\n * 支持多环境:dev/beta/uat/prod\n * 配置优先级:配置文件 > 错误(移除环境变量和默认值)\n */\n\nimport type { Environment, EnvironmentConfig } from '../types/config.js';\nimport {\n API_ENDPOINTS,\n POLL_CONFIG,\n} from '../constants/config.js';\nimport { isValidEnvironment } from './environments.js';\nimport { getMergedEnvironmentConfig, getDefaultEnvironment } from './config-loader.js';\n\n// 当前环境(运行时设置)\nlet currentEnv: Environment = getDefaultEnvironment();\n\n/**\n * 设置当前环境\n */\nexport function setCurrentEnvironment(env: Environment): void {\n currentEnv = env;\n}\n\n/**\n * 获取当前环境\n */\nexport function getCurrentEnvironment(): Environment {\n // 优先使用环境变量\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n return currentEnv;\n}\n\n/**\n * 获取当前环境的配置\n * 合并配置文件和默认值\n */\nexport function getEnvironmentConfig(): EnvironmentConfig {\n return getMergedEnvironmentConfig(getCurrentEnvironment());\n}\n\nconst getEnv = (key: string, defaultValue: string): string => {\n return process.env[key] || defaultValue;\n};\n\n/**\n * 动态配置(根据当前环境变化)\n */\nexport function getOceanetConfig() {\n const envConfig = getEnvironmentConfig();\n const env = getCurrentEnvironment();\n\n return {\n // 认证服务基础地址 (设备码授权、登录、登出等)\n AUTH_BASE_URL: envConfig.authBaseUrl,\n\n // 业务 API 基础地址\n API_BASE_URL: envConfig.apiBaseUrl,\n\n // 客户端 ID\n CLIENT_ID: envConfig.clientId,\n\n // Token 存储服务名(不同环境分开存储)\n SERVICE_NAME: `wukong-cli-${env}`,\n\n // 轮询配置\n POLL: POLL_CONFIG,\n\n // 认证服务端点\n AUTH_ENDPOINTS: API_ENDPOINTS.AUTH,\n\n // 业务 API 端点\n API_ENDPOINTS: API_ENDPOINTS.API,\n\n // 调试模式 (保留这个环境变量,因为它是运行时选项)\n DEBUG: getEnv('WUKONG_CLI_DEBUG', 'false') === 'true',\n\n // 当前环境信息\n ENVIRONMENT: env,\n ENVIRONMENT_DISPLAY: envConfig.displayName,\n };\n}\n\n// 向后兼容:导出获取函数而不是静态对象(延迟初始化)\n// 这样可以避免模块导入时立即执行配置加载\nexport const OCEANET_CONFIG = getOceanetConfig;\n","/**\n * Device Flow Service - 设备码授权流程(纯业务逻辑)\n * 从 device-flow.ts 提取,移除 UI 依赖\n */\n\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\n\n/**\n * 设备流程服务接口\n * 定义设备码授权流程的核心操作\n */\nexport interface IDeviceFlowService {\n /**\n * 获取设备授权码\n * @returns 设备授权响应,包含验证 URL 和设备码\n */\n getDeviceCode(): Promise<DeviceCodeResponse>;\n\n /**\n * 轮询获取 token\n * @param deviceCode 设备码\n * @returns Token 对\n */\n pollToken(deviceCode: string): Promise<TokenPair>;\n}\n\n/**\n * 设备流程服务实现\n * 纯业务逻辑,不包含 UI 依赖\n */\nexport class DeviceFlowService implements IDeviceFlowService {\n /**\n * 获取设备授权码\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_AUTHORIZE}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n },\n };\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders, requestBody);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(requestBody),\n });\n\n const duration = Date.now() - startTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n if (data.code !== 200) {\n throw new Error(\n `(${data.code}) ${data.message || 'Failed to get device code'}`\n );\n }\n\n const { verificationUri, expiresIn, interval } = data.result;\n\n // 从 URL 中提取 deviceCode\n const urlObj = new URL(verificationUri);\n const deviceCode = urlObj.searchParams.get('code') || '';\n\n return {\n verificationUri,\n deviceCode,\n expiresIn,\n interval: interval || config.POLL.INTERVAL,\n };\n }\n\n /**\n * 轮询获取 token\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n const startTime = Date.now();\n const config = getOceanetConfig();\n\n while (Date.now() - startTime < config.POLL.TIMEOUT * 1000) {\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_TOKEN}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n deviceCode,\n },\n };\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders, requestBody);\n\n const requestStartTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(requestBody),\n });\n\n const duration = Date.now() - requestStartTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n // 检查 API 错误(忽略 PENDING 状态)\n if (data.code !== 200) {\n // 静默跳过错误状态,继续轮询\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // result 为 null 或空表示 PENDING,继续轮询\n if (!data.result) {\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // 成功获取 token\n const {\n access_token,\n refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n return {\n accessToken: access_token,\n refreshToken: refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n }\n\n // 超时\n throw new Error('Authorization timed out. Please try again.');\n }\n}\n\n/**\n * 获取设备流程服务实例\n */\nexport function getDeviceFlowService(): IDeviceFlowService {\n return new DeviceFlowService();\n}\n","/**\n * Ora UI 回调实现 - 使用 ora spinner\n * CLI 特定的 UI 实现\n */\n\nimport ora, { Ora } from 'ora';\nimport type { IUICallbacks } from './ui-callbacks.js';\n\n/**\n * Ora Spinner UI 回调实现\n * 使用 ora 库提供 CLI 进度显示\n */\nexport class OraUICallbacks implements IUICallbacks {\n private spinner: Ora | null = null;\n\n onStart(message: string): void {\n this.spinner = ora(message).start();\n }\n\n onSuccess(message: string): void {\n if (this.spinner) {\n this.spinner.succeed(message);\n this.spinner = null;\n }\n }\n\n onError(message: string): void {\n if (this.spinner) {\n this.spinner.fail(message);\n this.spinner = null;\n }\n }\n\n onUpdate(message: string): void {\n if (this.spinner) {\n this.spinner.text = message;\n }\n }\n}\n","/**\n * keytar 适配器 - 处理 ESM/CommonJS 互操作\n * keytar 是可选依赖,如果不可用则返回 null\n */\n\nimport { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\nlet keytarModule: any = null;\n\ntry {\n keytarModule = require('keytar');\n} catch (error) {\n // keytar 未安装或编译失败\n keytarModule = null;\n}\n\n/**\n * 检查 keytar 是否可用\n */\nexport function isKeytarAvailable(): boolean {\n return keytarModule !== null;\n}\n\n/**\n * 设置密码\n */\nexport async function setPassword(service: string, account: string, password: string): Promise<void> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n await keytarModule.setPassword(service, account, password);\n}\n\n/**\n * 获取密码\n */\nexport async function getPassword(service: string, account: string): Promise<string | null> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.getPassword(service, account);\n}\n\n/**\n * 删除密码\n */\nexport async function deletePassword(service: string, account: string): Promise<boolean> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.deletePassword(service, account);\n}\n","/**\n * 文件凭据存储 - 作为 keytar 不可用时的降级方案\n * 将 token 存储在用户主目录的加密文件中\n */\n\nimport { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\n\n/**\n * 文件凭据存储实现\n */\nexport class FileCredentialStore {\n private configDir: string;\n\n constructor() {\n this.configDir = join(homedir(), '.wukong-cli');\n this.ensureConfigDir();\n }\n\n private ensureConfigDir(): void {\n if (!existsSync(this.configDir)) {\n mkdirSync(this.configDir, { recursive: true, mode: 0o700 });\n }\n }\n\n private getTokenPath(service: string, account: string): string {\n // 简单的文件命名:service_account.token\n const filename = `${service}_${account}.token`;\n return join(this.configDir, filename);\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n const filePath = this.getTokenPath(service, account);\n writeFileSync(filePath, password, { mode: 0o600 });\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return false;\n }\n\n try {\n unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 清除所有 token\n */\n clear(): void {\n // 简单实现:删除整个配置目录\n // 更精细的实现可以只删除 .token 文件\n }\n}\n","/**\n * 凭据存储提供者 - 抽象凭据存储接口\n * 优先使用 keytar,不可用时降级到文件存储\n */\n\nimport * as keytarAdapter from '../core/auth/keytar-adapter.js';\nimport { FileCredentialStore } from './file-credential-store.js';\n\n/**\n * 凭据存储接口\n */\nexport interface ICredentialStore {\n setPassword(service: string, account: string, password: string): Promise<void>;\n getPassword(service: string, account: string): Promise<string | null>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\n/**\n * Keytar 凭据存储实现\n */\nclass KeytarCredentialStore implements ICredentialStore {\n async setPassword(service: string, account: string, password: string): Promise<void> {\n await keytarAdapter.setPassword(service, account, password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return await keytarAdapter.getPassword(service, account);\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return await keytarAdapter.deletePassword(service, account);\n }\n}\n\n/**\n * 内存凭据存储实现(用于测试)\n */\nexport class InMemoryCredentialStore implements ICredentialStore {\n private store: Map<string, string> = new Map();\n\n private getKey(service: string, account: string): string {\n return `${service}:${account}`;\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n this.store.set(this.getKey(service, account), password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return this.store.get(this.getKey(service, account)) || null;\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return this.store.delete(this.getKey(service, account));\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n/**\n * 获取凭据存储实例\n * 自动选择:keytar 可用时使用 keytar,否则降级到文件存储\n */\nexport function getCredentialStore(): ICredentialStore {\n // 优先使用 keytar\n if (keytarAdapter.isKeytarAvailable()) {\n return new KeytarCredentialStore();\n }\n\n // 降级到文件存储\n return new FileCredentialStore();\n}\n\n/**\n * 获取测试用凭据存储实例\n */\nexport function getTestCredentialStore(): ICredentialStore {\n return new InMemoryCredentialStore();\n}\n\n/**\n * 检查是否使用安全存储(keytar)\n */\nexport function isUsingSecureStorage(): boolean {\n return keytarAdapter.isKeytarAvailable();\n}\n","/**\n * Token Cache 接口 - Token 缓存抽象\n * 用于替代全局变量 (global as any).__cachedAccessToken\n */\n\n/**\n * Token 缓存接口\n * 定义了 token 的读取、设置和清除操作\n */\nexport interface ITokenCache {\n /**\n * 获取访问令牌\n */\n getAccessToken(): string | null;\n\n /**\n * 获取刷新令牌\n */\n getRefreshToken(): string | null;\n\n /**\n * 设置令牌对\n */\n setTokens(accessToken: string, refreshToken: string): void;\n\n /**\n * 清除所有令牌\n */\n clear(): void;\n\n /**\n * 检查是否有有效的访问令牌\n */\n hasAccessToken(): boolean;\n\n /**\n * 检查是否有有效的刷新令牌\n */\n hasRefreshToken(): boolean;\n}\n\n/**\n * 内存 Token 缓存实现\n * 将 token 存储在内存中,适用于单次 CLI 会话\n */\nexport class MemoryTokenCache implements ITokenCache {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n getRefreshToken(): string | null {\n return this.refreshToken;\n }\n\n setTokens(accessToken: string, refreshToken: string): void {\n this.accessToken = accessToken;\n this.refreshToken = refreshToken;\n }\n\n clear(): void {\n this.accessToken = null;\n this.refreshToken = null;\n }\n\n hasAccessToken(): boolean {\n return this.accessToken !== null && this.accessToken.length > 0;\n }\n\n hasRefreshToken(): boolean {\n return this.refreshToken !== null && this.refreshToken.length > 0;\n }\n}\n\n/**\n * 全局 Token 缓存实例(单例)\n * 用于在整个 CLI 会话中共享同一个缓存实例\n */\nlet globalCacheInstance: ITokenCache | null = null;\n\n/**\n * 获取全局 Token 缓存实例\n * 如果不存在则创建一个新的 MemoryTokenCache 实例\n */\nexport function getGlobalTokenCache(): ITokenCache {\n if (!globalCacheInstance) {\n globalCacheInstance = new MemoryTokenCache();\n }\n return globalCacheInstance;\n}\n\n/**\n * 重置全局 Token 缓存实例\n * 用于测试或环境切换\n */\nexport function resetGlobalTokenCache(): void {\n globalCacheInstance = null;\n}\n\n/**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\nexport async function initializeTokenCache(\n loadTokens: () => Promise<{ accessToken: string | null; refreshToken: string | null }>\n): Promise<void> {\n const cache = getGlobalTokenCache();\n const { accessToken, refreshToken } = await loadTokens();\n\n if (accessToken && refreshToken) {\n cache.setTokens(accessToken, refreshToken);\n }\n}\n","/**\n * Wukong CLI 主入口\n * 命令结构: wukong-cli <command> [subcommand] [options]\n */\n\nimport { Command } from 'commander';\nimport { setDebugMode } from './utils/debug.js';\nimport { getVersionChecker } from './utils/version/index.js';\nimport { authCommands } from './commands/auth.js';\nimport { httpCommand } from './commands/http.js';\nimport { initCommand } from './commands/init.js';\n\nconst program = new Command();\n\n// 根命令配置\nprogram\n .name('wukong-cli')\n .description('Wukong CLI - TypeScript implementation')\n .version(CLI_VERSION)\n // 添加全局 --debug 选项\n .option('--debug', 'Enable debug mode (show HTTP requests)')\n // 在每个命令执行前设置调试模式\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n // 只有显式传递 --debug 时才设置为 true,否则允许环境变量生效\n if (options.debug === true) {\n setDebugMode(true, true);\n } else {\n // 不显式设置,允许环境变量生效\n setDebugMode(false, false);\n }\n });\n\n// 添加 auth 命令组\nprogram.addCommand(authCommands);\n\n// 添加 http 命令组\nprogram.addCommand(httpCommand);\n\n// 添加 init 命令\nprogram.addCommand(initCommand);\n\n// 如果没有参数,显示帮助\nif (process.argv.length === 2) {\n program.help();\n}\n\n// 先执行命令(立即响应用户)\nprogram.parse();\n\n// 命令执行完后,异步检查版本更新(不阻塞)\n// 使用 setImmediate 确保用户命令先执行\nsetImmediate(() => {\n try {\n const versionChecker = getVersionChecker();\n\n versionChecker.checkInBackground().catch(() => {\n // 静默失败,不影响正常使用\n });\n } catch {\n // Version checker not available in ESM build, silently skip\n }\n});\n","/**\n * Version Check Module\n * Testable version checking with caching\n */\n\nexport { VersionCache } from './cache.js';\nexport { NpmVersionProvider } from './provider.js';\nexport type { IVersionProvider } from './provider.js';\nexport { VersionChecker } from './checker.js';\nexport type { UpdateResult } from './checker.js';\n\n/**\n * Create VersionChecker instance (singleton pattern)\n */\nlet versionCheckerInstance: VersionChecker | null = null;\n\nexport function getVersionChecker(): VersionChecker {\n if (!versionCheckerInstance) {\n const { createRequire } = require('module');\n const nodeRequire = createRequire(import.meta.url);\n const packageJson = nodeRequire('../../package.json');\n\n const { NpmVersionProvider } = require('./provider.js');\n const { VersionChecker } = require('./checker.js');\n\n const provider = new NpmVersionProvider(\n '@zrhsh/wukong-cli',\n 'https://registry.npmjs.org'\n );\n\n versionCheckerInstance = new VersionChecker(\n provider,\n packageJson.version\n );\n }\n\n return versionCheckerInstance;\n}\n\n/**\n * Reset version checker instance (for testing)\n */\nexport function resetVersionChecker(): void {\n versionCheckerInstance = null;\n}\n","/**\n * Auth 命令组 - 基于 Oceanet Auth\n * wukong-cli auth <subcommand>\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { printEnvironmentInfo } from '../utils/environment.js';\nimport { success, error } from '../utils/symbols.js';\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\nimport {\n getDeviceCode,\n pollToken,\n} from '../core/auth/device-flow.js';\nimport {\n saveToken,\n getAccessToken,\n logout,\n} from '../core/auth/token-manager.js';\nimport { getClient } from '../core/http/client.js';\nimport {\n Environment,\n ENVIRONMENTS,\n} from '../config/environments.js';\nimport { setCurrentEnvironment, getOceanetConfig, getCurrentEnvironment } from '../config/oceanet.js';\nimport { getAllEnvironments } from '../config/config-loader.js';\n\nexport const authCommands = new Command('auth')\n .description('Authentication commands');\n\n// 登录命令\nauthCommands\n .command('login')\n .description('Login using Device Authorization Flow')\n .action(async () => {\n try {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n // 设置当前环境\n setCurrentEnvironment(env as Environment);\n const config = getOceanetConfig();\n const envConfig = allEnvs[env];\n\n console.log('');\n console.log(chalk.bgBlue.white.bold(' Wukong CLI Login '));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log('');\n\n // 步骤 1: 获取设备授权链接\n const { verificationUri, deviceCode, expiresIn, interval } =\n await getDeviceCode();\n\n // 显示授权信息\n console.log('');\n console.log(chalk.bold('='.repeat(50)));\n console.log(chalk.bold(' Please complete authorization'));\n console.log(chalk.bold('='.repeat(50)));\n console.log('');\n console.log(chalk.green(' Authorization URL:'));\n console.log('');\n\n // 用多种方式显示链接,确保用户能看到\n console.log(chalk.cyan(` ${verificationUri}`));\n console.log('');\n\n // 同时输出到 stderr(Claude Code 能捕获)\n console.error(chalk.yellow.bold('>>> Please open this link in your browser <<<'));\n console.error(chalk.cyan(verificationUri));\n console.error('');\n\n // 尝试自动打开浏览器(如果环境支持)\n const open = await import('open').catch(() => null);\n if (open) {\n try {\n await open.default(verificationUri);\n console.log(chalk.dim(' Browser opened automatically'));\n } catch {\n console.log(chalk.dim(' Please copy link to browser'));\n }\n } else {\n console.log(chalk.dim(' Please copy link to browser'));\n }\n console.log('');\n\n console.log(chalk.dim('═'.repeat(50)));\n console.log(chalk.dim(` Device Code: ${deviceCode}`));\n console.log(chalk.dim(` Expires in: ${expiresIn} seconds`));\n console.log(chalk.dim('═'.repeat(50)));\n console.log('');\n\n // 步骤 2: 轮询获取 Token\n const tokens = await pollToken(deviceCode);\n\n // 步骤 3: 保存 Token\n await saveToken(tokens.accessToken, tokens.refreshToken);\n\n console.log('');\n console.log(chalk.bgGreen.black.bold(' [OK] Login Successful '));\n console.log('');\n console.log(chalk.green('[OK] Tokens saved securely'));\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));\n console.log('');\n console.log(chalk.dim('Next:'), chalk.cyan('wukong-cli auth status'));\n console.log('');\n\n } catch (error) {\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log('');\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n return;\n }\n\n // Handle other errors\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n }\n });\n\n// 登出命令\nauthCommands\n .command('logout')\n .description('Logout and clear saved tokens')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n\n try {\n const accessToken = await getAccessToken();\n\n if (accessToken) {\n await logout(accessToken);\n }\n\n console.log('');\n console.log(chalk.green(`[OK] Logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n } catch {\n console.log('');\n console.log(chalk.yellow(`○ Already logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n }\n });\n\n// 刷新 token 命令\nauthCommands\n .command('refresh')\n .description('Manually refresh access token')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n const envConfig = allEnvs[env];\n\n try {\n const config = getOceanetConfig();\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log('');\n console.log(chalk.yellow('[ERROR] Not authenticated'));\n printEnvironmentInfo(env, envConfig.displayName);\n console.log('');\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return; // 不使用 process.exit,让程序自然退出\n }\n\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const client = getClient();\n await client.refreshToken();\n\n spinner.succeed('Token refreshed successfully!');\n\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim('New tokens saved securely'));\n console.log('');\n } catch (error) {\n spinner.fail('Token refresh failed');\n throw error;\n }\n } catch (error) {\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log('');\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n return;\n }\n\n // Handle other errors\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Your session may have expired. Please run:`));\n console.log(chalk.dim(` wukong-cli auth login`));\n console.log('');\n // 不使用 process.exit,让程序自然退出\n }\n });\n\n// 状态命令\nauthCommands\n .command('status')\n .description('Show authentication status')\n .action(async () => {\n console.log('');\n\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n\n try {\n const config = getOceanetConfig();\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return;\n }\n\n // 尝试获取用户信息来验证 token 是否真的有效\n try {\n const client = getClient();\n const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;\n const userInfo = await client.get(userInfoUrl);\n\n // 只有 API 调用成功才显示已认证\n console.log(chalk.green('[OK] Authenticated'));\n console.log('');\n\n const displayUser = userInfo.firstName\n ? `${userInfo.firstName} (${userInfo.username})`\n : userInfo.username || 'N/A';\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim('User:'), chalk.cyan(displayUser));\n console.log(chalk.dim('Email:'), chalk.cyan(userInfo.email || 'N/A'));\n console.log(chalk.dim('OrgCode:'), chalk.cyan(userInfo.ouCode || 'N/A'));\n console.log(chalk.dim('OrgName:'), chalk.cyan(userInfo.ouName || 'N/A'));\n console.log('');\n } catch (error: any) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\n console.log('');\n\n console.log(chalk.red('Error:'), chalk.dim(errorMsg));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n } catch (error) {\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n return;\n }\n\n // Handle other errors\n console.log(chalk.yellow(`✗ Not authenticated`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n });\n","/**\n * 环境显示工具\n * prod 环境不显示环境名称,保持界面简洁\n */\n\nimport chalk from 'chalk';\n\n/**\n * 格式化环境显示(prod 环境不显示)\n */\nexport function formatEnvironmentDisplay(env: string, displayName: string): string {\n if (env === 'prod') {\n return ''; // prod 环境不显示\n }\n return `${env} - ${displayName}`;\n}\n\n/**\n * 输出环境信息(prod 环境跳过)\n */\nexport function printEnvironmentInfo(env: string, displayName: string): void {\n const display = formatEnvironmentDisplay(env, displayName);\n if (display) {\n console.log(chalk.dim(`Environment: ${chalk.cyan(display)}`));\n }\n}\n","/**\n * Device PKCE Flow - 设备码授权流程\n * 从 oceanet.ts 提取的设备授权逻辑\n *\n * @deprecated 请直接使用 device-flow-service.ts 和 cli-device-flow.ts\n * 此文件保留以向后兼容\n */\n\nimport chalk from 'chalk';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\nimport { createCliDeviceFlowAdapter } from '../../adapters/cli-device-flow.js';\n\n// 重新导出类型和接口\nexport type { DeviceCodeResponse, TokenPair };\nexport type { IDeviceFlowService } from './device-flow-service.js';\n\n/**\n * 发起授权请求 - 获取设备授权链接\n * @deprecated 使用 CliDeviceFlowAdapter.getDeviceCode() 代替\n */\nexport async function getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const adapter = createCliDeviceFlowAdapter();\n\n // 调试信息\n if (config.DEBUG) {\n console.log('');\n console.log(chalk.dim('=== Debug Info ==='));\n console.log(chalk.dim('Getting device authorization...'));\n console.log(chalk.dim('Client ID:'), chalk.yellow(config.CLIENT_ID));\n console.log('');\n }\n\n const result = await adapter.getDeviceCode();\n\n // 调试响应\n if (config.DEBUG) {\n console.log(chalk.dim('=== Response ==='));\n console.log(chalk.dim('Device Code:'), chalk.yellow(result.deviceCode));\n console.log(chalk.dim('Verification URI:'), chalk.cyan(result.verificationUri));\n console.log(chalk.dim('Expires In:'), chalk.yellow(result.expiresIn));\n console.log('');\n }\n\n return result;\n}\n\n/**\n * 轮询获取 Token\n * @deprecated 使用 CliDeviceFlowAdapter.pollToken() 代替\n */\nexport async function pollToken(deviceCode: string): Promise<TokenPair> {\n const adapter = createCliDeviceFlowAdapter();\n return adapter.pollToken(deviceCode);\n}\n\n// 重新导出新的服务和适配器\nexport { DeviceFlowService, getDeviceFlowService } from './device-flow-service.js';\nexport { CliDeviceFlowAdapter, createCliDeviceFlowAdapter } from '../../adapters/cli-device-flow.js';\nexport { IUICallbacks } from '../../adapters/ui-callbacks.js';\nexport { OraUICallbacks } from '../../adapters/ora-ui-callbacks.js';\n\n","/**\n * CLI 设备流程适配器 - 为设备流程添加 CLI UI 支持\n * 连接纯业务逻辑和 CLI UI 表现层\n */\n\nimport type { IDeviceFlowService } from '../core/auth/device-flow-service.js';\nimport type { IUICallbacks } from './ui-callbacks.js';\nimport type { DeviceCodeResponse, TokenPair } from '../types/auth.js';\n\n/**\n * CLI 设备流程适配器\n * 为设备流程服务添加 UI 反馈\n */\nexport class CliDeviceFlowAdapter {\n /**\n * 构造函数\n * @param deviceFlow 设备流程服务实例\n * @param ui UI 回调实例\n */\n constructor(\n private deviceFlow: IDeviceFlowService,\n private ui: IUICallbacks\n ) {}\n\n /**\n * 获取设备授权码(带 UI)\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n this.ui.onStart('Getting device authorization...');\n\n try {\n const result = await this.deviceFlow.getDeviceCode();\n this.ui.onSuccess('Device code obtained');\n return result;\n } catch (error: any) {\n this.ui.onError('Failed to get device code');\n throw error;\n }\n }\n\n /**\n * 轮询获取 token(带 UI)\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n this.ui.onStart('Waiting for authorization...');\n\n try {\n const result = await this.deviceFlow.pollToken(deviceCode);\n this.ui.onSuccess('Authorization successful!');\n return result;\n } catch (error: any) {\n this.ui.onError('Authorization error');\n throw error;\n }\n }\n}\n\n/**\n * 创建 CLI 设备流程适配器(使用默认实现)\n */\nexport function createCliDeviceFlowAdapter(): CliDeviceFlowAdapter {\n const { getDeviceFlowService } = require('../core/auth/device-flow-service.js');\n const { OraUICallbacks } = require('./ora-ui-callbacks.js');\n\n const deviceFlow = getDeviceFlowService();\n const ui = new OraUICallbacks();\n\n return new CliDeviceFlowAdapter(deviceFlow, ui);\n}\n","/**\n * UI 回调接口 - 用于 CLI 适配器\n * 定义 UI 操作的抽象,便于测试和替换 UI 实现\n */\n\n/**\n * UI 回调接口\n * 用于解耦业务逻辑和 CLI UI 表现层\n */\nexport interface IUICallbacks {\n /**\n * 操作开始时调用\n * @param message 提示消息\n */\n onStart(message: string): void;\n\n /**\n * 操作成功时调用\n * @param message 成功消息\n */\n onSuccess(message: string): void;\n\n /**\n * 操作失败时调用\n * @param message 失败消息\n */\n onError(message: string): void;\n\n /**\n * 更新操作信息\n * @param message 更新消息\n */\n onUpdate(message: string): void;\n}\n","/**\n * Token Manager - Token 存储和刷新管理\n * 从 oceanet.ts 提取的 token 管理逻辑\n */\n\nimport ora from 'ora';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport type { TokenPair } from '../../types/auth.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from './token-cache.js';\n\n/**\n * Token Manager 类\n * 负责与底层凭据存储和 token 缓存的交互\n */\nexport class TokenManager {\n /**\n * 构造函数\n * @param credentialStore 凭据存储实例\n * @param tokenCache token 缓存实例\n */\n constructor(\n private credentialStore: ICredentialStore,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 保存 Token\n */\n async saveToken(\n accessToken: string,\n refreshToken: string\n ): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'access_token', accessToken);\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'refresh_token', refreshToken);\n\n // 更新缓存\n this.tokenCache.setTokens(accessToken, refreshToken);\n }\n\n /**\n * 获取 Access Token\n */\n async getAccessToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getAccessToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(token, null); // 只更新 access token\n }\n\n return token;\n }\n\n /**\n * 获取 Refresh Token\n */\n async getRefreshToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getRefreshToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(null, token); // 只更新 refresh token\n }\n\n return token;\n }\n\n /**\n * 刷新 Token\n */\n async refreshAccessToken(\n refreshToken: string\n ): Promise<TokenPair> {\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n };\n\n const requestBody = { param: refreshToken };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders, requestBody);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(requestBody),\n });\n\n const duration = Date.now() - startTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n if (data.code !== 200) {\n spinner.fail('Token refresh failed');\n throw new Error(data.message || 'Refresh token failed');\n }\n\n const {\n access_token,\n refresh_token: new_refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n spinner.succeed('Token refreshed');\n\n return {\n accessToken: access_token,\n refreshToken: new_refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n } catch (error) {\n spinner.fail('Token refresh error');\n throw error;\n }\n }\n\n /**\n * 清除本地 Token\n */\n async clearTokens(): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'access_token');\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'refresh_token');\n\n // 清除缓存\n this.tokenCache.clear();\n }\n\n /**\n * 退出登录\n */\n async logout(accessToken: string): Promise<void> {\n try {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`;\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n });\n\n const duration = Date.now() - startTime;\n\n // 尝试解析响应\n let data;\n try {\n data = await response.json();\n } catch {\n // 响应可能为空\n }\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data || 'No response body', duration);\n } catch (error) {\n // 忽略退出登录错误\n }\n\n // 清除本地存储\n await this.clearTokens();\n }\n\n /**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\n async initTokenCache(): Promise<void> {\n const config = getOceanetConfig();\n\n // 并行读取两个 token(避免循环依赖)\n const [accessToken, refreshToken] = await Promise.all([\n this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token'),\n this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token')\n ]);\n\n // 同时更新缓存\n if (accessToken || refreshToken) {\n this.tokenCache.setTokens(accessToken || null, refreshToken || null);\n }\n }\n}\n\n// ============ 便利函数(向后兼容) ============\n\n/**\n * 全局 TokenManager 实例\n */\nlet tokenManagerInstance: TokenManager | null = null;\n\n/**\n * 获取 TokenManager 单例\n */\nexport function getTokenManager(): TokenManager {\n if (!tokenManagerInstance) {\n // 延迟导入以避免循环依赖\n const { getCredentialStore } = require('../../providers/credential-store.js');\n const { getGlobalTokenCache } = require('./token-cache.js');\n\n const credentialStore = getCredentialStore();\n const tokenCache = getGlobalTokenCache();\n\n tokenManagerInstance = new TokenManager(credentialStore, tokenCache);\n }\n return tokenManagerInstance;\n}\n\n/**\n * 重置 TokenManager 实例\n */\nexport function resetTokenManager(): void {\n tokenManagerInstance = null;\n}\n\n/**\n * 保存 Token(便利函数)\n */\nexport async function saveToken(\n accessToken: string,\n refreshToken: string\n): Promise<void> {\n const manager = getTokenManager();\n await manager.saveToken(accessToken, refreshToken);\n}\n\n/**\n * 获取 Access Token(便利函数)\n */\nexport async function getAccessToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getAccessToken();\n}\n\n/**\n * 获取 Refresh Token(便利函数)\n */\nexport async function getRefreshToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getRefreshToken();\n}\n\n/**\n * 刷新 Token(便利函数)\n */\nexport async function refreshAccessToken(\n refreshToken: string\n): Promise<TokenPair> {\n const manager = getTokenManager();\n return await manager.refreshAccessToken(refreshToken);\n}\n\n/**\n * 清除本地 Token(便利函数)\n */\nexport async function clearTokens(): Promise<void> {\n const manager = getTokenManager();\n await manager.clearTokens();\n}\n\n/**\n * 退出登录(便利函数)\n */\nexport async function logout(accessToken: string): Promise<void> {\n const manager = getTokenManager();\n await manager.logout(accessToken);\n}\n\n/**\n * 初始化 Token 缓存(便利函数)\n */\nexport async function initTokenCache(): Promise<void> {\n const manager = getTokenManager();\n await manager.initTokenCache();\n}\n","/**\n * Oceanet HTTP Client - 自动 Token 刷新的 HTTP 客户端\n * 从 oceanet-client.ts 重构\n *\n * 架构:\n * - BaseHttpClient: 纯 HTTP 请求\n * - AuthenticatingHttpClient: 添加认证和自动刷新\n * - ApiErrorHandler: 业务错误处理\n * - OceanetClient: 便利包装器(向后兼容)\n */\n\nimport { BaseHttpClient } from './base-http-client.js';\nimport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\n\n/**\n * Oceanet HTTP 客户端类(向后兼容的便利包装器)\n * 组合基础客户端、认证客户端和错误处理器\n */\nexport class OceanetClient implements IHttpClient {\n private authenticatingClient: AuthenticatingHttpClient;\n\n /**\n * 构造函数\n * @param tokenCache token 缓存实例(可选)\n */\n constructor(tokenCache?: ITokenCache) {\n // 如果没有提供 tokenCache,从全局获取\n let cache: ITokenCache;\n if (tokenCache) {\n cache = tokenCache;\n } else {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n cache = getGlobalTokenCache();\n }\n\n // 组合客户端链:Base -> Authenticating\n const baseClient = new BaseHttpClient();\n this.authenticatingClient = new AuthenticatingHttpClient(baseClient, cache);\n }\n\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options?: any\n ): Promise<T> {\n return this.authenticatingClient.request<T>(endpoint, options);\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.authenticatingClient.get<T>(endpoint, params);\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.post<T>(endpoint, data, headers);\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.put<T>(endpoint, data, headers);\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.authenticatingClient.delete<T>(endpoint);\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.patch<T>(endpoint, data, headers);\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n return this.authenticatingClient.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n return this.authenticatingClient.refreshToken();\n }\n}\n\n// 单例实例\nlet clientInstance: OceanetClient | null = null;\nlet lastEnvironment: string | null = null;\n\n/**\n * 清除 token 缓存\n */\nexport function clearTokenCache(): void {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n const cache = getGlobalTokenCache();\n cache.clear();\n}\n\n/**\n * 获取 HTTP 客户端单例\n * 如果环境变化,会重新创建实例并清除缓存\n */\nexport function getClient(): OceanetClient {\n const currentEnv = getOceanetConfig().ENVIRONMENT;\n\n // 环境变化时,清除缓存并重新创建客户端实例\n if (!clientInstance || lastEnvironment !== currentEnv) {\n clearTokenCache();\n clientInstance = new OceanetClient();\n lastEnvironment = currentEnv;\n }\n return clientInstance;\n}\n\n// 重新导出新组件\nexport { BaseHttpClient } from './base-http-client.js';\nexport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nexport { ApiErrorHandler, getApiErrorHandler, ApiError } from './api-error-handler.js';\nexport type { IHttpClient, IReadOnlyHttpClient, IMutatingHttpClient } from './http-client-interface.js';\n","/**\n * 基础 HTTP 客户端 - 纯 HTTP 请求逻辑\n * 不包含认证和错误处理\n */\n\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { RequestOptions, OceanetApiResponse } from '../../types/oceanet.js';\n\n/**\n * 构建 URL(添加查询参数)\n * 如果 endpoint 已经是完整 URL(以 http:// 或 https:// 开头),直接使用\n */\nfunction buildUrl(endpoint: string, params?: Record<string, string>): string {\n // 如果是完整 URL,直接使用\n if (endpoint.startsWith('http://') || endpoint.startsWith('https://')) {\n let url = endpoint;\n if (params) {\n const searchParams = new URLSearchParams(params);\n const separator = url.includes('?') ? '&' : '?';\n url += `${separator}${searchParams.toString()}`;\n }\n return url;\n }\n\n // 否则,拼接 base URL\n const config = getOceanetConfig();\n let url = `${config.API_BASE_URL}${endpoint}`;\n if (params) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n return url;\n}\n\n/**\n * 基础 HTTP 客户端实现\n * 提供纯 HTTP 请求功能,不包含认证逻辑\n */\nexport class BaseHttpClient implements IHttpClient {\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const {\n method = 'GET',\n headers = {},\n body,\n params,\n } = options;\n\n const url = buildUrl(endpoint, params);\n const requestHeaders = {\n ...headers,\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest(method, url, requestHeaders, body);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const duration = Date.now() - startTime;\n const data: OceanetApiResponse<T> = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n return data as T;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n}\n","/**\n * 认证 HTTP 客户端 - 添加认证和自动刷新功能\n * 装饰器模式,为基础 HTTP 客户端添加认证能力\n */\n\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport { getApiErrorHandler, ApiError } from './api-error-handler.js';\nimport { getRetoken } from './interceptors.js';\nimport { getTokenManager } from '../auth/token-manager.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\n\n/**\n * 认证 HTTP 客户端\n * 为基础 HTTP 客户端添加:\n * 1. 自动添加 Authorization 头\n * 2. 401 自动刷新 token 并重试\n * 3. 业务错误处理\n */\nexport class AuthenticatingHttpClient implements IHttpClient {\n private initialized = false;\n\n constructor(\n private baseClient: IHttpClient,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 确保 token 缓存已初始化\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n const tokenManager = getTokenManager();\n await tokenManager.initTokenCache();\n this.initialized = true;\n }\n }\n\n /**\n * 发起认证的 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: any = {}\n ): Promise<T> {\n await this.ensureInitialized();\n\n // 获取当前 token\n const accessToken = this.tokenCache.getAccessToken();\n if (!accessToken) {\n throw new Error(\n 'Not authenticated. Please run: wukong-cli auth login'\n );\n }\n\n // 添加认证头\n const headers = {\n ...options.headers,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n // 构建完整 URL(使用配置系统)\n const config = getOceanetConfig();\n const baseUrl = options.baseUrl || config.API_BASE_URL;\n const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;\n\n // 打印调试信息\n debugRequest(options.method || 'GET', url, headers, options.body);\n\n // 使用 ts-retoken 的 fetch 包装器\n const retoken = getRetoken();\n const startTime = Date.now();\n const response = await retoken.fetch(\n url,\n {\n method: options.method || 'GET',\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n\n const data: OceanetApiResponse<T> = await response.json();\n const duration = Date.now() - startTime;\n\n // 打印响应调试信息\n debugResponse(response.status, response.statusText, data, duration);\n\n // 处理业务错误\n const errorHandler = getApiErrorHandler();\n\n // 9913 = token不存在或已失效,尝试刷新后重试\n if (data.code === 9913) {\n return errorHandler.tryRecover(\n new ApiError(data.code, data.message || 'Token expired', true),\n async () => {\n await retoken.refreshToken();\n const newAccessToken = this.tokenCache.getAccessToken();\n if (newAccessToken) {\n const config = getOceanetConfig();\n const baseUrl = options.baseUrl || config.API_BASE_URL;\n const retryUrl = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;\n const retryResponse = await fetch(\n retryUrl,\n {\n method: options.method || 'GET',\n headers: {\n ...headers,\n 'Authorization': `Bearer ${newAccessToken}`,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n const retryData: OceanetApiResponse<T> = await retryResponse.json();\n\n if (retryData.code === 200) {\n return retryData.result;\n }\n throw new Error(\n `API Error (${retryData.code}): ${retryData.message || 'Unknown error'}`\n );\n }\n throw new Error('Failed to refresh token');\n }\n );\n }\n\n // 检查其他业务错误\n errorHandler.handle(data);\n\n return data.result;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n return retoken.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n await retoken.refreshToken();\n }\n}\n","/**\n * API 错误处理器 - 处理 Oceanet API 特定错误\n */\n\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport chalk from 'chalk';\n\n/**\n * API 错误类\n */\nexport class ApiError extends Error {\n constructor(\n public code: number,\n message: string,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\n/**\n * 错误处理函数类型\n */\ntype ErrorHandler = (response: OceanetApiResponse) => void | never;\n\n/**\n * API 错误处理器\n * 负责处理 Oceanet API 的业务错误码\n */\nexport class ApiErrorHandler {\n private errorHandlers: Map<number, ErrorHandler> = new Map();\n\n constructor() {\n // 注册默认错误处理器\n this.registerDefaultHandlers();\n }\n\n /**\n * 注册默认的 Oceanet 错误处理器\n */\n private registerDefaultHandlers(): void {\n // 9913 = token 不存在或已失效\n this.register(9913, (response) => {\n const error = new ApiError(\n response.code,\n response.message || 'Token expired or invalid',\n true // 可重试\n );\n throw error;\n });\n\n // 其他认证错误\n [401, 403].forEach(code => {\n this.register(code, (response) => {\n throw new ApiError(\n response.code,\n response.message || 'Authentication failed',\n code === 401 // 401 可以尝试刷新 token\n );\n });\n });\n }\n\n /**\n * 注册错误处理器\n * @param code 错误码\n * @param handler 处理函数\n */\n register(code: number, handler: ErrorHandler): void {\n this.errorHandlers.set(code, handler);\n }\n\n /**\n * 处理 API 响应\n * @param response API 响应\n * @throws {ApiError} 当响应包含错误时\n */\n handle(response: OceanetApiResponse): void {\n if (response.code !== 200) {\n const handler = this.errorHandlers.get(response.code);\n\n if (handler) {\n handler(response);\n }\n\n // 没有特定处理器,使用默认处理\n throw new ApiError(\n response.code,\n response.message || 'Unknown API error'\n );\n }\n }\n\n /**\n * 检查响应是否为错误\n * @param response API 响应\n * @returns 是否为错误\n */\n isError(response: OceanetApiResponse): boolean {\n return response.code !== 200;\n }\n\n /**\n * 尝试从错误中恢复\n * @param error 错误对象\n * @param recoverFunction 恢复函数\n * @returns 恢复结果或抛出错误\n */\n async tryRecover<T>(\n error: unknown,\n recoverFunction: () => Promise<T>\n ): Promise<T> {\n if (error instanceof ApiError && error.retryable) {\n console.log('');\n console.log(chalk.yellow('⚠ Token expired, attempting refresh...'));\n try {\n return await recoverFunction();\n } catch (refreshError: any) {\n console.log('');\n console.log(chalk.yellow('⚠ Auto-refresh failed:'), chalk.dim(refreshError.message));\n throw new ApiError(\n error.code,\n `${error.message} (Auto-refresh failed)`\n );\n }\n }\n throw error;\n }\n}\n\n/**\n * 获取全局错误处理器实例\n */\nlet errorHandlerInstance: ApiErrorHandler | null = null;\n\nexport function getApiErrorHandler(): ApiErrorHandler {\n if (!errorHandlerInstance) {\n errorHandlerInstance = new ApiErrorHandler();\n }\n return errorHandlerInstance;\n}\n","/**\n * HTTP 拦截器 - Token 刷新和 401 重试逻辑\n * 使用 ts-retoken 实现\n */\n\nimport { createRetoken } from 'ts-retoken';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { Tokens } from '../../types/oceanet.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\n\n/**\n * 创建带超时的 fetch\n */\nfunction createFetchWithTimeout(timeoutMs: number) {\n return async (url: string, options: any = {}) => {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${timeoutMs}ms`);\n }\n throw error;\n }\n };\n}\n\n/**\n * 创建 retoken 实例(动态获取配置)\n * 处理主动刷新和 401 重试\n * @param credentialStore 凭据存储实例(可选)\n * @param tokenCache token 缓存实例(可选)\n */\nexport function createRetokenInstance(\n credentialStore?: ICredentialStore,\n tokenCache?: ITokenCache\n) {\n const config = getOceanetConfig();\n\n // 如果没有提供实例,使用默认实现\n const store = credentialStore || (require('../../providers/credential-store.js').getCredentialStore());\n const cache = tokenCache || (require('../auth/token-cache.js').getGlobalTokenCache());\n\n return createRetoken({\n // 使用带超时的 fetch(10秒超时)\n fetch: createFetchWithTimeout(10000),\n refreshEndpoint: {\n url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,\n method: 'POST',\n // Oceanet API 要求: { \"param\": \"refresh_token_string\" }\n buildBody: (token) => JSON.stringify({ param: token }),\n headers: {\n 'Content-Type': 'application/json',\n },\n parseResponse: (data: any) => {\n // 调试:打印请求和响应\n if (config.DEBUG || (global as any).__debugMode) {\n console.log('');\n console.log('=== HTTP Request ===');\n console.log(`POST ${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`);\n console.log('Headers:');\n console.log(' Content-Type: application/json');\n console.log('Body:');\n const refreshToken = cache.getRefreshToken();\n const truncated = refreshToken && refreshToken.length > 50\n ? refreshToken.substring(0, 50) + '...'\n : refreshToken || '(none)';\n console.log(` {\"param\":\"${truncated}\"}`);\n console.log('');\n console.log('=== HTTP Response ===');\n console.log(JSON.stringify(data, null, 2));\n console.log('');\n }\n\n // 检查业务错误码 - refresh_token 过期或无效\n if (data.code === 401 || data.code === 403) {\n const error: any = new Error(data.message || 'Refresh token expired or invalid');\n error.code = data.code;\n error.isAuthFailure = true;\n throw error;\n }\n\n // Oceanet API 返回格式: { code: 200, result: { access_token, refresh_token, ... } }\n const result = data.result || data;\n\n // 验证 token 字段存在\n if (!result.access_token && !result.accessToken) {\n throw new Error('Invalid token response: missing access_token field');\n }\n if (!result.refresh_token && !result.refreshToken) {\n throw new Error('Invalid token response: missing refresh_token field');\n }\n\n return {\n accessToken: result.access_token || result.accessToken,\n refreshToken: result.refresh_token || result.refreshToken,\n };\n },\n },\n // 从缓存获取 token(同步函数)\n getAccessToken: () => {\n return cache.getAccessToken();\n },\n getRefreshToken: () => {\n return cache.getRefreshToken();\n },\n // 保存 token 到持久化存储和缓存(异步)\n setTokens: async (tokens: Tokens) => {\n // 参数验证 - 支持驼峰和下划线命名\n const accessToken = tokens?.accessToken || tokens?.access_token;\n const refreshToken = tokens?.refreshToken || tokens?.refresh_token;\n\n if (!accessToken || !refreshToken) {\n throw new Error('Invalid tokens: missing access_token or refresh_token');\n }\n\n const cfg = getOceanetConfig();\n await store.setPassword(cfg.SERVICE_NAME, 'access_token', accessToken);\n await store.setPassword(cfg.SERVICE_NAME, 'refresh_token', refreshToken);\n // 更新缓存\n cache.setTokens(accessToken, refreshToken);\n },\n // 清除 token\n clearTokens: async () => {\n const cfg = getOceanetConfig();\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n // 清除缓存\n cache.clear();\n },\n // 提前 1 分钟(60 秒)主动刷新\n expirationLeeway: 60,\n // 401 时触发重试\n retryStatuses: [401],\n // 认证完全失败时的回调\n onAuthFailure: async () => {\n const cfg = getOceanetConfig();\n try {\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n cache.clear();\n } catch {\n // 忽略清除错误\n }\n },\n });\n}\n\n// 缓存的 retoken 实例(按环境)\nconst retokenInstances: Record<string, ReturnType<typeof createRetokenInstance>> = {};\n\n/**\n * 获取当前环境的 retoken 实例\n */\nexport function getRetoken() {\n const config = getOceanetConfig();\n const env = config.ENVIRONMENT;\n\n if (!retokenInstances[env]) {\n retokenInstances[env] = createRetokenInstance();\n }\n\n return retokenInstances[env];\n}\n","/**\n * HTTP 测试命令\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { getClient } from '../core/http/client.js';\nimport { getAccessToken } from '../core/auth/token-manager.js';\nimport { OCEANET_CONFIG } from '../config/oceanet.js';\nimport { debugRequest, debugResponse } from '../utils/debug.js';\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\n\ninterface RequestOptions {\n baseUrl?: string;\n headers: string[];\n data?: string;\n}\n\n/**\n * 修复 Git Bash 路径转换问题\n */\nfunction fixGitBashPath(url: string): string {\n if (url.includes(':') && !url.startsWith('http')) {\n // 移除 Windows 路径前缀 (如 \"D:/Program Files/Git\")\n // 查找 \"/oceanet-\" 并从那里开始\n const oceanetIndex = url.indexOf('/oceanet-');\n if (oceanetIndex >= 0) {\n return url.substring(oceanetIndex);\n }\n }\n return url;\n}\n\n/**\n * 解析自定义头\n */\nfunction parseHeaders(headers: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n if (Array.isArray(headers)) {\n for (const h of headers) {\n const [key, ...valueParts] = h.split(':');\n if (key && valueParts.length > 0) {\n result[key.trim()] = valueParts.join(':').trim();\n }\n }\n }\n return result;\n}\n\n/**\n * 构建完整 URL\n */\nfunction buildUrl(url: string, baseUrl?: string): string {\n const cleanUrl = fixGitBashPath(url);\n if (cleanUrl.startsWith('http')) {\n return cleanUrl;\n }\n const config = OCEANET_CONFIG();\n const base = baseUrl || config.API_BASE_URL;\n return `${base}${cleanUrl}`;\n}\n\n/**\n * 执行 HTTP 请求\n */\nasync function executeRequest(\n method: string,\n url: string,\n options: RequestOptions\n): Promise<void> {\n const spinner = ora('Sending request...').start();\n\n try {\n // 获取 Token\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n spinner.fail('Not authenticated');\n console.error(chalk.red('Please run: wukong-cli auth login'));\n process.exit(1);\n }\n\n // 构建完整 URL\n const fullUrl = buildUrl(url, options.baseUrl);\n\n // 解析自定义头\n const customHeaders = parseHeaders(options.headers);\n\n // 构建请求头\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n ...customHeaders,\n };\n\n // 构建请求体\n let body: string | undefined;\n if (options.data) {\n body = options.data;\n // 如果没有自定义 Content-Type,使用 application/json\n if (!customHeaders['Content-Type']) {\n headers['Content-Type'] = 'application/json';\n }\n }\n\n // 发起请求\n spinner.text = `${method} ${chalk.cyan(fullUrl)}`;\n\n // 打印请求(调试模式)\n debugRequest(method, fullUrl, headers, options.data ? JSON.parse(options.data) : undefined);\n\n const startTime = Date.now();\n\n const response = await fetch(fullUrl, {\n method,\n headers,\n body: method !== 'GET' && method !== 'DELETE' ? body : undefined,\n });\n\n const duration = Date.now() - startTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n spinner.succeed('Response received');\n\n // 显示响应\n console.log('');\n console.log(chalk.dim('Status:'), response.status, response.statusText);\n console.log('');\n console.log(chalk.dim('Response:'));\n console.log(JSON.stringify(data, null, 2));\n\n } catch (error) {\n spinner.fail('Request failed');\n\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log('');\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n process.exit(1);\n }\n\n // Handle other errors\n if (error instanceof Error) {\n console.error(chalk.red(error.message));\n }\n process.exit(1);\n }\n}\n\nexport const httpCommand = new Command('http');\n\nhttpCommand.description('HTTP commands for making API requests');\n\n// GET 请求\nhttpCommand\n .command('get <url>')\n .description('Send GET request (uses configured base URL or override with -b)')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('GET', url, options);\n });\n\n// POST 请求\nhttpCommand\n .command('post <url>')\n .description('Send POST request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('POST', url, options);\n });\n\n// PUT 请求\nhttpCommand\n .command('put <url>')\n .description('Send PUT request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('PUT', url, options);\n });\n\n// DELETE 请求\nhttpCommand\n .command('delete <url>')\n .description('Send DELETE request')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('DELETE', url, options);\n });\n","/**\n * Init Command\n * 重新生成配置文件\n */\n\nimport { Command } from 'commander';\nimport { writeFileSync, existsSync, readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport chalk from 'chalk';\n\n/**\n * 获取项目根目录\n */\nfunction getProjectRoot(): string {\n let currentDir = dirname(fileURLToPath(import.meta.url));\n\n while (currentDir !== dirname(currentDir)) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = dirname(currentDir);\n }\n\n return process.cwd();\n}\n\n/**\n * 执行init命令\n */\nexport async function executeInit(): Promise<void> {\n const configPath = join(homedir(), 'wukong-cli.json');\n const templatePath = join(getProjectRoot(), 'wukong-cli.json.template');\n\n // 检查模板文件是否存在\n if (!existsSync(templatePath)) {\n console.error(chalk.red('❌ Template configuration file not found'));\n console.error(chalk.yellow(`Expected location: ${templatePath}`));\n process.exit(1);\n }\n\n try {\n // 读取模板文件\n const templateContent = readFileSync(templatePath, 'utf-8');\n\n // 检查是否覆盖现有文件\n const configExists = existsSync(configPath);\n if (configExists) {\n console.log(chalk.yellow('⚠️ Existing configuration file will be overwritten'));\n }\n\n // 写入配置文件\n writeFileSync(configPath, templateContent, 'utf-8');\n\n console.log(chalk.green('✅ Configuration file created successfully'));\n console.log(chalk.gray(`Location: ${configPath}`));\n\n if (configExists) {\n console.log(chalk.yellow('Previous configuration has been overwritten'));\n }\n\n // 显示配置预览\n try {\n const config = JSON.parse(templateContent);\n console.log(chalk.gray('\\nConfiguration preview:'));\n console.log(chalk.gray(` Default Environment: ${config.defaultEnv}`));\n console.log(chalk.gray(` Configured Environments: ${Object.keys(config.environments).join(', ')}`));\n } catch (parseError) {\n // 忽略解析错误\n }\n\n } catch (error) {\n console.error(chalk.red('❌ Failed to create configuration file'));\n console.error(chalk.yellow(`Error: ${error}`));\n process.exit(1);\n }\n}\n\n/**\n * 创建init命令\n */\nexport const initCommand = new Command('init')\n .description('Initialize configuration file (creates or overwrites ~/wukong-cli.json)')\n .action(async () => {\n await executeInit();\n });"],"mappings":"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","names":["fileURLToPath","require","writeFileSync","readFileSync","existsSync","mkdirSync","join","homedir","Command","createRequire","NpmVersionProvider","VersionChecker","chalk","ora","chalk","chalk","getDeviceFlowService","OraUICallbacks","chalk","ora","getCredentialStore","getGlobalTokenCache","url","chalk","config","baseUrl","getGlobalTokenCache","currentEnv","chalk","ora","Command","ora","chalk","buildUrl","ora","chalk","Command","Command","writeFileSync","existsSync","readFileSync","join","dirname","homedir","fileURLToPath","chalk","getProjectRoot","Command"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/debug.ts","../src/utils/version/cache.ts","../src/utils/version/provider.ts","../src/utils/version/checker.ts","../src/config/errors/config-file-error.ts","../src/constants/config.ts","../src/config/environments.ts","../src/config/config-loader.ts","../src/config/oceanet.ts","../src/core/auth/device-flow-service.ts","../src/adapters/ora-ui-callbacks.ts","../src/core/auth/keytar-adapter.ts","../src/providers/file-credential-store.ts","../src/providers/credential-store.ts","../src/core/auth/token-cache.ts","../src/cli.ts","../src/utils/version/index.ts","../src/commands/auth.ts","../src/utils/environment.ts","../src/adapters/cli-device-flow.ts","../src/core/auth/token-manager.ts","../src/core/http/client.ts","../src/core/http/base-http-client.ts","../src/core/http/authenticating-http-client.ts","../src/core/http/api-error-handler.ts","../src/core/http/interceptors.ts","../src/commands/http.ts","../src/commands/init.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Debug utilities for HTTP request/response logging\n */\n\nimport chalk from 'chalk';\n\nlet debugMode: boolean | null = null;\nlet explicitSet = false; // 标记是否显式设置过\n\n/**\n * 启用调试模式\n * @param enabled 是否启用调试模式\n * @param explicit 是否显式设置(命令行参数),默认为 true\n */\nexport function setDebugMode(enabled: boolean, explicit: boolean = true): void {\n if (explicit) {\n debugMode = enabled;\n explicitSet = true;\n }\n // 同时设置全局变量供其他模块使用\n (global as any).__debugMode = enabled;\n}\n\n/**\n * 检查是否在调试模式\n * 优先级:命令行参数(显式设置)> 环境变量 > 默认关闭\n */\nexport function isDebugMode(): boolean {\n // 如果已显式通过命令行参数设置,优先使用\n if (explicitSet) {\n return debugMode === true;\n }\n\n // 检查全局变量\n if ((global as any).__debugMode === true) {\n return true;\n }\n\n // 检查环境变量 WUKONG_CLI_DEBUG\n return process.env.WUKONG_CLI_DEBUG === 'true';\n}\n\n/**\n * 打印 HTTP 请求\n */\nexport function debugRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n): void {\n if (!isDebugMode()) return;\n\n console.log('');\n console.log(chalk.dim('=== HTTP Request ==='));\n console.log(chalk.cyan(`${method} ${url}`));\n\n if (headers) {\n console.log(chalk.dim('Headers:'));\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization') {\n // 只显示 token 的前 50 个字符\n const truncated = value.length > 50\n ? value.substring(0, 50) + '...'\n : value;\n console.log(chalk.dim(` ${key}: ${truncated}`));\n } else {\n console.log(chalk.dim(` ${key}: ${value}`));\n }\n }\n }\n\n if (body) {\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n }\n console.log('');\n}\n\n/**\n * 打印 HTTP 响应\n */\nexport function debugResponse(\n status: number,\n statusText: string,\n body: any,\n duration: number\n): void {\n if (!isDebugMode()) return;\n\n const statusColor = status >= 200 && status < 300 ? chalk.green : chalk.red;\n\n console.log(chalk.dim('=== HTTP Response') + chalk.dim(` (${duration}ms) ===`));\n console.log(statusColor(`Status: ${status} ${statusText}`));\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n console.log('');\n}\n","/**\n * Version Cache\n * Manages caching of version check results\n */\n\nexport class VersionCache {\n private lastCheckTime: number = 0;\n private cachedVersion: string | null = null;\n private checkInterval: number;\n\n /**\n * Constructor\n * @param checkInterval - Check interval in milliseconds (default: 24 hours)\n */\n constructor(checkInterval: number = 24 * 60 * 60 * 1000) {\n this.checkInterval = checkInterval;\n }\n\n /**\n * Check if a new version check should be performed\n */\n shouldCheck(): boolean {\n const now = Date.now();\n return now - this.lastCheckTime >= this.checkInterval;\n }\n\n /**\n * Get cached version\n */\n get(): string | null {\n return this.cachedVersion;\n }\n\n /**\n * Set cached version with timestamp\n */\n set(version: string): void {\n this.cachedVersion = version;\n this.lastCheckTime = Date.now();\n }\n\n /**\n * Clear cache\n */\n clear(): void {\n this.lastCheckTime = 0;\n this.cachedVersion = null;\n }\n\n /**\n * Get time since last check\n */\n getTimeSinceLastCheck(): number {\n if (this.lastCheckTime === 0) {\n return 0;\n }\n return Date.now() - this.lastCheckTime;\n }\n}\n","/**\n * Version Provider Interface\n * Abstract source of version information\n */\n\nexport interface IVersionProvider {\n /**\n * Get the latest available version\n */\n getLatestVersion(): Promise<string | null>;\n}\n\n/**\n * NPM Version Provider\n * Fetches latest version from npm registry\n */\n\nexport class NpmVersionProvider implements IVersionProvider {\n private readonly timeout: number;\n\n constructor(\n private readonly packageName: string,\n private readonly registryUrl: string\n ) {\n this.timeout = 5000; // 5 second timeout\n }\n\n /**\n * Get latest version from npm\n */\n async getLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(`${this.registryUrl}/${this.packageName}`, {\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n return null;\n }\n\n const data = await response.json();\n return data['dist-tags']?.latest || null;\n\n } catch (error) {\n // Fail silently on network errors or timeout\n return null;\n }\n }\n}\n","/**\n * Version Checker\n * Coordinates version checking with caching\n */\n\nimport type { IVersionProvider } from './provider.js';\nimport { VersionCache } from './cache.js';\n\nexport interface UpdateResult {\n hasUpdate: boolean;\n currentVersion: string;\n latestVersion: string | null;\n}\n\n/**\n * Version Checker\n * Orchestrates version checking with caching\n */\nexport class VersionChecker {\n private readonly cache: VersionCache;\n\n constructor(\n private readonly provider: IVersionProvider,\n private readonly currentVersion: string,\n cache?: VersionCache\n ) {\n this.cache = cache || new VersionCache();\n }\n\n /**\n * Compare two version strings\n * Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if equal\n */\n private compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map(Number);\n const parts2 = v2.split('.').map(Number);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n }\n\n /**\n * Check for update (cached or fresh)\n */\n async checkForUpdate(): Promise<UpdateResult> {\n // Use cached result if still valid\n if (!this.cache.shouldCheck()) {\n const cached = this.cache.get();\n if (cached) {\n return {\n hasUpdate: this.compareVersions(cached, this.currentVersion) > 0,\n currentVersion: this.currentVersion,\n latestVersion: cached,\n };\n }\n }\n\n // Perform fresh check\n const latestVersion = await this.provider.getLatestVersion();\n\n if (!latestVersion) {\n return {\n hasUpdate: false,\n currentVersion: this.currentVersion,\n latestVersion: null,\n };\n }\n\n // Update cache\n this.cache.set(latestVersion);\n\n return {\n hasUpdate: this.compareVersions(latestVersion, this.currentVersion) > 0,\n currentVersion: this.currentVersion,\n latestVersion,\n };\n }\n\n /**\n * Check in background (for async execution)\n */\n async checkInBackground(): Promise<void> {\n try {\n await this.checkForUpdate();\n } catch (error) {\n // Silently fail - result is cached, will be shown on next run\n }\n }\n\n /**\n * Clear cached data\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Get current cache info\n */\n getCacheInfo(): {\n lastCheckTime: number;\n cachedVersion: string | null;\n } {\n return {\n lastCheckTime: this.cache.lastCheckTime,\n cachedVersion: this.cache.cachedVersion,\n };\n }\n}\n","/**\n * Configuration file error types\n */\n\n/**\n * Configuration error types\n */\nexport enum ConfigErrorType {\n CONFIG_FILE_MISSING = 'CONFIG_FILE_MISSING',\n ENVIRONMENT_MISSING = 'ENVIRONMENT_MISSING',\n REQUIRED_FIELD_MISSING = 'REQUIRED_FIELD_MISSING',\n}\n\n/**\n * Structured configuration error\n * Provides actionable guidance for users\n */\nexport class ConfigFileError extends Error {\n constructor(\n public type: ConfigErrorType,\n message: string,\n public environment?: string,\n public missingFields?: string[],\n public fixSuggestion?: string\n ) {\n super(message);\n this.name = 'ConfigFileError';\n }\n\n /**\n * Format error message for user display\n */\n toUserMessage(): string {\n let message = `\\n${this.message}\\n`;\n\n if (this.environment) {\n message += `Environment: ${this.environment}\\n`;\n }\n\n if (this.missingFields && this.missingFields.length > 0) {\n message += `Missing fields: ${this.missingFields.join(', ')}\\n`;\n }\n\n if (this.fixSuggestion) {\n message += `\\n${this.fixSuggestion}\\n`;\n }\n\n return message;\n }\n}\n","/**\n * 配置常量\n * 只包含常量定义,不包含环境配置\n */\n\n/**\n * 配置文件名\n */\nexport const CONFIG_FILE = '.wukong-cli.json';\n\n/**\n * Keytar 服务名\n */\nexport const KEYTAR_SERVICE = 'wukong-cli';\n\n/**\n * Keytar 账户名\n */\nexport const KEYTAR_ACCOUNTS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n} as const;\n\n/**\n * API 端点路径\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n DEVICE_AUTHORIZE: '/oceanet-auth/pkce/device/authorize',\n DEVICE_TOKEN: '/oceanet-auth/pkce/device/token',\n REFRESH_TOKEN: '/oceanet-auth/manage/refreshToken',\n LOGOUT: '/oceanet-auth/manage/logout',\n },\n API: {\n USER_INFO: '/oceanet-auth/web/userInfo',\n },\n} as const;\n\n/**\n * 轮询配置\n */\nexport const POLL_CONFIG = {\n INTERVAL: 3, // 轮询间隔(秒)\n TIMEOUT: 300, // 轮询超时(秒)\n} as const;\n","/**\n * 多环境配置支持\n * 支持 dev/beta/uat/prod 四套环境\n */\n\nexport type Environment = 'dev' | 'beta' | 'uat' | 'prod';\n\nexport interface EnvironmentConfig {\n name: Environment;\n displayName: string;\n authBaseUrl: string;\n apiBaseUrl: string;\n clientId: string;\n}\n\n/**\n * 环境配置表(默认值)\n * 可通过配置文件或环境变量覆盖\n */\nexport const ENVIRONMENTS: Record<Environment, EnvironmentConfig> = {\n dev: {\n name: 'dev',\n displayName: 'Development',\n authBaseUrl: 'https://portal-dev.zrhsh.com',\n apiBaseUrl: 'https://nrp-dev.zrhsh.com',\n clientId: 'wukong-cli-dev',\n },\n beta: {\n name: 'beta',\n displayName: 'Testing',\n authBaseUrl: 'https://portal-beta.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode.zrhsh.com',\n clientId: 'wukong-cli-beta',\n },\n uat: {\n name: 'uat',\n displayName: 'UAT (User Acceptance Testing)',\n authBaseUrl: 'https://portal-uat.zrhsh.com',\n apiBaseUrl: 'https://nrp-pd.zrhsh.com',\n clientId: 'wukong-cli-uat',\n },\n prod: {\n name: 'prod',\n displayName: 'Production',\n authBaseUrl: 'https://portal.zrhsh.com',\n apiBaseUrl: 'https://nrp.zrhsh.com',\n clientId: 'wukong-cli-prod',\n },\n};\n\n/**\n * 默认环境\n */\nexport const DEFAULT_ENVIRONMENT: Environment = 'prod';\n\n/**\n * 验证环境名称\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env in ENVIRONMENTS;\n}\n","/**\n * 配置文件加载器\n * 支持从 wukong-cli.json 加载环境配置\n * 首次运行时自动创建默认配置文件\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport { Environment, EnvironmentConfig, ENVIRONMENTS, DEFAULT_ENVIRONMENT, isValidEnvironment } from './environments.js';\nimport { ConfigFileError, ConfigErrorType } from './errors/config-file-error.js';\n\n/**\n * 用户自定义环境配置\n */\nexport interface CustomEnvironmentConfig {\n authBaseUrl?: string;\n apiBaseUrl?: string;\n clientId?: string;\n}\n\nexport interface WukongCliConfig {\n /** 默认环境 */\n defaultEnv?: Environment;\n /** 环境配置覆盖 */\n environments?: Record<string, CustomEnvironmentConfig>;\n /** 自定义环境(非标准环境) */\n customEnvironments?: Record<string, EnvironmentConfig & { displayName: string }>;\n}\n\n/**\n * 获取用户主目录下的配置文件路径\n * 这是唯一的配置文件位置,简化了配置系统\n */\nexport function getUserConfigPath(): string {\n return join(homedir(), 'wukong-cli.json');\n}\n\n/**\n * 创建默认配置文件\n * 从模板文件读取默认配置\n */\nexport function createDefaultConfig(): void {\n const configPath = getUserConfigPath();\n\n // 如果配置文件已存在,不覆盖\n if (existsSync(configPath)) {\n return;\n }\n\n try {\n // 读取模板文件\n const templatePath = join(getProjectRoot(), 'wukong-cli.json.template');\n\n if (!existsSync(templatePath)) {\n console.warn(`Warning: Template config not found: ${templatePath}`);\n return;\n }\n\n const templateContent = readFileSync(templatePath, 'utf-8');\n const defaultConfig = JSON.parse(templateContent) as WukongCliConfig;\n\n // 确保目录存在\n const dir = dirname(configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // 写入配置文件\n writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');\n } catch (error) {\n // 静默失败,不影响程序运行\n // console.warn(`Warning: Failed to create default config: ${error}`);\n }\n}\n\n/**\n * 获取项目根目录\n */\nfunction getProjectRoot(): string {\n // 从当前文件的路径向上查找,直到找到 package.json\n let currentDir = dirname(fileURLToPath(import.meta.url));\n\n while (currentDir !== dirname(currentDir)) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = dirname(currentDir);\n }\n\n // 如果找不到,返回当前工作目录\n return process.cwd();\n}\n\n/**\n * 查找配置文件\n * 仅检查用户主目录下的配置文件\n * 简化了配置系统,消除了项目目录配置的冲突\n */\nfunction findConfigFile(): string | null {\n // 仅使用用户主目录配置\n const userConfigPath = getUserConfigPath();\n if (existsSync(userConfigPath)) {\n return userConfigPath;\n }\n\n return null;\n}\n\n/**\n * 加载配置文件\n * 如果用户主目录下没有配置文件,自动创建默认配置\n */\nexport function loadConfig(): WukongCliConfig {\n const configPath = findConfigFile();\n\n if (!configPath) {\n // 首次运行,创建默认配置\n createDefaultConfig();\n return {};\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content) as WukongCliConfig;\n return config;\n } catch (error) {\n console.warn(`Warning: Failed to load config from ${configPath}: ${error}`);\n return {};\n }\n}\n\n/**\n * 获取环境配置(支持fallback到默认配置)\n * 优先级:配置文件 > 默认配置 > 错误\n */\nexport function getMergedEnvironmentConfig(env: Environment): EnvironmentConfig {\n const config = loadConfig();\n\n // 检查环境是否有默认配置\n const defaultEnvConfig = ENVIRONMENTS[env];\n if (!defaultEnvConfig) {\n // 环境不在默认配置中,真正未知\n throw new ConfigFileError(\n ConfigErrorType.ENVIRONMENT_MISSING,\n `Unknown environment: '${env}'`,\n env,\n undefined,\n `Valid environments: ${Object.keys(ENVIRONMENTS).join(', ')}`\n );\n }\n\n // 如果配置文件中有该环境的配置,合并\n if (config.environments && env in config.environments) {\n const envConfig = config.environments[env];\n\n // 检查必需字段\n const requiredFields = ['authBaseUrl', 'apiBaseUrl', 'clientId'];\n const missingFields = requiredFields.filter(field => !(field in envConfig));\n\n if (missingFields.length > 0) {\n throw new ConfigFileError(\n ConfigErrorType.REQUIRED_FIELD_MISSING,\n `Incomplete configuration for environment '${env}'`,\n env,\n missingFields,\n `Edit your wukong-cli.json or run 'wukong-cli init' to reset`\n );\n }\n\n // 返回合并后的配置\n return {\n name: env,\n displayName: defaultEnvConfig.displayName,\n authBaseUrl: envConfig.authBaseUrl!,\n apiBaseUrl: envConfig.apiBaseUrl!,\n clientId: envConfig.clientId!,\n };\n }\n\n // 配置文件中没有该环境,使用默认配置\n // 这允许用户只配置需要的环境,其他使用默认值\n return defaultEnvConfig;\n}\n\n/**\n * 获取所有可用环境(包括自定义环境)\n */\nexport function getAllEnvironments(): Record<string, EnvironmentConfig & { displayName: string }> {\n const config = loadConfig();\n const result: Record<string, EnvironmentConfig & { displayName: string }> = { ...ENVIRONMENTS };\n\n // 添加自定义环境\n if (config.customEnvironments) {\n for (const [name, customEnv] of Object.entries(config.customEnvironments)) {\n result[name] = {\n name: name as Environment,\n displayName: customEnv.displayName || name,\n authBaseUrl: customEnv.authBaseUrl,\n apiBaseUrl: customEnv.apiBaseUrl,\n clientId: customEnv.clientId,\n };\n }\n }\n\n return result;\n}\n\n/**\n * 获取默认环境\n */\nexport function getDefaultEnvironment(): Environment {\n // 优先级:环境变量 > 配置文件 > 默认值\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n\n const config = loadConfig();\n if (config.defaultEnv && isValidEnvironment(config.defaultEnv)) {\n return config.defaultEnv;\n }\n\n return DEFAULT_ENVIRONMENT;\n}","/**\n * Oceanet Auth 配置\n * 支持多环境:dev/beta/uat/prod\n * 配置优先级:配置文件 > 错误(移除环境变量和默认值)\n */\n\nimport type { Environment, EnvironmentConfig } from '../types/config.js';\nimport {\n API_ENDPOINTS,\n POLL_CONFIG,\n} from '../constants/config.js';\nimport { isValidEnvironment } from './environments.js';\nimport { getMergedEnvironmentConfig, getDefaultEnvironment } from './config-loader.js';\n\n// 当前环境(运行时设置)\nlet currentEnv: Environment = getDefaultEnvironment();\n\n/**\n * 设置当前环境\n */\nexport function setCurrentEnvironment(env: Environment): void {\n currentEnv = env;\n}\n\n/**\n * 获取当前环境\n */\nexport function getCurrentEnvironment(): Environment {\n // 优先使用环境变量\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n return currentEnv;\n}\n\n/**\n * 获取当前环境的配置\n * 合并配置文件和默认值\n */\nexport function getEnvironmentConfig(): EnvironmentConfig {\n return getMergedEnvironmentConfig(getCurrentEnvironment());\n}\n\nconst getEnv = (key: string, defaultValue: string): string => {\n return process.env[key] || defaultValue;\n};\n\n/**\n * 动态配置(根据当前环境变化)\n */\nexport function getOceanetConfig() {\n const envConfig = getEnvironmentConfig();\n const env = getCurrentEnvironment();\n\n return {\n // 认证服务基础地址 (设备码授权、登录、登出等)\n AUTH_BASE_URL: envConfig.authBaseUrl,\n\n // 业务 API 基础地址\n API_BASE_URL: envConfig.apiBaseUrl,\n\n // 客户端 ID\n CLIENT_ID: envConfig.clientId,\n\n // Token 存储服务名(不同环境分开存储)\n SERVICE_NAME: `wukong-cli-${env}`,\n\n // 轮询配置\n POLL: POLL_CONFIG,\n\n // 认证服务端点\n AUTH_ENDPOINTS: API_ENDPOINTS.AUTH,\n\n // 业务 API 端点\n API_ENDPOINTS: API_ENDPOINTS.API,\n\n // 调试模式 (保留这个环境变量,因为它是运行时选项)\n DEBUG: getEnv('WUKONG_CLI_DEBUG', 'false') === 'true',\n\n // 当前环境信息\n ENVIRONMENT: env,\n ENVIRONMENT_DISPLAY: envConfig.displayName,\n };\n}\n\n// 向后兼容:导出获取函数而不是静态对象(延迟初始化)\n// 这样可以避免模块导入时立即执行配置加载\nexport const OCEANET_CONFIG = getOceanetConfig;\n","/**\n * Device Flow Service - 设备码授权流程(纯业务逻辑)\n * 从 device-flow.ts 提取,移除 UI 依赖\n */\n\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\n\n/**\n * 设备流程服务接口\n * 定义设备码授权流程的核心操作\n */\nexport interface IDeviceFlowService {\n /**\n * 获取设备授权码\n * @returns 设备授权响应,包含验证 URL 和设备码\n */\n getDeviceCode(): Promise<DeviceCodeResponse>;\n\n /**\n * 轮询获取 token\n * @param deviceCode 设备码\n * @returns Token 对\n */\n pollToken(deviceCode: string): Promise<TokenPair>;\n}\n\n/**\n * 设备流程服务实现\n * 纯业务逻辑,不包含 UI 依赖\n */\nexport class DeviceFlowService implements IDeviceFlowService {\n /**\n * 获取设备授权码\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_AUTHORIZE}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n },\n };\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders, requestBody);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(requestBody),\n });\n\n const duration = Date.now() - startTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n if (data.code !== 200) {\n throw new Error(\n `(${data.code}) ${data.message || 'Failed to get device code'}`\n );\n }\n\n const { verificationUri, expiresIn, interval } = data.result;\n\n // 从 URL 中提取 deviceCode\n const urlObj = new URL(verificationUri);\n const deviceCode = urlObj.searchParams.get('code') || '';\n\n return {\n verificationUri,\n deviceCode,\n expiresIn,\n interval: interval || config.POLL.INTERVAL,\n };\n }\n\n /**\n * 轮询获取 token\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n const startTime = Date.now();\n const config = getOceanetConfig();\n\n while (Date.now() - startTime < config.POLL.TIMEOUT * 1000) {\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_TOKEN}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n deviceCode,\n },\n };\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders, requestBody);\n\n const requestStartTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(requestBody),\n });\n\n const duration = Date.now() - requestStartTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n // 检查 API 错误(忽略 PENDING 状态)\n if (data.code !== 200) {\n // 静默跳过错误状态,继续轮询\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // result 为 null 或空表示 PENDING,继续轮询\n if (!data.result) {\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // 成功获取 token\n const {\n access_token,\n refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n return {\n accessToken: access_token,\n refreshToken: refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n }\n\n // 超时\n throw new Error('Authorization timed out. Please try again.');\n }\n}\n\n/**\n * 获取设备流程服务实例\n */\nexport function getDeviceFlowService(): IDeviceFlowService {\n return new DeviceFlowService();\n}\n","/**\n * Ora UI 回调实现 - 使用 ora spinner\n * CLI 特定的 UI 实现\n */\n\nimport ora, { Ora } from 'ora';\nimport type { IUICallbacks } from './ui-callbacks.js';\n\n/**\n * Ora Spinner UI 回调实现\n * 使用 ora 库提供 CLI 进度显示\n */\nexport class OraUICallbacks implements IUICallbacks {\n private spinner: Ora | null = null;\n\n onStart(message: string): void {\n this.spinner = ora(message).start();\n }\n\n onSuccess(message: string): void {\n if (this.spinner) {\n this.spinner.succeed(message);\n this.spinner = null;\n }\n }\n\n onError(message: string): void {\n if (this.spinner) {\n this.spinner.fail(message);\n this.spinner = null;\n }\n }\n\n onUpdate(message: string): void {\n if (this.spinner) {\n this.spinner.text = message;\n }\n }\n}\n","/**\n * keytar 适配器 - 处理 ESM/CommonJS 互操作\n * keytar 是可选依赖,如果不可用则返回 null\n */\n\nimport { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\nlet keytarModule: any = null;\n\ntry {\n keytarModule = require('keytar');\n} catch (error) {\n // keytar 未安装或编译失败\n keytarModule = null;\n}\n\n/**\n * 检查 keytar 是否可用\n */\nexport function isKeytarAvailable(): boolean {\n return keytarModule !== null;\n}\n\n/**\n * 设置密码\n */\nexport async function setPassword(service: string, account: string, password: string): Promise<void> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n await keytarModule.setPassword(service, account, password);\n}\n\n/**\n * 获取密码\n */\nexport async function getPassword(service: string, account: string): Promise<string | null> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.getPassword(service, account);\n}\n\n/**\n * 删除密码\n */\nexport async function deletePassword(service: string, account: string): Promise<boolean> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.deletePassword(service, account);\n}\n","/**\n * 文件凭据存储 - 作为 keytar 不可用时的降级方案\n * 将 token 存储在用户主目录的加密文件中\n */\n\nimport { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\n\n/**\n * 文件凭据存储实现\n */\nexport class FileCredentialStore {\n private configDir: string;\n\n constructor() {\n this.configDir = join(homedir(), '.wukong-cli');\n this.ensureConfigDir();\n }\n\n private ensureConfigDir(): void {\n if (!existsSync(this.configDir)) {\n mkdirSync(this.configDir, { recursive: true, mode: 0o700 });\n }\n }\n\n private getTokenPath(service: string, account: string): string {\n // 简单的文件命名:service_account.token\n const filename = `${service}_${account}.token`;\n return join(this.configDir, filename);\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n const filePath = this.getTokenPath(service, account);\n writeFileSync(filePath, password, { mode: 0o600 });\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return false;\n }\n\n try {\n unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 清除所有 token\n */\n clear(): void {\n // 简单实现:删除整个配置目录\n // 更精细的实现可以只删除 .token 文件\n }\n}\n","/**\n * 凭据存储提供者 - 抽象凭据存储接口\n * 优先使用 keytar,不可用时降级到文件存储\n */\n\nimport * as keytarAdapter from '../core/auth/keytar-adapter.js';\nimport { FileCredentialStore } from './file-credential-store.js';\n\n/**\n * 凭据存储接口\n */\nexport interface ICredentialStore {\n setPassword(service: string, account: string, password: string): Promise<void>;\n getPassword(service: string, account: string): Promise<string | null>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\n/**\n * Keytar 凭据存储实现\n */\nclass KeytarCredentialStore implements ICredentialStore {\n async setPassword(service: string, account: string, password: string): Promise<void> {\n await keytarAdapter.setPassword(service, account, password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return await keytarAdapter.getPassword(service, account);\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return await keytarAdapter.deletePassword(service, account);\n }\n}\n\n/**\n * 内存凭据存储实现(用于测试)\n */\nexport class InMemoryCredentialStore implements ICredentialStore {\n private store: Map<string, string> = new Map();\n\n private getKey(service: string, account: string): string {\n return `${service}:${account}`;\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n this.store.set(this.getKey(service, account), password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return this.store.get(this.getKey(service, account)) || null;\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return this.store.delete(this.getKey(service, account));\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n/**\n * 获取凭据存储实例\n * 自动选择:keytar 可用时使用 keytar,否则降级到文件存储\n */\nexport function getCredentialStore(): ICredentialStore {\n // 优先使用 keytar\n if (keytarAdapter.isKeytarAvailable()) {\n return new KeytarCredentialStore();\n }\n\n // 降级到文件存储\n return new FileCredentialStore();\n}\n\n/**\n * 获取测试用凭据存储实例\n */\nexport function getTestCredentialStore(): ICredentialStore {\n return new InMemoryCredentialStore();\n}\n\n/**\n * 检查是否使用安全存储(keytar)\n */\nexport function isUsingSecureStorage(): boolean {\n return keytarAdapter.isKeytarAvailable();\n}\n","/**\n * Token Cache 接口 - Token 缓存抽象\n * 用于替代全局变量 (global as any).__cachedAccessToken\n */\n\n/**\n * Token 缓存接口\n * 定义了 token 的读取、设置和清除操作\n */\nexport interface ITokenCache {\n /**\n * 获取访问令牌\n */\n getAccessToken(): string | null;\n\n /**\n * 获取刷新令牌\n */\n getRefreshToken(): string | null;\n\n /**\n * 设置令牌对\n */\n setTokens(accessToken: string, refreshToken: string): void;\n\n /**\n * 清除所有令牌\n */\n clear(): void;\n\n /**\n * 检查是否有有效的访问令牌\n */\n hasAccessToken(): boolean;\n\n /**\n * 检查是否有有效的刷新令牌\n */\n hasRefreshToken(): boolean;\n}\n\n/**\n * 内存 Token 缓存实现\n * 将 token 存储在内存中,适用于单次 CLI 会话\n */\nexport class MemoryTokenCache implements ITokenCache {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n getRefreshToken(): string | null {\n return this.refreshToken;\n }\n\n setTokens(accessToken: string, refreshToken: string): void {\n this.accessToken = accessToken;\n this.refreshToken = refreshToken;\n }\n\n clear(): void {\n this.accessToken = null;\n this.refreshToken = null;\n }\n\n hasAccessToken(): boolean {\n return this.accessToken !== null && this.accessToken.length > 0;\n }\n\n hasRefreshToken(): boolean {\n return this.refreshToken !== null && this.refreshToken.length > 0;\n }\n}\n\n/**\n * 全局 Token 缓存实例(单例)\n * 用于在整个 CLI 会话中共享同一个缓存实例\n */\nlet globalCacheInstance: ITokenCache | null = null;\n\n/**\n * 获取全局 Token 缓存实例\n * 如果不存在则创建一个新的 MemoryTokenCache 实例\n */\nexport function getGlobalTokenCache(): ITokenCache {\n if (!globalCacheInstance) {\n globalCacheInstance = new MemoryTokenCache();\n }\n return globalCacheInstance;\n}\n\n/**\n * 重置全局 Token 缓存实例\n * 用于测试或环境切换\n */\nexport function resetGlobalTokenCache(): void {\n globalCacheInstance = null;\n}\n\n/**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\nexport async function initializeTokenCache(\n loadTokens: () => Promise<{ accessToken: string | null; refreshToken: string | null }>\n): Promise<void> {\n const cache = getGlobalTokenCache();\n const { accessToken, refreshToken } = await loadTokens();\n\n if (accessToken && refreshToken) {\n cache.setTokens(accessToken, refreshToken);\n }\n}\n","/**\n * Wukong CLI 主入口\n * 命令结构: wukong-cli <command> [subcommand] [options]\n */\n\nimport { Command } from 'commander';\nimport { setDebugMode } from './utils/debug.js';\nimport { getVersionChecker } from './utils/version/index.js';\nimport { authCommands } from './commands/auth.js';\nimport { httpCommand } from './commands/http.js';\nimport { initCommand } from './commands/init.js';\n\nconst program = new Command();\n\n// 根命令配置\nprogram\n .name('wukong-cli')\n .description('Wukong CLI - TypeScript implementation')\n .version(CLI_VERSION)\n // 添加全局 --debug 选项\n .option('--debug', 'Enable debug mode (show HTTP requests)')\n // 在每个命令执行前设置调试模式\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n // 只有显式传递 --debug 时才设置为 true,否则允许环境变量生效\n if (options.debug === true) {\n setDebugMode(true, true);\n } else {\n // 不显式设置,允许环境变量生效\n setDebugMode(false, false);\n }\n });\n\n// 添加 auth 命令组\nprogram.addCommand(authCommands);\n\n// 添加 http 命令组\nprogram.addCommand(httpCommand);\n\n// 添加 init 命令\nprogram.addCommand(initCommand);\n\n// 如果没有参数,显示帮助\nif (process.argv.length === 2) {\n program.help();\n}\n\n// 先执行命令(立即响应用户)\nprogram.parse();\n\n// 命令执行完后,异步检查版本更新(不阻塞)\n// 使用 setImmediate 确保用户命令先执行\nsetImmediate(() => {\n try {\n const versionChecker = getVersionChecker();\n\n versionChecker.checkInBackground().catch(() => {\n // 静默失败,不影响正常使用\n });\n } catch {\n // Version checker not available in ESM build, silently skip\n }\n});\n","/**\n * Version Check Module\n * Testable version checking with caching\n */\n\nexport { VersionCache } from './cache.js';\nexport { NpmVersionProvider } from './provider.js';\nexport type { IVersionProvider } from './provider.js';\nexport { VersionChecker } from './checker.js';\nexport type { UpdateResult } from './checker.js';\n\n/**\n * Create VersionChecker instance (singleton pattern)\n */\nlet versionCheckerInstance: VersionChecker | null = null;\n\nexport function getVersionChecker(): VersionChecker {\n if (!versionCheckerInstance) {\n const { createRequire } = require('module');\n const nodeRequire = createRequire(import.meta.url);\n const packageJson = nodeRequire('../../package.json');\n\n const { NpmVersionProvider } = require('./provider.js');\n const { VersionChecker } = require('./checker.js');\n\n const provider = new NpmVersionProvider(\n '@zrhsh/wukong-cli',\n 'https://registry.npmjs.org'\n );\n\n versionCheckerInstance = new VersionChecker(\n provider,\n packageJson.version\n );\n }\n\n return versionCheckerInstance;\n}\n\n/**\n * Reset version checker instance (for testing)\n */\nexport function resetVersionChecker(): void {\n versionCheckerInstance = null;\n}\n","/**\n * Auth 命令组 - 基于 Oceanet Auth\n * wukong-cli auth <subcommand>\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { printEnvironmentInfo } from '../utils/environment.js';\nimport { success, error } from '../utils/symbols.js';\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\nimport { createCliDeviceFlowAdapter } from '../adapters/cli-device-flow.js';\nimport {\n saveToken,\n getAccessToken,\n logout,\n} from '../core/auth/token-manager.js';\nimport { getClient } from '../core/http/client.js';\nimport {\n Environment,\n ENVIRONMENTS,\n} from '../config/environments.js';\nimport { setCurrentEnvironment, getOceanetConfig, getCurrentEnvironment } from '../config/oceanet.js';\nimport { getAllEnvironments } from '../config/config-loader.js';\n\nexport const authCommands = new Command('auth')\n .description('Authentication commands');\n\n// 登录命令\nauthCommands\n .command('login')\n .description('Login using Device Authorization Flow')\n .action(async () => {\n try {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n // 设置当前环境\n setCurrentEnvironment(env as Environment);\n const config = getOceanetConfig();\n const envConfig = allEnvs[env];\n\n console.log('');\n console.log(chalk.bgBlue.white.bold(' Wukong CLI Login '));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log('');\n\n // 步骤 1: 获取设备授权链接(使用新 API)\n const adapter = createCliDeviceFlowAdapter();\n const { verificationUri, deviceCode, expiresIn, interval } =\n await adapter.getDeviceCode();\n\n // 显示授权信息\n console.log('');\n console.log(chalk.bold('='.repeat(50)));\n console.log(chalk.bold(' Please complete authorization'));\n console.log(chalk.bold('='.repeat(50)));\n console.log('');\n console.log(chalk.green(' Authorization URL:'));\n console.log('');\n\n // 用多种方式显示链接,确保用户能看到\n console.log(chalk.cyan(` ${verificationUri}`));\n console.log('');\n\n // 同时输出到 stderr(Claude Code 能捕获)\n console.error(chalk.yellow.bold('>>> Please open this link in your browser <<<'));\n console.error(chalk.cyan(verificationUri));\n console.error('');\n\n // 尝试自动打开浏览器(如果环境支持)\n const open = await import('open').catch(() => null);\n if (open) {\n try {\n await open.default(verificationUri);\n console.log(chalk.dim(' Browser opened automatically'));\n } catch {\n console.log(chalk.dim(' Please copy link to browser'));\n }\n } else {\n console.log(chalk.dim(' Please copy link to browser'));\n }\n console.log('');\n\n console.log(chalk.dim('═'.repeat(50)));\n console.log(chalk.dim(` Device Code: ${deviceCode}`));\n console.log(chalk.dim(` Expires in: ${expiresIn} seconds`));\n console.log(chalk.dim('═'.repeat(50)));\n console.log('');\n\n // 步骤 2: 轮询获取 Token(使用新 API)\n const tokens = await adapter.pollToken(deviceCode);\n\n // 步骤 3: 保存 Token\n await saveToken(tokens.accessToken, tokens.refreshToken);\n\n console.log('');\n console.log(chalk.bgGreen.black.bold(' [OK] Login Successful '));\n console.log('');\n console.log(chalk.green('[OK] Tokens saved securely'));\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));\n console.log('');\n console.log(chalk.dim('Next:'), chalk.cyan('wukong-cli auth status'));\n console.log('');\n\n } catch (error) {\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log('');\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n return;\n }\n\n // Handle other errors\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n }\n });\n\n// 登出命令\nauthCommands\n .command('logout')\n .description('Logout and clear saved tokens')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n\n try {\n const accessToken = await getAccessToken();\n\n if (accessToken) {\n await logout(accessToken);\n }\n\n console.log('');\n console.log(chalk.green(`[OK] Logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n } catch {\n console.log('');\n console.log(chalk.yellow(`○ Already logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n }\n });\n\n// 刷新 token 命令\nauthCommands\n .command('refresh')\n .description('Manually refresh access token')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n const envConfig = allEnvs[env];\n\n try {\n const config = getOceanetConfig();\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log('');\n console.log(chalk.yellow('[ERROR] Not authenticated'));\n printEnvironmentInfo(env, envConfig.displayName);\n console.log('');\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return; // 不使用 process.exit,让程序自然退出\n }\n\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const client = getClient();\n await client.refreshToken();\n\n spinner.succeed('Token refreshed successfully!');\n\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim('New tokens saved securely'));\n console.log('');\n } catch (error) {\n spinner.fail('Token refresh failed');\n throw error;\n }\n } catch (error) {\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log('');\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n return;\n }\n\n // Handle other errors\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Your session may have expired. Please run:`));\n console.log(chalk.dim(` wukong-cli auth login`));\n console.log('');\n // 不使用 process.exit,让程序自然退出\n }\n });\n\n// 状态命令\nauthCommands\n .command('status')\n .description('Show authentication status')\n .action(async () => {\n console.log('');\n\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n\n try {\n const config = getOceanetConfig();\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return;\n }\n\n // 尝试获取用户信息来验证 token 是否真的有效\n try {\n const client = getClient();\n const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;\n const userInfo = await client.get(userInfoUrl);\n\n // 只有 API 调用成功才显示已认证\n console.log(chalk.green('[OK] Authenticated'));\n console.log('');\n\n const displayUser = userInfo.firstName\n ? `${userInfo.firstName} (${userInfo.username})`\n : userInfo.username || 'N/A';\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim('User:'), chalk.cyan(displayUser));\n console.log(chalk.dim('Email:'), chalk.cyan(userInfo.email || 'N/A'));\n console.log(chalk.dim('OrgCode:'), chalk.cyan(userInfo.ouCode || 'N/A'));\n console.log(chalk.dim('OrgName:'), chalk.cyan(userInfo.ouName || 'N/A'));\n console.log('');\n } catch (error: any) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\n console.log('');\n\n console.log(chalk.red('Error:'), chalk.dim(errorMsg));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n } catch (error) {\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n return;\n }\n\n // Handle other errors\n console.log(chalk.yellow(`✗ Not authenticated`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n });\n","/**\n * 环境显示工具\n * prod 环境不显示环境名称,保持界面简洁\n */\n\nimport chalk from 'chalk';\n\n/**\n * 格式化环境显示(prod 环境不显示)\n */\nexport function formatEnvironmentDisplay(env: string, displayName: string): string {\n if (env === 'prod') {\n return ''; // prod 环境不显示\n }\n return `${env} - ${displayName}`;\n}\n\n/**\n * 输出环境信息(prod 环境跳过)\n */\nexport function printEnvironmentInfo(env: string, displayName: string): void {\n const display = formatEnvironmentDisplay(env, displayName);\n if (display) {\n console.log(chalk.dim(`Environment: ${chalk.cyan(display)}`));\n }\n}\n","/**\n * CLI 设备流程适配器 - 为设备流程添加 CLI UI 支持\n * 连接纯业务逻辑和 CLI UI 表现层\n */\n\nimport type { IDeviceFlowService } from '../core/auth/device-flow-service.js';\nimport type { IUICallbacks } from './ui-callbacks.js';\nimport type { DeviceCodeResponse, TokenPair } from '../types/auth.js';\n\n/**\n * CLI 设备流程适配器\n * 为设备流程服务添加 UI 反馈\n */\nexport class CliDeviceFlowAdapter {\n /**\n * 构造函数\n * @param deviceFlow 设备流程服务实例\n * @param ui UI 回调实例\n */\n constructor(\n private deviceFlow: IDeviceFlowService,\n private ui: IUICallbacks\n ) {}\n\n /**\n * 获取设备授权码(带 UI)\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n this.ui.onStart('Getting device authorization...');\n\n try {\n const result = await this.deviceFlow.getDeviceCode();\n this.ui.onSuccess('Device code obtained');\n return result;\n } catch (error: any) {\n this.ui.onError('Failed to get device code');\n throw error;\n }\n }\n\n /**\n * 轮询获取 token(带 UI)\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n this.ui.onStart('Waiting for authorization...');\n\n try {\n const result = await this.deviceFlow.pollToken(deviceCode);\n this.ui.onSuccess('Authorization successful!');\n return result;\n } catch (error: any) {\n this.ui.onError('Authorization error');\n throw error;\n }\n }\n}\n\n/**\n * 创建 CLI 设备流程适配器(使用默认实现)\n */\nexport function createCliDeviceFlowAdapter(): CliDeviceFlowAdapter {\n const { getDeviceFlowService } = require('../core/auth/device-flow-service.js');\n const { OraUICallbacks } = require('./ora-ui-callbacks.js');\n\n const deviceFlow = getDeviceFlowService();\n const ui = new OraUICallbacks();\n\n return new CliDeviceFlowAdapter(deviceFlow, ui);\n}\n","/**\n * Token Manager - Token 存储和刷新管理\n * 从 oceanet.ts 提取的 token 管理逻辑\n */\n\nimport ora from 'ora';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport type { TokenPair } from '../../types/auth.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from './token-cache.js';\n\n/**\n * Token Manager 类\n * 负责与底层凭据存储和 token 缓存的交互\n */\nexport class TokenManager {\n /**\n * 构造函数\n * @param credentialStore 凭据存储实例\n * @param tokenCache token 缓存实例\n */\n constructor(\n private credentialStore: ICredentialStore,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 保存 Token\n */\n async saveToken(\n accessToken: string,\n refreshToken: string\n ): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'access_token', accessToken);\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'refresh_token', refreshToken);\n\n // 更新缓存\n this.tokenCache.setTokens(accessToken, refreshToken);\n }\n\n /**\n * 获取 Access Token\n */\n async getAccessToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getAccessToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(token, null); // 只更新 access token\n }\n\n return token;\n }\n\n /**\n * 获取 Refresh Token\n */\n async getRefreshToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getRefreshToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(null, token); // 只更新 refresh token\n }\n\n return token;\n }\n\n /**\n * 刷新 Token\n */\n async refreshAccessToken(\n refreshToken: string\n ): Promise<TokenPair> {\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n };\n\n const requestBody = { param: refreshToken };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders, requestBody);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(requestBody),\n });\n\n const duration = Date.now() - startTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n if (data.code !== 200) {\n spinner.fail('Token refresh failed');\n throw new Error(data.message || 'Refresh token failed');\n }\n\n const {\n access_token,\n refresh_token: new_refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n spinner.succeed('Token refreshed');\n\n return {\n accessToken: access_token,\n refreshToken: new_refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n } catch (error) {\n spinner.fail('Token refresh error');\n throw error;\n }\n }\n\n /**\n * 清除本地 Token\n */\n async clearTokens(): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'access_token');\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'refresh_token');\n\n // 清除缓存\n this.tokenCache.clear();\n }\n\n /**\n * 退出登录\n */\n async logout(accessToken: string): Promise<void> {\n try {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`;\n\n const requestHeaders = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n // 打印请求(调试模式)\n debugRequest('POST', url, requestHeaders);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: requestHeaders,\n });\n\n const duration = Date.now() - startTime;\n\n // 尝试解析响应\n let data;\n try {\n data = await response.json();\n } catch {\n // 响应可能为空\n }\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data || 'No response body', duration);\n } catch (error) {\n // 忽略退出登录错误\n }\n\n // 清除本地存储\n await this.clearTokens();\n }\n\n /**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\n async initTokenCache(): Promise<void> {\n const config = getOceanetConfig();\n\n // 并行读取两个 token(避免循环依赖)\n const [accessToken, refreshToken] = await Promise.all([\n this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token'),\n this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token')\n ]);\n\n // 同时更新缓存\n if (accessToken || refreshToken) {\n this.tokenCache.setTokens(accessToken || null, refreshToken || null);\n }\n }\n}\n\n// ============ 便利函数(向后兼容) ============\n\n/**\n * 全局 TokenManager 实例\n */\nlet tokenManagerInstance: TokenManager | null = null;\n\n/**\n * 获取 TokenManager 单例\n */\nexport function getTokenManager(): TokenManager {\n if (!tokenManagerInstance) {\n // 延迟导入以避免循环依赖\n const { getCredentialStore } = require('../../providers/credential-store.js');\n const { getGlobalTokenCache } = require('./token-cache.js');\n\n const credentialStore = getCredentialStore();\n const tokenCache = getGlobalTokenCache();\n\n tokenManagerInstance = new TokenManager(credentialStore, tokenCache);\n }\n return tokenManagerInstance;\n}\n\n/**\n * 重置 TokenManager 实例\n */\nexport function resetTokenManager(): void {\n tokenManagerInstance = null;\n}\n\n/**\n * 保存 Token(便利函数)\n */\nexport async function saveToken(\n accessToken: string,\n refreshToken: string\n): Promise<void> {\n const manager = getTokenManager();\n await manager.saveToken(accessToken, refreshToken);\n}\n\n/**\n * 获取 Access Token(便利函数)\n */\nexport async function getAccessToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getAccessToken();\n}\n\n/**\n * 获取 Refresh Token(便利函数)\n */\nexport async function getRefreshToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getRefreshToken();\n}\n\n/**\n * 刷新 Token(便利函数)\n */\nexport async function refreshAccessToken(\n refreshToken: string\n): Promise<TokenPair> {\n const manager = getTokenManager();\n return await manager.refreshAccessToken(refreshToken);\n}\n\n/**\n * 清除本地 Token(便利函数)\n */\nexport async function clearTokens(): Promise<void> {\n const manager = getTokenManager();\n await manager.clearTokens();\n}\n\n/**\n * 退出登录(便利函数)\n */\nexport async function logout(accessToken: string): Promise<void> {\n const manager = getTokenManager();\n await manager.logout(accessToken);\n}\n\n/**\n * 初始化 Token 缓存(便利函数)\n */\nexport async function initTokenCache(): Promise<void> {\n const manager = getTokenManager();\n await manager.initTokenCache();\n}\n","/**\n * Oceanet HTTP Client - 自动 Token 刷新的 HTTP 客户端\n * 从 oceanet-client.ts 重构\n *\n * 架构:\n * - BaseHttpClient: 纯 HTTP 请求\n * - AuthenticatingHttpClient: 添加认证和自动刷新\n * - ApiErrorHandler: 业务错误处理\n * - OceanetClient: 便利包装器(向后兼容)\n */\n\nimport { BaseHttpClient } from './base-http-client.js';\nimport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\n\n/**\n * Oceanet HTTP 客户端类(向后兼容的便利包装器)\n * 组合基础客户端、认证客户端和错误处理器\n */\nexport class OceanetClient implements IHttpClient {\n private authenticatingClient: AuthenticatingHttpClient;\n\n /**\n * 构造函数\n * @param tokenCache token 缓存实例(可选)\n */\n constructor(tokenCache?: ITokenCache) {\n // 如果没有提供 tokenCache,从全局获取\n let cache: ITokenCache;\n if (tokenCache) {\n cache = tokenCache;\n } else {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n cache = getGlobalTokenCache();\n }\n\n // 组合客户端链:Base -> Authenticating\n const baseClient = new BaseHttpClient();\n this.authenticatingClient = new AuthenticatingHttpClient(baseClient, cache);\n }\n\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options?: any\n ): Promise<T> {\n return this.authenticatingClient.request<T>(endpoint, options);\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.authenticatingClient.get<T>(endpoint, params);\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.post<T>(endpoint, data, headers);\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.put<T>(endpoint, data, headers);\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.authenticatingClient.delete<T>(endpoint);\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.patch<T>(endpoint, data, headers);\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n return this.authenticatingClient.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n return this.authenticatingClient.refreshToken();\n }\n}\n\n// 单例实例\nlet clientInstance: OceanetClient | null = null;\nlet lastEnvironment: string | null = null;\n\n/**\n * 清除 token 缓存\n */\nexport function clearTokenCache(): void {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n const cache = getGlobalTokenCache();\n cache.clear();\n}\n\n/**\n * 获取 HTTP 客户端单例\n * 如果环境变化,会重新创建实例并清除缓存\n */\nexport function getClient(): OceanetClient {\n const currentEnv = getOceanetConfig().ENVIRONMENT;\n\n // 环境变化时,清除缓存并重新创建客户端实例\n if (!clientInstance || lastEnvironment !== currentEnv) {\n clearTokenCache();\n clientInstance = new OceanetClient();\n lastEnvironment = currentEnv;\n }\n return clientInstance;\n}\n\n// 重新导出新组件\nexport { BaseHttpClient } from './base-http-client.js';\nexport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nexport { ApiErrorHandler, getApiErrorHandler, ApiError } from './api-error-handler.js';\nexport type { IHttpClient, IReadOnlyHttpClient, IMutatingHttpClient } from './http-client-interface.js';\n","/**\n * 基础 HTTP 客户端 - 纯 HTTP 请求逻辑\n * 不包含认证和错误处理\n */\n\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { RequestOptions, OceanetApiResponse } from '../../types/oceanet.js';\n\n/**\n * 构建 URL(添加查询参数)\n * 如果 endpoint 已经是完整 URL(以 http:// 或 https:// 开头),直接使用\n */\nfunction buildUrl(endpoint: string, params?: Record<string, string>): string {\n // 如果是完整 URL,直接使用\n if (endpoint.startsWith('http://') || endpoint.startsWith('https://')) {\n let url = endpoint;\n if (params) {\n const searchParams = new URLSearchParams(params);\n const separator = url.includes('?') ? '&' : '?';\n url += `${separator}${searchParams.toString()}`;\n }\n return url;\n }\n\n // 否则,拼接 base URL\n const config = getOceanetConfig();\n let url = `${config.API_BASE_URL}${endpoint}`;\n if (params) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n return url;\n}\n\n/**\n * 基础 HTTP 客户端实现\n * 提供纯 HTTP 请求功能,不包含认证逻辑\n */\nexport class BaseHttpClient implements IHttpClient {\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const {\n method = 'GET',\n headers = {},\n body,\n params,\n } = options;\n\n const url = buildUrl(endpoint, params);\n const requestHeaders = {\n ...headers,\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest(method, url, requestHeaders, body);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const duration = Date.now() - startTime;\n const data: OceanetApiResponse<T> = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n return data as T;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n}\n","/**\n * 认证 HTTP 客户端 - 添加认证和自动刷新功能\n * 装饰器模式,为基础 HTTP 客户端添加认证能力\n */\n\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport { getApiErrorHandler, ApiError } from './api-error-handler.js';\nimport { getRetoken } from './interceptors.js';\nimport { getTokenManager } from '../auth/token-manager.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\n\n/**\n * 认证 HTTP 客户端\n * 为基础 HTTP 客户端添加:\n * 1. 自动添加 Authorization 头\n * 2. 401 自动刷新 token 并重试\n * 3. 业务错误处理\n */\nexport class AuthenticatingHttpClient implements IHttpClient {\n private initialized = false;\n\n constructor(\n private baseClient: IHttpClient,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 确保 token 缓存已初始化\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n const tokenManager = getTokenManager();\n await tokenManager.initTokenCache();\n this.initialized = true;\n }\n }\n\n /**\n * 发起认证的 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: any = {}\n ): Promise<T> {\n await this.ensureInitialized();\n\n // 获取当前 token\n const accessToken = this.tokenCache.getAccessToken();\n if (!accessToken) {\n throw new Error(\n 'Not authenticated. Please run: wukong-cli auth login'\n );\n }\n\n // 添加认证头\n const headers = {\n ...options.headers,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n // 构建完整 URL(使用配置系统)\n const config = getOceanetConfig();\n const baseUrl = options.baseUrl || config.API_BASE_URL;\n const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;\n\n // 打印调试信息\n debugRequest(options.method || 'GET', url, headers, options.body);\n\n // 使用 ts-retoken 的 fetch 包装器\n const retoken = getRetoken();\n const startTime = Date.now();\n const response = await retoken.fetch(\n url,\n {\n method: options.method || 'GET',\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n\n const data: OceanetApiResponse<T> = await response.json();\n const duration = Date.now() - startTime;\n\n // 打印响应调试信息\n debugResponse(response.status, response.statusText, data, duration);\n\n // 处理业务错误\n const errorHandler = getApiErrorHandler();\n\n // 9913 = token不存在或已失效,尝试刷新后重试\n if (data.code === 9913) {\n return errorHandler.tryRecover(\n new ApiError(data.code, data.message || 'Token expired', true),\n async () => {\n await retoken.refreshToken();\n const newAccessToken = this.tokenCache.getAccessToken();\n if (newAccessToken) {\n const config = getOceanetConfig();\n const baseUrl = options.baseUrl || config.API_BASE_URL;\n const retryUrl = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;\n const retryResponse = await fetch(\n retryUrl,\n {\n method: options.method || 'GET',\n headers: {\n ...headers,\n 'Authorization': `Bearer ${newAccessToken}`,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n const retryData: OceanetApiResponse<T> = await retryResponse.json();\n\n if (retryData.code === 200) {\n return retryData.result;\n }\n throw new Error(\n `API Error (${retryData.code}): ${retryData.message || 'Unknown error'}`\n );\n }\n throw new Error('Failed to refresh token');\n }\n );\n }\n\n // 检查其他业务错误\n errorHandler.handle(data);\n\n return data.result;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n return retoken.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n await retoken.refreshToken();\n }\n}\n","/**\n * API 错误处理器 - 处理 Oceanet API 特定错误\n */\n\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport chalk from 'chalk';\n\n/**\n * API 错误类\n */\nexport class ApiError extends Error {\n constructor(\n public code: number,\n message: string,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\n/**\n * 错误处理函数类型\n */\ntype ErrorHandler = (response: OceanetApiResponse) => void | never;\n\n/**\n * API 错误处理器\n * 负责处理 Oceanet API 的业务错误码\n */\nexport class ApiErrorHandler {\n private errorHandlers: Map<number, ErrorHandler> = new Map();\n\n constructor() {\n // 注册默认错误处理器\n this.registerDefaultHandlers();\n }\n\n /**\n * 注册默认的 Oceanet 错误处理器\n */\n private registerDefaultHandlers(): void {\n // 9913 = token 不存在或已失效\n this.register(9913, (response) => {\n const error = new ApiError(\n response.code,\n response.message || 'Token expired or invalid',\n true // 可重试\n );\n throw error;\n });\n\n // 其他认证错误\n [401, 403].forEach(code => {\n this.register(code, (response) => {\n throw new ApiError(\n response.code,\n response.message || 'Authentication failed',\n code === 401 // 401 可以尝试刷新 token\n );\n });\n });\n }\n\n /**\n * 注册错误处理器\n * @param code 错误码\n * @param handler 处理函数\n */\n register(code: number, handler: ErrorHandler): void {\n this.errorHandlers.set(code, handler);\n }\n\n /**\n * 处理 API 响应\n * @param response API 响应\n * @throws {ApiError} 当响应包含错误时\n */\n handle(response: OceanetApiResponse): void {\n if (response.code !== 200) {\n const handler = this.errorHandlers.get(response.code);\n\n if (handler) {\n handler(response);\n }\n\n // 没有特定处理器,使用默认处理\n throw new ApiError(\n response.code,\n response.message || 'Unknown API error'\n );\n }\n }\n\n /**\n * 检查响应是否为错误\n * @param response API 响应\n * @returns 是否为错误\n */\n isError(response: OceanetApiResponse): boolean {\n return response.code !== 200;\n }\n\n /**\n * 尝试从错误中恢复\n * @param error 错误对象\n * @param recoverFunction 恢复函数\n * @returns 恢复结果或抛出错误\n */\n async tryRecover<T>(\n error: unknown,\n recoverFunction: () => Promise<T>\n ): Promise<T> {\n if (error instanceof ApiError && error.retryable) {\n console.log('');\n console.log(chalk.yellow('⚠ Token expired, attempting refresh...'));\n try {\n return await recoverFunction();\n } catch (refreshError: any) {\n console.log('');\n console.log(chalk.yellow('⚠ Auto-refresh failed:'), chalk.dim(refreshError.message));\n throw new ApiError(\n error.code,\n `${error.message} (Auto-refresh failed)`\n );\n }\n }\n throw error;\n }\n}\n\n/**\n * 获取全局错误处理器实例\n */\nlet errorHandlerInstance: ApiErrorHandler | null = null;\n\nexport function getApiErrorHandler(): ApiErrorHandler {\n if (!errorHandlerInstance) {\n errorHandlerInstance = new ApiErrorHandler();\n }\n return errorHandlerInstance;\n}\n","/**\n * HTTP 拦截器 - Token 刷新和 401 重试逻辑\n * 使用 ts-retoken 实现\n */\n\nimport { createRetoken } from 'ts-retoken';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { Tokens } from '../../types/oceanet.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\n\n/**\n * 创建带超时的 fetch\n */\nfunction createFetchWithTimeout(timeoutMs: number) {\n return async (url: string, options: any = {}) => {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${timeoutMs}ms`);\n }\n throw error;\n }\n };\n}\n\n/**\n * 创建 retoken 实例(动态获取配置)\n * 处理主动刷新和 401 重试\n * @param credentialStore 凭据存储实例(可选)\n * @param tokenCache token 缓存实例(可选)\n */\nexport function createRetokenInstance(\n credentialStore?: ICredentialStore,\n tokenCache?: ITokenCache\n) {\n const config = getOceanetConfig();\n\n // 如果没有提供实例,使用默认实现\n const store = credentialStore || (require('../../providers/credential-store.js').getCredentialStore());\n const cache = tokenCache || (require('../auth/token-cache.js').getGlobalTokenCache());\n\n return createRetoken({\n // 使用带超时的 fetch(10秒超时)\n fetch: createFetchWithTimeout(10000),\n refreshEndpoint: {\n url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,\n method: 'POST',\n // Oceanet API 要求: { \"param\": \"refresh_token_string\" }\n buildBody: (token) => JSON.stringify({ param: token }),\n headers: {\n 'Content-Type': 'application/json',\n },\n parseResponse: (data: any) => {\n // 调试:打印请求和响应\n if (config.DEBUG || (global as any).__debugMode) {\n console.log('');\n console.log('=== HTTP Request ===');\n console.log(`POST ${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`);\n console.log('Headers:');\n console.log(' Content-Type: application/json');\n console.log('Body:');\n const refreshToken = cache.getRefreshToken();\n const truncated = refreshToken && refreshToken.length > 50\n ? refreshToken.substring(0, 50) + '...'\n : refreshToken || '(none)';\n console.log(` {\"param\":\"${truncated}\"}`);\n console.log('');\n console.log('=== HTTP Response ===');\n console.log(JSON.stringify(data, null, 2));\n console.log('');\n }\n\n // 检查业务错误码 - refresh_token 过期或无效\n if (data.code === 401 || data.code === 403) {\n const error: any = new Error(data.message || 'Refresh token expired or invalid');\n error.code = data.code;\n error.isAuthFailure = true;\n throw error;\n }\n\n // Oceanet API 返回格式: { code: 200, result: { access_token, refresh_token, ... } }\n const result = data.result || data;\n\n // 验证 token 字段存在\n if (!result.access_token && !result.accessToken) {\n throw new Error('Invalid token response: missing access_token field');\n }\n if (!result.refresh_token && !result.refreshToken) {\n throw new Error('Invalid token response: missing refresh_token field');\n }\n\n return {\n accessToken: result.access_token || result.accessToken,\n refreshToken: result.refresh_token || result.refreshToken,\n };\n },\n },\n // 从缓存获取 token(同步函数)\n getAccessToken: () => {\n return cache.getAccessToken();\n },\n getRefreshToken: () => {\n return cache.getRefreshToken();\n },\n // 保存 token 到持久化存储和缓存(异步)\n setTokens: async (tokens: Tokens) => {\n // 参数验证 - 支持驼峰和下划线命名\n const accessToken = tokens?.accessToken || tokens?.access_token;\n const refreshToken = tokens?.refreshToken || tokens?.refresh_token;\n\n if (!accessToken || !refreshToken) {\n throw new Error('Invalid tokens: missing access_token or refresh_token');\n }\n\n const cfg = getOceanetConfig();\n await store.setPassword(cfg.SERVICE_NAME, 'access_token', accessToken);\n await store.setPassword(cfg.SERVICE_NAME, 'refresh_token', refreshToken);\n // 更新缓存\n cache.setTokens(accessToken, refreshToken);\n },\n // 清除 token\n clearTokens: async () => {\n const cfg = getOceanetConfig();\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n // 清除缓存\n cache.clear();\n },\n // 提前 1 分钟(60 秒)主动刷新\n expirationLeeway: 60,\n // 401 时触发重试\n retryStatuses: [401],\n // 认证完全失败时的回调\n onAuthFailure: async () => {\n const cfg = getOceanetConfig();\n try {\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n cache.clear();\n } catch {\n // 忽略清除错误\n }\n },\n });\n}\n\n// 缓存的 retoken 实例(按环境)\nconst retokenInstances: Record<string, ReturnType<typeof createRetokenInstance>> = {};\n\n/**\n * 获取当前环境的 retoken 实例\n */\nexport function getRetoken() {\n const config = getOceanetConfig();\n const env = config.ENVIRONMENT;\n\n if (!retokenInstances[env]) {\n retokenInstances[env] = createRetokenInstance();\n }\n\n return retokenInstances[env];\n}\n","/**\n * HTTP 测试命令\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { getClient } from '../core/http/client.js';\nimport { getAccessToken } from '../core/auth/token-manager.js';\nimport { OCEANET_CONFIG } from '../config/oceanet.js';\nimport { debugRequest, debugResponse } from '../utils/debug.js';\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\n\ninterface RequestOptions {\n baseUrl?: string;\n headers: string[];\n data?: string;\n}\n\n/**\n * 修复 Git Bash 路径转换问题\n */\nfunction fixGitBashPath(url: string): string {\n if (url.includes(':') && !url.startsWith('http')) {\n // 移除 Windows 路径前缀 (如 \"D:/Program Files/Git\")\n // 查找 \"/oceanet-\" 并从那里开始\n const oceanetIndex = url.indexOf('/oceanet-');\n if (oceanetIndex >= 0) {\n return url.substring(oceanetIndex);\n }\n }\n return url;\n}\n\n/**\n * 解析自定义头\n */\nfunction parseHeaders(headers: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n if (Array.isArray(headers)) {\n for (const h of headers) {\n const [key, ...valueParts] = h.split(':');\n if (key && valueParts.length > 0) {\n result[key.trim()] = valueParts.join(':').trim();\n }\n }\n }\n return result;\n}\n\n/**\n * 构建完整 URL\n */\nfunction buildUrl(url: string, baseUrl?: string): string {\n const cleanUrl = fixGitBashPath(url);\n if (cleanUrl.startsWith('http')) {\n return cleanUrl;\n }\n const config = OCEANET_CONFIG();\n const base = baseUrl || config.API_BASE_URL;\n return `${base}${cleanUrl}`;\n}\n\n/**\n * 执行 HTTP 请求\n */\nasync function executeRequest(\n method: string,\n url: string,\n options: RequestOptions\n): Promise<void> {\n const spinner = ora('Sending request...').start();\n\n try {\n // 获取 Token\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n spinner.fail('Not authenticated');\n console.error(chalk.red('Please run: wukong-cli auth login'));\n process.exit(1);\n }\n\n // 构建完整 URL\n const fullUrl = buildUrl(url, options.baseUrl);\n\n // 解析自定义头\n const customHeaders = parseHeaders(options.headers);\n\n // 构建请求头\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n ...customHeaders,\n };\n\n // 构建请求体\n let body: string | undefined;\n if (options.data) {\n body = options.data;\n // 如果没有自定义 Content-Type,使用 application/json\n if (!customHeaders['Content-Type']) {\n headers['Content-Type'] = 'application/json';\n }\n }\n\n // 发起请求\n spinner.text = `${method} ${chalk.cyan(fullUrl)}`;\n\n // 打印请求(调试模式)\n debugRequest(method, fullUrl, headers, options.data ? JSON.parse(options.data) : undefined);\n\n const startTime = Date.now();\n\n const response = await fetch(fullUrl, {\n method,\n headers,\n body: method !== 'GET' && method !== 'DELETE' ? body : undefined,\n });\n\n const duration = Date.now() - startTime;\n const data = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n spinner.succeed('Response received');\n\n // 显示响应\n console.log('');\n console.log(chalk.dim('Status:'), response.status, response.statusText);\n console.log('');\n console.log(chalk.dim('Response:'));\n console.log(JSON.stringify(data, null, 2));\n\n } catch (error) {\n spinner.fail('Request failed');\n\n // Handle ConfigFileError with structured error messages\n if (error instanceof ConfigFileError) {\n console.log('');\n console.log(chalk.red(`[ERROR] Configuration Error`));\n console.log('');\n console.log(chalk.red(error.toUserMessage()));\n console.log('');\n process.exit(1);\n }\n\n // Handle other errors\n if (error instanceof Error) {\n console.error(chalk.red(error.message));\n }\n process.exit(1);\n }\n}\n\nexport const httpCommand = new Command('http');\n\nhttpCommand.description('HTTP commands for making API requests');\n\n// GET 请求\nhttpCommand\n .command('get <url>')\n .description('Send GET request (uses configured base URL or override with -b)')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('GET', url, options);\n });\n\n// POST 请求\nhttpCommand\n .command('post <url>')\n .description('Send POST request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('POST', url, options);\n });\n\n// PUT 请求\nhttpCommand\n .command('put <url>')\n .description('Send PUT request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('PUT', url, options);\n });\n\n// DELETE 请求\nhttpCommand\n .command('delete <url>')\n .description('Send DELETE request')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('DELETE', url, options);\n });\n","/**\n * Init Command\n * 重新生成配置文件\n */\n\nimport { Command } from 'commander';\nimport { writeFileSync, existsSync, readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport chalk from 'chalk';\n\n/**\n * 获取项目根目录\n */\nfunction getProjectRoot(): string {\n let currentDir = dirname(fileURLToPath(import.meta.url));\n\n while (currentDir !== dirname(currentDir)) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = dirname(currentDir);\n }\n\n return process.cwd();\n}\n\n/**\n * 执行init命令\n */\nexport async function executeInit(): Promise<void> {\n const configPath = join(homedir(), 'wukong-cli.json');\n const templatePath = join(getProjectRoot(), 'wukong-cli.json.template');\n\n // 检查模板文件是否存在\n if (!existsSync(templatePath)) {\n console.error(chalk.red('❌ Template configuration file not found'));\n console.error(chalk.yellow(`Expected location: ${templatePath}`));\n process.exit(1);\n }\n\n try {\n // 读取模板文件\n const templateContent = readFileSync(templatePath, 'utf-8');\n\n // 检查是否覆盖现有文件\n const configExists = existsSync(configPath);\n if (configExists) {\n console.log(chalk.yellow('⚠️ Existing configuration file will be overwritten'));\n }\n\n // 写入配置文件\n writeFileSync(configPath, templateContent, 'utf-8');\n\n console.log(chalk.green('✅ Configuration file created successfully'));\n console.log(chalk.gray(`Location: ${configPath}`));\n\n if (configExists) {\n console.log(chalk.yellow('Previous configuration has been overwritten'));\n }\n\n // 显示配置预览\n try {\n const config = JSON.parse(templateContent);\n console.log(chalk.gray('\\nConfiguration preview:'));\n console.log(chalk.gray(` Default Environment: ${config.defaultEnv}`));\n console.log(chalk.gray(` Configured Environments: ${Object.keys(config.environments).join(', ')}`));\n } catch (parseError) {\n // 忽略解析错误\n }\n\n } catch (error) {\n console.error(chalk.red('❌ Failed to create configuration file'));\n console.error(chalk.yellow(`Error: ${error}`));\n process.exit(1);\n }\n}\n\n/**\n * 创建init命令\n */\nexport const initCommand = new Command('init')\n .description('Initialize configuration file (creates or overwrites ~/wukong-cli.json)')\n .action(async () => {\n await executeInit();\n });"],"mappings":"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","names":["fileURLToPath","require","writeFileSync","readFileSync","existsSync","mkdirSync","join","homedir","Command","createRequire","NpmVersionProvider","VersionChecker","chalk","ora","chalk","getDeviceFlowService","OraUICallbacks","ora","getCredentialStore","getGlobalTokenCache","url","chalk","config","baseUrl","getGlobalTokenCache","currentEnv","chalk","ora","Command","ora","chalk","buildUrl","ora","chalk","Command","Command","writeFileSync","existsSync","readFileSync","join","dirname","homedir","fileURLToPath","chalk","getProjectRoot","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zrhsh/wukong-cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Wukong CLI - TypeScript with auto token refresh",
5
5
  "private": false,
6
6
  "type": "module",
@@ -36,6 +36,8 @@
36
36
  "test:e2e:interactive:beta": "cross-env WUKONG_CLI_ENV=beta vitest run tests/e2e/interactive/",
37
37
  "test:e2e:interactive:prod": "cross-env WUKONG_CLI_ENV=prod vitest run tests/e2e/interactive/",
38
38
  "test:e2e:interactive:run": "node scripts/run-interactive-e2e.cjs",
39
+ "prepack": "npm run build",
40
+ "prepare": "npm run build",
39
41
  "prepublishOnly": "npm run build && npm run verify",
40
42
  "postinstall": "node scripts/install.js",
41
43
  "publish:patch": "npm version patch && npm publish",
@@ -45,11 +47,9 @@
45
47
  "dependencies": {
46
48
  "axios": "^1.6.0",
47
49
  "chalk": "^5.3.0",
48
- "cli-table3": "^0.6.5",
49
50
  "commander": "^12.0.0",
50
51
  "open": "^11.0.0",
51
52
  "ora": "^8.0.0",
52
- "prompts": "^2.4.2",
53
53
  "ts-retoken": "^0.2.0"
54
54
  },
55
55
  "optionalDependencies": {