@zrhsh/wukong-cli 0.4.15 → 0.4.16

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/dist/cli.js CHANGED
@@ -2637,11 +2637,23 @@ var NpmUpdater = class {
2637
2637
  return new Promise((resolve, reject) => {
2638
2638
  const child = this.spawnFn(
2639
2639
  "npm",
2640
- ["install", "-g", "@zrhsh/wukong-cli@latest"],
2640
+ [
2641
+ "install",
2642
+ "-g",
2643
+ "@zrhsh/wukong-cli@latest",
2644
+ "--loglevel=error",
2645
+ // Only show errors
2646
+ "--no-audit",
2647
+ // Disable audit report
2648
+ "--no-fund"
2649
+ // Disable funding message
2650
+ ],
2641
2651
  this.getSpawnOptions()
2642
2652
  );
2643
- child.stdout?.pipe(process.stdout);
2644
- child.stderr?.pipe(process.stderr);
2653
+ let stderr = "";
2654
+ child.stderr?.on("data", (data) => {
2655
+ stderr += data.toString();
2656
+ });
2645
2657
  child.on("error", (error) => {
2646
2658
  reject(
2647
2659
  new UpdateExecutionError(
@@ -2655,12 +2667,8 @@ var NpmUpdater = class {
2655
2667
  resolve();
2656
2668
  return;
2657
2669
  }
2658
- reject(
2659
- new UpdateExecutionError(
2660
- `npm install failed with exit code ${code}`,
2661
- code
2662
- )
2663
- );
2670
+ const errorMessage = stderr.trim() ? `npm install failed: ${stderr.trim()}` : `npm install failed with exit code ${code}`;
2671
+ reject(new UpdateExecutionError(errorMessage, code));
2664
2672
  });
2665
2673
  });
2666
2674
  }
@@ -2691,26 +2699,28 @@ async function runUpdateCommand({
2691
2699
  return 0;
2692
2700
  }
2693
2701
  if (comparison > 0) {
2694
- output.log("Skip update.");
2702
+ output.log("Skip update (current version is newer)");
2695
2703
  return 0;
2696
2704
  }
2697
- output.log("Updating with npm...");
2705
+ output.log("Updating wukong-cli...");
2698
2706
  try {
2699
2707
  await updater.updateToLatest();
2700
- output.log("\u2705 Update completed successfully!");
2708
+ output.log("Update completed successfully!");
2701
2709
  output.log(`Updated from ${currentVersion} to ${latestVersion}`);
2702
2710
  output.log("Run: wukong-cli --version to verify.");
2703
2711
  return 0;
2704
2712
  } catch (error) {
2705
2713
  const message = error instanceof Error ? error.message : String(error);
2706
- output.error(`Update failed: ${message}`);
2714
+ output.error("Update failed!");
2715
+ output.error(message);
2716
+ output.error("");
2707
2717
  output.error(`Manual update: ${MANUAL_UPDATE_COMMAND}`);
2708
2718
  return 1;
2709
2719
  }
2710
2720
  }
2711
2721
  var updateCommand = new Command4("update").description("Update wukong-cli to the latest npm version").action(async () => {
2712
2722
  const exitCode = await runUpdateCommand({
2713
- currentVersion: "0.4.15",
2723
+ currentVersion: "0.4.16",
2714
2724
  versionProvider: new NpmVersionProvider(
2715
2725
  "@zrhsh/wukong-cli",
2716
2726
  "https://registry.npmjs.org"
@@ -2725,7 +2735,7 @@ var updateCommand = new Command4("update").description("Update wukong-cli to the
2725
2735
 
2726
2736
  // src/cli.ts
2727
2737
  var program = new Command5();
2728
- program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.15").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
2738
+ program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.16").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
2729
2739
  const options = thisCommand.opts();
2730
2740
  if (options.debug === true) {
2731
2741
  setDebugMode(true, true);
@@ -2743,7 +2753,7 @@ if (process.argv.length === 2) {
2743
2753
  program.parse();
2744
2754
  setImmediate(() => {
2745
2755
  try {
2746
- const versionChecker = getVersionChecker("0.4.15");
2756
+ const versionChecker = getVersionChecker("0.4.16");
2747
2757
  const notifier = new ConsoleNotifier();
2748
2758
  versionChecker.checkInBackground(notifier).catch(() => {
2749
2759
  });
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/debug.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/utils/version/checker.ts","../src/utils/version/cache.ts","../src/utils/version/compare.ts","../src/utils/version/provider.ts","../src/utils/version/persistent-cache.ts","../src/utils/version/notifier.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","../src/commands/update.ts","../src/core/update/npm-updater.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('');\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 * 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","/**\r\n * 配置常量\r\n * 只包含常量定义,不包含环境配置\r\n */\r\n\r\n/**\r\n * 配置文件名\r\n */\r\nexport const CONFIG_FILE = '.wukong-cli.json';\r\n\r\n/**\r\n * Keytar 服务名\r\n */\r\nexport const KEYTAR_SERVICE = 'wukong-cli';\r\n\r\n/**\r\n * Keytar 账户名\r\n */\r\nexport const KEYTAR_ACCOUNTS = {\r\n ACCESS_TOKEN: 'access_token',\r\n REFRESH_TOKEN: 'refresh_token',\r\n YST_ACCESS_TOKEN: 'yst_access_token',\r\n YST_REFRESH_TOKEN: 'yst_refresh_token',\r\n} as const;\r\n\r\n/**\r\n * API 端点路径\r\n */\r\nexport const API_ENDPOINTS = {\r\n AUTH: {\r\n DEVICE_AUTHORIZE: '/oceanet-auth/pkce/device/authorize',\r\n DEVICE_TOKEN: '/oceanet-auth/pkce/device/token',\r\n REFRESH_TOKEN: '/oceanet-auth/manage/refreshToken',\r\n REFRESH_TOKEN_NRP: '/oceanet-auth/manage/refreshTokenNRP',\r\n LOGOUT: '/oceanet-auth/manage/logout',\r\n },\r\n API: {\r\n USER_INFO: '/oceanet-auth/web/userInfo',\r\n },\r\n} as const;\r\n\r\n/**\r\n * 轮询配置\r\n */\r\nexport const POLL_CONFIG = {\r\n INTERVAL: 3, // 轮询间隔(秒)\r\n TIMEOUT: 300, // 轮询超时(秒)\r\n} as const;\r\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 */\nconst CONFIG_DIR = join(homedir(), '.wukong-cli');\nconst CONFIG_FILE_PATH = join(CONFIG_DIR, 'wukong-cli.json');\n\n/**\n * 获取用户配置文件路径\n * 配置文件位于 ~/.wukong-cli/wukong-cli.json\n */\nexport function getUserConfigPath(): string {\n return CONFIG_FILE_PATH;\n}\n\n/**\n * 确保配置目录存在\n */\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\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 ensureConfigDir();\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","/**\r\n * Device Flow Service - 设备码授权流程(纯业务逻辑)\r\n * 从 device-flow.ts 提取,移除 UI 依赖\r\n */\r\n\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\r\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\r\n\r\n/**\r\n * 设备流程服务接口\r\n * 定义设备码授权流程的核心操作\r\n */\r\nexport interface IDeviceFlowService {\r\n /**\r\n * 获取设备授权码\r\n * @returns 设备授权响应,包含验证 URL 和设备码\r\n */\r\n getDeviceCode(): Promise<DeviceCodeResponse>;\r\n\r\n /**\r\n * 轮询获取 token\r\n * @param deviceCode 设备码\r\n * @returns Token 对\r\n */\r\n pollToken(deviceCode: string): Promise<TokenPair>;\r\n}\r\n\r\n/**\r\n * 设备流程服务实现\r\n * 纯业务逻辑,不包含 UI 依赖\r\n */\r\nexport class DeviceFlowService implements IDeviceFlowService {\r\n /**\r\n * 获取设备授权码\r\n */\r\n async getDeviceCode(): Promise<DeviceCodeResponse> {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_AUTHORIZE}`;\r\n const requestBody = {\r\n param: {\r\n clientId: config.CLIENT_ID,\r\n },\r\n };\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n // 打印请求(调试模式)\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n const data = await response.json();\r\n\r\n // 打印响应(调试模式)\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n if (data.code !== 200) {\r\n throw new Error(\r\n `(${data.code}) ${data.message || 'Failed to get device code'}`\r\n );\r\n }\r\n\r\n const { verificationUri, expiresIn, interval } = data.result;\r\n\r\n // 从 URL 中提取 deviceCode\r\n const urlObj = new URL(verificationUri);\r\n const deviceCode = urlObj.searchParams.get('code') || '';\r\n\r\n return {\r\n verificationUri,\r\n deviceCode,\r\n expiresIn,\r\n interval: interval || config.POLL.INTERVAL,\r\n };\r\n }\r\n\r\n /**\r\n * 轮询获取 token\r\n */\r\n async pollToken(deviceCode: string): Promise<TokenPair> {\r\n const startTime = Date.now();\r\n const config = getOceanetConfig();\r\n\r\n while (Date.now() - startTime < config.POLL.TIMEOUT * 1000) {\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_TOKEN}`;\r\n const requestBody = {\r\n param: {\r\n clientId: config.CLIENT_ID,\r\n deviceCode,\r\n },\r\n };\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n // 打印请求(调试模式)\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const requestStartTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - requestStartTime;\r\n const data = await response.json();\r\n\r\n // 打印响应(调试模式)\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n // 检查 API 错误(忽略 PENDING 状态)\r\n if (data.code !== 200) {\r\n // 静默跳过错误状态,继续轮询\r\n await new Promise((resolve) =>\r\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\r\n );\r\n continue;\r\n }\r\n\r\n // result 为 null 或空表示 PENDING,继续轮询\r\n if (!data.result) {\r\n await new Promise((resolve) =>\r\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\r\n );\r\n continue;\r\n }\r\n\r\n // 成功获取 token\r\n const {\r\n access_token,\r\n refresh_token,\r\n expires_in,\r\n token_type,\r\n scope,\r\n yst_access_token,\r\n yst_refresh_token,\r\n } = data.result;\r\n\r\n return {\r\n accessToken: access_token,\r\n refreshToken: refresh_token,\r\n expiresIn: expires_in,\r\n tokenType: token_type,\r\n scope: Array.isArray(scope) ? scope : [scope || ''],\r\n ...(yst_access_token ? { ystAccessToken: yst_access_token } : {}),\r\n ...(yst_refresh_token ? { ystRefreshToken: yst_refresh_token } : {}),\r\n };\r\n }\r\n\r\n // 超时\r\n throw new Error('Authorization timed out. Please try again.');\r\n }\r\n}\r\n\r\n/**\r\n * 获取设备流程服务实例\r\n */\r\nexport function getDeviceFlowService(): IDeviceFlowService {\r\n return new DeviceFlowService();\r\n}\r\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","/**\r\n * Token Cache 接口 - Token 缓存抽象\r\n * 用于替代全局变量 (global as any).__cachedAccessToken\r\n */\r\n\r\n/**\r\n * Token 缓存接口\r\n * 定义了 token 的读取、设置和清除操作\r\n */\r\nexport interface ITokenCache {\r\n getAccessToken(): string | null;\r\n getRefreshToken(): string | null;\r\n getYstAccessToken(): string | null;\r\n getYstRefreshToken(): string | null;\r\n setTokens(accessToken: string | null, refreshToken: string | null, ystAccessToken?: string | null, ystRefreshToken?: string | null): void;\r\n clear(): void;\r\n hasAccessToken(): boolean;\r\n hasRefreshToken(): boolean;\r\n}\r\n\r\n/**\r\n * 内存 Token 缓存实现\r\n * 将 token 存储在内存中,适用于单次 CLI 会话\r\n */\r\nexport class MemoryTokenCache implements ITokenCache {\r\n private accessToken: string | null = null;\r\n private refreshToken: string | null = null;\r\n private ystAccessToken: string | null = null;\r\n private ystRefreshToken: string | null = null;\r\n\r\n getAccessToken(): string | null {\r\n return this.accessToken;\r\n }\r\n\r\n getRefreshToken(): string | null {\r\n return this.refreshToken;\r\n }\r\n\r\n getYstAccessToken(): string | null {\r\n return this.ystAccessToken;\r\n }\r\n\r\n getYstRefreshToken(): string | null {\r\n return this.ystRefreshToken;\r\n }\r\n\r\n setTokens(accessToken: string | null, refreshToken: string | null, ystAccessToken?: string | null, ystRefreshToken?: string | null): void {\r\n if (accessToken !== null) this.accessToken = accessToken;\r\n if (refreshToken !== null) this.refreshToken = refreshToken;\r\n if (ystAccessToken !== undefined && ystAccessToken !== null) this.ystAccessToken = ystAccessToken;\r\n if (ystRefreshToken !== undefined && ystRefreshToken !== null) this.ystRefreshToken = ystRefreshToken;\r\n }\r\n\r\n clear(): void {\r\n this.accessToken = null;\r\n this.refreshToken = null;\r\n this.ystAccessToken = null;\r\n this.ystRefreshToken = null;\r\n }\r\n\r\n hasAccessToken(): boolean {\r\n return this.accessToken !== null && this.accessToken.length > 0;\r\n }\r\n\r\n hasRefreshToken(): boolean {\r\n return this.refreshToken !== null && this.refreshToken.length > 0;\r\n }\r\n}\r\n\r\n/**\r\n * 全局 Token 缓存实例(单例)\r\n * 用于在整个 CLI 会话中共享同一个缓存实例\r\n */\r\nlet globalCacheInstance: ITokenCache | null = null;\r\n\r\n/**\r\n * 获取全局 Token 缓存实例\r\n * 如果不存在则创建一个新的 MemoryTokenCache 实例\r\n */\r\nexport function getGlobalTokenCache(): ITokenCache {\r\n if (!globalCacheInstance) {\r\n globalCacheInstance = new MemoryTokenCache();\r\n }\r\n return globalCacheInstance;\r\n}\r\n\r\n/**\r\n * 重置全局 Token 缓存实例\r\n * 用于测试或环境切换\r\n */\r\nexport function resetGlobalTokenCache(): void {\r\n globalCacheInstance = null;\r\n}\r\n\r\n/**\r\n * 初始化 Token 缓存\r\n * 从持久化存储加载 token 到内存缓存\r\n */\r\nexport async function initializeTokenCache(\r\n loadTokens: () => Promise<{ accessToken: string | null; refreshToken: string | null }>\r\n): Promise<void> {\r\n const cache = getGlobalTokenCache();\r\n const { accessToken, refreshToken } = await loadTokens();\r\n\r\n if (accessToken && refreshToken) {\r\n cache.setTokens(accessToken, refreshToken);\r\n }\r\n}\r\n","/**\n * Wukong CLI 主入口\n * 命令结构: wukong-cli <command> [subcommand] [options]\n */\n\ndeclare const CLI_VERSION: string;\n\nimport { Command } from 'commander';\nimport { setDebugMode } from './utils/debug.js';\nimport { getVersionChecker } from './utils/version/index.js';\nimport { ConsoleNotifier } from './utils/version/notifier.js';\nimport { authCommands } from './commands/auth.js';\nimport { httpCommand } from './commands/http.js';\nimport { initCommand } from './commands/init.js';\nimport { updateCommand } from './commands/update.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// 添加 update 命令\nprogram.addCommand(updateCommand);\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(CLI_VERSION);\n const notifier = new ConsoleNotifier();\n\n versionChecker.checkInBackground(notifier).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\nimport { VersionChecker } from './checker.js';\nimport { NpmVersionProvider } from './provider.js';\nimport { PersistentVersionCache } from './persistent-cache.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\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';\nexport { compareVersions, describeVersionComparison } from './compare.js';\nexport type { VersionComparison } from './compare.js';\nexport { PersistentVersionCache } from './persistent-cache.js';\nexport { ConsoleNotifier } from './notifier.js';\nexport type { UpdateNotifier } from './notifier.js';\n\n/**\n * Create VersionChecker instance (singleton pattern)\n */\nlet versionCheckerInstance: VersionChecker | null = null;\n\nexport function getVersionChecker(currentVersion: string): VersionChecker {\n if (versionCheckerInstance) {\n return versionCheckerInstance;\n }\n\n const cacheFilePath = join(homedir(), '.wukong-cli', 'version-cache.json');\n const provider = new NpmVersionProvider(\n '@zrhsh/wukong-cli',\n 'https://registry.npmjs.org'\n );\n\n const instance: VersionChecker = new VersionChecker(\n provider,\n currentVersion,\n new PersistentVersionCache(cacheFilePath)\n );\n\n versionCheckerInstance = instance;\n return instance;\n}\n\n/**\n * Reset version checker instance (for testing)\n */\nexport function resetVersionChecker(): void {\n versionCheckerInstance = null;\n}\n","/**\n * Version Checker\n * Coordinates version checking with caching\n */\n\nimport type { IVersionProvider } from './provider.js';\nimport { VersionCache } from './cache.js';\nimport { compareVersions } from './compare.js';\nimport type { UpdateNotifier } from './notifier.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 * 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: 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: 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(notifier?: UpdateNotifier): Promise<void> {\n try {\n const result = await this.checkForUpdate();\n if (result.hasUpdate && notifier && result.latestVersion) {\n notifier.notify(result.currentVersion, result.latestVersion);\n }\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.lastCheck,\n cachedVersion: this.cache.version,\n };\n }\n}\n","/**\n * Version Cache\n * Manages caching of version check results\n */\n\nexport class VersionCache {\n protected lastCheckTime: number = 0;\n protected 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 /** Last check timestamp */\n get lastCheck(): number {\n return this.lastCheckTime;\n }\n\n /** Cached version string */\n get version(): string | null {\n return this.cachedVersion;\n }\n}\n","/**\n * Version comparison utilities.\n */\n\nexport type VersionComparison = -1 | 0 | 1;\n\nexport function compareVersions(v1: string, v2: string): VersionComparison {\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\nexport function describeVersionComparison(\n currentVersion: string,\n latestVersion: string\n): string {\n const comparison = compareVersions(currentVersion, latestVersion);\n\n if (comparison > 0) {\n return 'current version is newer than latest';\n }\n\n if (comparison < 0) {\n return 'latest version is newer';\n }\n\n return 'current version is equal to latest';\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","import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { VersionCache } from './cache.js';\n\ninterface CacheData {\n lastCheckTime: number;\n version: string;\n}\n\nexport class PersistentVersionCache extends VersionCache {\n private readonly cacheFilePath: string;\n\n constructor(cacheFilePath: string, checkInterval?: number) {\n super(checkInterval);\n this.cacheFilePath = cacheFilePath;\n this.loadFromFile();\n }\n\n private loadFromFile(): void {\n try {\n const content = readFileSync(this.cacheFilePath, 'utf-8');\n const data: CacheData = JSON.parse(content);\n\n if (typeof data.lastCheckTime === 'number' && typeof data.version === 'string') {\n this.lastCheckTime = data.lastCheckTime;\n this.cachedVersion = data.version;\n }\n } catch {\n // 文件不存在或内容损坏,使用默认空状态\n }\n }\n\n private saveToFile(): void {\n try {\n mkdirSync(dirname(this.cacheFilePath), { recursive: true });\n const data: CacheData = {\n lastCheckTime: this.lastCheckTime,\n version: this.cachedVersion ?? '',\n };\n writeFileSync(this.cacheFilePath, JSON.stringify(data), 'utf-8');\n } catch {\n // 写入失败,静默跳过,内存缓存仍然有效\n }\n }\n\n set(version: string): void {\n super.set(version);\n this.saveToFile();\n }\n\n clear(): void {\n super.clear();\n this.saveToFile();\n }\n}\n","import chalk from 'chalk';\n\nexport interface UpdateNotifier {\n notify(currentVersion: string, latestVersion: string): void;\n}\n\nexport class ConsoleNotifier implements UpdateNotifier {\n notify(currentVersion: string, latestVersion: string): void {\n const message = `New version available: ${currentVersion} → ${latestVersion}, run 'wukong-cli update' to update.`;\n console.log(chalk.yellow(message));\n }\n}\n","/**\r\n * Auth 命令组 - 基于 Oceanet Auth\r\n * wukong-cli auth <subcommand>\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport chalk from 'chalk';\r\nimport ora from 'ora';\r\nimport { printEnvironmentInfo } from '../utils/environment.js';\r\nimport { success, error } from '../utils/symbols.js';\r\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\r\nimport { createCliDeviceFlowAdapter } from '../adapters/cli-device-flow.js';\r\nimport {\r\n saveToken,\r\n getAccessToken,\r\n getRefreshToken,\r\n getYstAccessToken,\r\n getYstRefreshToken,\r\n getTokenManager,\r\n logout,\r\n} from '../core/auth/token-manager.js';\r\nimport { getClient } from '../core/http/client.js';\r\nimport {\r\n Environment,\r\n ENVIRONMENTS,\r\n} from '../config/environments.js';\r\nimport { setCurrentEnvironment, getOceanetConfig, getCurrentEnvironment } from '../config/oceanet.js';\r\nimport { getAllEnvironments } from '../config/config-loader.js';\r\n\r\nexport const authCommands = new Command('auth')\r\n .description('Authentication commands');\r\n\r\n// 登录命令\r\nauthCommands\r\n .command('login')\r\n .description('Login using Device Authorization Flow')\r\n .action(async () => {\r\n try {\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n // 设置当前环境\r\n setCurrentEnvironment(env as Environment);\r\n const config = getOceanetConfig();\r\n const envConfig = allEnvs[env];\r\n\r\n console.log('');\r\n console.log(chalk.bgBlue.white.bold(' Wukong CLI Login '));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log('');\r\n\r\n // 步骤 1: 获取设备授权链接(使用新 API)\r\n const adapter = createCliDeviceFlowAdapter();\r\n const { verificationUri, deviceCode, expiresIn, interval } =\r\n await adapter.getDeviceCode();\r\n\r\n // 显示授权信息\r\n console.log('');\r\n console.log(chalk.bold('='.repeat(50)));\r\n console.log(chalk.bold(' Please complete authorization'));\r\n console.log(chalk.bold('='.repeat(50)));\r\n console.log('');\r\n console.log(chalk.green(' Authorization URL:'));\r\n console.log('');\r\n\r\n // 用多种方式显示链接,确保用户能看到\r\n console.log(chalk.cyan(` ${verificationUri}`));\r\n console.log('');\r\n\r\n // 同时输出到 stderr(Claude Code 能捕获)\r\n console.error(chalk.yellow.bold('>>> Please open this link in your browser <<<'));\r\n console.error(chalk.cyan(verificationUri));\r\n console.error('');\r\n\r\n // 尝试自动打开浏览器(如果环境支持)\r\n const open = await import('open').catch(() => null);\r\n if (open) {\r\n try {\r\n await open.default(verificationUri);\r\n console.log(chalk.dim(' Browser opened automatically'));\r\n } catch {\r\n console.log(chalk.dim(' Please copy link to browser'));\r\n }\r\n } else {\r\n console.log(chalk.dim(' Please copy link to browser'));\r\n }\r\n console.log('');\r\n\r\n console.log(chalk.dim('═'.repeat(50)));\r\n console.log(chalk.dim(` Device Code: ${deviceCode}`));\r\n console.log(chalk.dim(` Expires in: ${expiresIn} seconds`));\r\n console.log(chalk.dim('═'.repeat(50)));\r\n console.log('');\r\n\r\n // 步骤 2: 轮询获取 Token(使用新 API)\r\n const tokens = await adapter.pollToken(deviceCode);\r\n\r\n // 步骤 3: 保存 Token\r\n await saveToken({\r\n accessToken: tokens.accessToken,\r\n refreshToken: tokens.refreshToken,\r\n ystAccessToken: tokens.ystAccessToken,\r\n ystRefreshToken: tokens.ystRefreshToken,\r\n });\r\n\r\n console.log('');\r\n console.log(chalk.bgGreen.black.bold(' [OK] Login Successful '));\r\n console.log('');\r\n console.log(chalk.green('[OK] Tokens saved securely'));\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));\r\n console.log('');\r\n console.log(chalk.dim('Next:'), chalk.cyan('wukong-cli auth status'));\r\n console.log('');\r\n\r\n } catch (error) {\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // Handle other errors\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n console.log('');\r\n }\r\n });\r\n\r\n// 登出命令\r\nauthCommands\r\n .command('logout')\r\n .description('Logout and clear saved tokens')\r\n .action(async () => {\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n setCurrentEnvironment(env as Environment);\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const accessToken = await getAccessToken();\r\n const ystAccessToken = await getYstAccessToken();\r\n\r\n if (accessToken) {\r\n await logout(accessToken, ystAccessToken ?? undefined);\r\n }\r\n\r\n console.log('');\r\n console.log(chalk.green(`[OK] Logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\r\n console.log('');\r\n } catch {\r\n console.log('');\r\n console.log(chalk.yellow(`○ Already logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\r\n console.log('');\r\n }\r\n });\r\n\r\n// 刷新 token 命令\r\nauthCommands\r\n .command('refresh')\r\n .description('Manually refresh access token')\r\n .action(async () => {\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const accessToken = await getAccessToken();\r\n\r\n if (!accessToken) {\r\n console.log('');\r\n console.log(chalk.yellow('[ERROR] Not authenticated'));\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log('');\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n return; // 不使用 process.exit,让程序自然退出\r\n }\r\n\r\n const spinner = ora('Refreshing access token...').start();\r\n\r\n try {\r\n const client = getClient();\r\n await client.refreshToken();\r\n\r\n spinner.succeed('Token refreshed successfully!');\r\n\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim('New tokens saved securely'));\r\n console.log('');\r\n } catch (error) {\r\n spinner.fail('Token refresh failed');\r\n throw error;\r\n }\r\n } catch (error) {\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // Handle other errors\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Your session may have expired. Please run:`));\r\n console.log(chalk.dim(` wukong-cli auth login`));\r\n console.log('');\r\n // 不使用 process.exit,让程序自然退出\r\n }\r\n });\r\n\r\n// 状态命令\r\nauthCommands\r\n .command('status')\r\n .description('Show authentication status')\r\n .action(async () => {\r\n console.log('');\r\n\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n setCurrentEnvironment(env as Environment);\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const accessToken = await getAccessToken();\r\n\r\n if (!accessToken) {\r\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // 尝试获取用户信息来验证 token 是否真的有效\r\n try {\r\n const client = getClient();\r\n const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;\r\n const userInfo = await client.get(userInfoUrl);\r\n\r\n // 只有 API 调用成功才显示已认证\r\n console.log(chalk.green('[OK] Authenticated'));\r\n console.log('');\r\n\r\n const displayUser = userInfo.firstName\r\n ? `${userInfo.firstName} (${userInfo.username})`\r\n : userInfo.username || 'N/A';\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim('User:'), chalk.cyan(displayUser));\r\n console.log(chalk.dim('Email:'), chalk.cyan(userInfo.email || 'N/A'));\r\n console.log(chalk.dim('OrgCode:'), chalk.cyan(userInfo.ouCode || 'N/A'));\r\n console.log(chalk.dim('OrgName:'), chalk.cyan(userInfo.ouName || 'N/A'));\r\n console.log('');\r\n } catch (error: any) {\r\n const errorMsg = error instanceof Error ? error.message : String(error);\r\n\r\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\r\n console.log('');\r\n\r\n console.log(chalk.red('Error:'), chalk.dim(errorMsg));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n }\r\n } catch (error) {\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // Handle other errors\r\n console.log(chalk.yellow(`✗ Not authenticated`));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n }\r\n });\r\n\r\n// Token 信息命令\r\nauthCommands\r\n .command('token')\r\n .description('Display current token structure and JWT payload claims')\r\n .action(async () => {\r\n console.log('');\r\n\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n setCurrentEnvironment(env as Environment);\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const accessToken = await getAccessToken();\r\n const refreshToken = await getRefreshToken();\r\n\r\n if (!accessToken) {\r\n console.log(chalk.yellow('[ERROR] Not authenticated'));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim('Run: wukong-cli auth login'));\r\n console.log('');\r\n return;\r\n }\r\n\r\n function decodeJwt(token: string): { header: Record<string, unknown>; payload: Record<string, unknown> } | null {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) return null;\r\n const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString('utf-8'));\r\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));\r\n return { header, payload };\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n console.log(chalk.bgGreen.black.bold(' Token Information '));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log('');\r\n\r\n const decoded = decodeJwt(accessToken);\r\n\r\n if (!decoded) {\r\n console.log(chalk.yellow('[WARNING] Access token is not a valid JWT'));\r\n console.log('');\r\n console.log(chalk.dim('Access Token (raw):'), chalk.cyan(accessToken.substring(0, 40) + '...'));\r\n if (refreshToken) {\r\n console.log(chalk.dim('Refresh Token:'), chalk.cyan(refreshToken.substring(0, 20) + '...' + refreshToken.slice(-4)));\r\n }\r\n console.log('');\r\n return;\r\n }\r\n\r\n console.log(chalk.bold('JWT Header:'));\r\n console.log(chalk.dim(' alg:'), chalk.cyan(String(decoded.header.alg ?? 'N/A')));\r\n console.log(chalk.dim(' typ:'), chalk.cyan(String(decoded.header.typ ?? 'N/A')));\r\n console.log('');\r\n\r\n console.log(chalk.bold('JWT Payload:'));\r\n const skipKeys = new Set(['exp', 'iat', 'nbf', 'jti']);\r\n for (const [key, value] of Object.entries(decoded.payload)) {\r\n if (skipKeys.has(key)) continue;\r\n console.log(chalk.dim(` ${key}:`), chalk.cyan(String(value)));\r\n }\r\n console.log('');\r\n\r\n const now = Date.now();\r\n const exp = typeof decoded.payload.exp === 'number' ? decoded.payload.exp * 1000 : null;\r\n const iat = typeof decoded.payload.iat === 'number' ? decoded.payload.iat * 1000 : null;\r\n\r\n console.log(chalk.bold('Expiration:'));\r\n if (exp) {\r\n const expDate = new Date(exp);\r\n const diffMs = exp - now;\r\n\r\n if (diffMs <= 0) {\r\n console.log(chalk.dim(' Status:'), chalk.red('EXPIRED'));\r\n console.log(chalk.dim(' Expired at:'), chalk.red(expDate.toLocaleString()));\r\n } else if (diffMs < 5 * 60 * 1000) {\r\n console.log(chalk.dim(' Status:'), chalk.yellow('Expiring soon'));\r\n console.log(chalk.dim(' Expires at:'), chalk.yellow(expDate.toLocaleString()));\r\n console.log(chalk.dim(' Remaining:'), chalk.yellow(`${Math.floor(diffMs / 60000)} minutes`));\r\n } else {\r\n console.log(chalk.dim(' Status:'), chalk.green('Valid'));\r\n console.log(chalk.dim(' Expires at:'), chalk.green(expDate.toLocaleString()));\r\n console.log(chalk.dim(' Remaining:'), chalk.green(`${Math.floor(diffMs / 60000)} minutes`));\r\n }\r\n } else {\r\n console.log(chalk.dim(' exp:'), chalk.yellow('N/A'));\r\n }\r\n\r\n if (iat) {\r\n console.log(chalk.dim(' Issued at:'), chalk.cyan(new Date(iat).toLocaleString()));\r\n }\r\n console.log('');\r\n\r\n if (refreshToken) {\r\n console.log(chalk.bold('Refresh Token:'));\r\n console.log(chalk.dim(' Token:'), chalk.cyan(refreshToken.substring(0, 20) + '...' + refreshToken.slice(-4)));\r\n console.log(chalk.dim(' Length:'), chalk.cyan(`${refreshToken.length} characters`));\r\n console.log('');\r\n } else {\r\n console.log(chalk.dim('Refresh Token:'), chalk.yellow('Not available'));\r\n console.log('');\r\n }\r\n\r\n // YST Token 信息\r\n const ystAccessToken = await getYstAccessToken();\r\n const ystRefreshToken = await getYstRefreshToken();\r\n\r\n if (ystAccessToken || ystRefreshToken) {\r\n console.log(chalk.bold('YST Token (NRP):'));\r\n if (ystAccessToken) {\r\n console.log(chalk.dim(' Access Token:'), chalk.cyan(ystAccessToken.substring(0, 20) + '...' + ystAccessToken.slice(-4)));\r\n console.log(chalk.dim(' Length:'), chalk.cyan(`${ystAccessToken.length} characters`));\r\n\r\n const ystDecoded = decodeJwt(ystAccessToken);\r\n if (ystDecoded) {\r\n const ystExp = typeof ystDecoded.payload.exp === 'number' ? ystDecoded.payload.exp * 1000 : null;\r\n if (ystExp) {\r\n const ystDiffMs = ystExp - now;\r\n if (ystDiffMs <= 0) {\r\n console.log(chalk.dim(' JWT Status:'), chalk.red('EXPIRED'));\r\n console.log(chalk.dim(' Expires at:'), chalk.red(new Date(ystExp).toLocaleString()));\r\n } else if (ystDiffMs < 5 * 60 * 1000) {\r\n console.log(chalk.dim(' JWT Status:'), chalk.yellow('Expiring soon'));\r\n console.log(chalk.dim(' Expires at:'), chalk.yellow(new Date(ystExp).toLocaleString()));\r\n } else {\r\n console.log(chalk.dim(' JWT Status:'), chalk.green('Valid'));\r\n console.log(chalk.dim(' Expires at:'), chalk.green(new Date(ystExp).toLocaleString()));\r\n console.log(chalk.dim(' Remaining:'), chalk.green(`${Math.floor(ystDiffMs / 60000)} minutes`));\r\n }\r\n }\r\n }\r\n\r\n // 服务端校验 yst token\r\n console.log(chalk.dim(' Server:'));\r\n try {\r\n const ystVerifyUrl = `${config.API_BASE_URL}/yst-system/sys/users/current`;\r\n const ystResponse = await fetch(ystVerifyUrl, {\r\n headers: { 'Authorization': `Bearer ${ystAccessToken}` },\r\n });\r\n if (ystResponse.ok) {\r\n console.log(chalk.dim(' Status:'), chalk.green('Valid (server verified)'));\r\n } else {\r\n const ystErrText = await ystResponse.text().catch(() => '');\r\n console.log(chalk.dim(' Status:'), chalk.red(`Invalid (HTTP ${ystResponse.status})`));\r\n if (ystErrText) {\r\n console.log(chalk.dim(' Error:'), chalk.red(ystErrText.substring(0, 100)));\r\n }\r\n }\r\n } catch (ystVerifyError) {\r\n console.log(chalk.dim(' Status:'), chalk.yellow('Unable to verify (network error)'));\r\n }\r\n } else {\r\n console.log(chalk.dim(' Access Token:'), chalk.yellow('Not available'));\r\n }\r\n if (ystRefreshToken) {\r\n console.log(chalk.dim(' Refresh Token:'), chalk.cyan(ystRefreshToken.substring(0, 20) + '...' + ystRefreshToken.slice(-4)));\r\n console.log(chalk.dim(' Refresh Length:'), chalk.cyan(`${ystRefreshToken.length} characters`));\r\n } else {\r\n console.log(chalk.dim(' Refresh Token:'), chalk.yellow('Not available'));\r\n }\r\n console.log('');\r\n }\r\n\r\n } catch (error) {\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red('[ERROR] Configuration Error'));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n console.log('');\r\n }\r\n });\r\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","/**\r\n * Token Manager - Token 存储和刷新管理\r\n * 从 oceanet.ts 提取的 token 管理逻辑\r\n */\r\n\r\nimport ora from 'ora';\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\r\nimport type { TokenPair } from '../../types/auth.js';\r\nimport type { ICredentialStore } from '../../providers/credential-store.js';\r\nimport type { ITokenCache } from './token-cache.js';\r\n\r\nexport interface SaveTokenOptions {\r\n accessToken: string;\r\n refreshToken: string;\r\n ystAccessToken?: string;\r\n ystRefreshToken?: string;\r\n}\r\n\r\n/**\r\n * Token Manager 类\r\n * 负责与底层凭据存储和 token 缓存的交互\r\n */\r\nexport class TokenManager {\r\n constructor(\r\n private credentialStore: ICredentialStore,\r\n private tokenCache: ITokenCache\r\n ) {}\r\n\r\n async saveToken(options: SaveTokenOptions): Promise<void> {\r\n const config = getOceanetConfig();\r\n const { accessToken, refreshToken, ystAccessToken, ystRefreshToken } = options;\r\n\r\n await Promise.all([\r\n this.credentialStore.setPassword(config.SERVICE_NAME, 'access_token', accessToken),\r\n this.credentialStore.setPassword(config.SERVICE_NAME, 'refresh_token', refreshToken),\r\n ...(ystAccessToken ? [this.credentialStore.setPassword(config.SERVICE_NAME, 'yst_access_token', ystAccessToken)] : []),\r\n ...(ystRefreshToken ? [this.credentialStore.setPassword(config.SERVICE_NAME, 'yst_refresh_token', ystRefreshToken)] : []),\r\n ]);\r\n\r\n this.tokenCache.setTokens(accessToken, refreshToken, ystAccessToken ?? null, ystRefreshToken ?? null);\r\n }\r\n\r\n async getAccessToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getAccessToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(token, null);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async getRefreshToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getRefreshToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(null, token);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async getYstAccessToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getYstAccessToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_access_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(null, null, token, null);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async getYstRefreshToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getYstRefreshToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_refresh_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(null, null, null, token);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async refreshAccessToken(\r\n refreshToken: string\r\n ): Promise<TokenPair> {\r\n const spinner = ora('Refreshing access token...').start();\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n const requestBody = { param: refreshToken };\r\n\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n const data = await response.json();\r\n\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n if (data.code !== 200) {\r\n spinner.fail('Token refresh failed');\r\n throw new Error(data.message || 'Refresh token failed');\r\n }\r\n\r\n const {\r\n access_token,\r\n refresh_token: new_refresh_token,\r\n expires_in,\r\n token_type,\r\n scope,\r\n yst_access_token,\r\n yst_refresh_token: yst_new_refresh_token,\r\n } = data.result;\r\n\r\n spinner.succeed('Token refreshed');\r\n\r\n return {\r\n accessToken: access_token,\r\n refreshToken: new_refresh_token,\r\n expiresIn: expires_in,\r\n tokenType: token_type,\r\n scope: Array.isArray(scope) ? scope : [scope || ''],\r\n ...(yst_access_token ? { ystAccessToken: yst_access_token } : {}),\r\n ...(yst_new_refresh_token ? { ystRefreshToken: yst_new_refresh_token } : {}),\r\n };\r\n } catch (error) {\r\n spinner.fail('Token refresh error');\r\n throw error;\r\n }\r\n }\r\n\r\n async refreshYstAccessToken(\r\n ystRefreshToken: string\r\n ): Promise<{ ystAccessToken: string; ystRefreshToken: string }> {\r\n const spinner = ora('Refreshing YST access token...').start();\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN_NRP}`;\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n const requestBody = { param: ystRefreshToken };\r\n\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n const data = await response.json();\r\n\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n if (data.code !== 200) {\r\n spinner.fail('YST token refresh failed');\r\n throw new Error(data.message || 'YST refresh token failed');\r\n }\r\n\r\n const { access_token, refresh_token } = data.result;\r\n\r\n spinner.succeed('YST token refreshed');\r\n\r\n return {\r\n ystAccessToken: access_token,\r\n ystRefreshToken: refresh_token,\r\n };\r\n } catch (error) {\r\n spinner.fail('YST token refresh error');\r\n throw error;\r\n }\r\n }\r\n\r\n async clearTokens(): Promise<void> {\r\n const config = getOceanetConfig();\r\n await Promise.all([\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'access_token'),\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'refresh_token'),\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'yst_access_token'),\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n\r\n this.tokenCache.clear();\r\n }\r\n\r\n async logout(accessToken: string, ocAccessToken?: string): Promise<void> {\r\n try {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`;\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n const requestBody: Record<string, string> = {\r\n access_token: accessToken,\r\n };\r\n if (ocAccessToken) {\r\n requestBody.oc_access_token = ocAccessToken;\r\n }\r\n\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n\r\n let data;\r\n try {\r\n data = await response.json();\r\n } catch {\r\n // 响应可能为空\r\n }\r\n\r\n debugResponse(response.status, response.statusText, data || 'No response body', duration);\r\n } catch (error) {\r\n // 忽略退出登录错误\r\n }\r\n\r\n await this.clearTokens();\r\n }\r\n\r\n async initTokenCache(): Promise<void> {\r\n const config = getOceanetConfig();\r\n\r\n const [accessToken, refreshToken, ystAccessToken, ystRefreshToken] = await Promise.all([\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token'),\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token'),\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_access_token'),\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n\r\n if (accessToken || refreshToken || ystAccessToken || ystRefreshToken) {\r\n this.tokenCache.setTokens(\r\n accessToken || null,\r\n refreshToken || null,\r\n ystAccessToken || null,\r\n ystRefreshToken || null\r\n );\r\n }\r\n }\r\n}\r\n\r\n// ============ 便利函数(向后兼容) ============\r\n\r\nlet tokenManagerInstance: TokenManager | null = null;\r\n\r\nexport function getTokenManager(): TokenManager {\r\n if (!tokenManagerInstance) {\r\n const { getCredentialStore } = require('../../providers/credential-store.js');\r\n const { getGlobalTokenCache } = require('./token-cache.js');\r\n\r\n const credentialStore = getCredentialStore();\r\n const tokenCache = getGlobalTokenCache();\r\n\r\n tokenManagerInstance = new TokenManager(credentialStore, tokenCache);\r\n }\r\n return tokenManagerInstance;\r\n}\r\n\r\nexport function resetTokenManager(): void {\r\n tokenManagerInstance = null;\r\n}\r\n\r\n/**\r\n * 保存 Token(便利函数,向后兼容)\r\n * 支持两种调用方式:\r\n * saveToken(accessToken, refreshToken)\r\n * saveToken({ accessToken, refreshToken, ystAccessToken?, ystRefreshToken? })\r\n */\r\nexport async function saveToken(\r\n accessTokenOrOptions: string | SaveTokenOptions,\r\n refreshToken?: string\r\n): Promise<void> {\r\n const manager = getTokenManager();\r\n\r\n const options: SaveTokenOptions = typeof accessTokenOrOptions === 'string'\r\n ? { accessToken: accessTokenOrOptions, refreshToken: refreshToken! }\r\n : accessTokenOrOptions;\r\n\r\n await manager.saveToken(options);\r\n}\r\n\r\nexport async function getAccessToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getAccessToken();\r\n}\r\n\r\nexport async function getRefreshToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getRefreshToken();\r\n}\r\n\r\nexport async function getYstAccessToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getYstAccessToken();\r\n}\r\n\r\nexport async function getYstRefreshToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getYstRefreshToken();\r\n}\r\n\r\nexport async function refreshAccessToken(\r\n refreshToken: string\r\n): Promise<TokenPair> {\r\n const manager = getTokenManager();\r\n return await manager.refreshAccessToken(refreshToken);\r\n}\r\n\r\nexport async function refreshYstAccessToken(\r\n ystRefreshToken: string\r\n): Promise<{ ystAccessToken: string; ystRefreshToken: string }> {\r\n const manager = getTokenManager();\r\n return await manager.refreshYstAccessToken(ystRefreshToken);\r\n}\r\n\r\nexport async function clearTokens(): Promise<void> {\r\n const manager = getTokenManager();\r\n await manager.clearTokens();\r\n}\r\n\r\nexport async function logout(accessToken: string, ocAccessToken?: string): Promise<void> {\r\n const manager = getTokenManager();\r\n await manager.logout(accessToken, ocAccessToken);\r\n}\r\n\r\nexport async function initTokenCache(): Promise<void> {\r\n const manager = getTokenManager();\r\n await manager.initTokenCache();\r\n}\r\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(\n endpoint: string,\n options: {\n baseUrl?: string;\n params?: Record<string, string>;\n } = {}\n): string {\n const { baseUrl, params } = options;\n\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 const base = baseUrl || config.API_BASE_URL;\n let url = `${base}${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 * 支持运行时 baseUrl 覆盖(用于多域名支持)\n */\n async request<T = any>(\n endpoint: string,\n options: RequestOptions & { baseUrl?: string } = {}\n ): Promise<T> {\n const {\n method = 'GET',\n headers = {},\n body,\n params,\n baseUrl,\n } = options;\n\n const url = buildUrl(endpoint, { baseUrl, 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","/**\r\n * 认证 HTTP 客户端 - 添加认证和自动刷新功能\r\n * 装饰器模式,为基础 HTTP 客户端添加认证能力\r\n */\r\n\r\nimport type { IHttpClient } from './http-client-interface.js';\r\nimport type { ITokenCache } from '../auth/token-cache.js';\r\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\r\nimport { getApiErrorHandler, ApiError } from './api-error-handler.js';\r\nimport { getRetoken } from './interceptors.js';\r\nimport { getTokenManager } from '../auth/token-manager.js';\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\n\r\n/**\r\n * 认证 HTTP 客户端\r\n * 为基础 HTTP 客户端添加:\r\n * 1. 自动添加 Authorization 头\r\n * 2. 401 自动刷新 token 并重试\r\n * 3. 业务错误处理\r\n */\r\nexport class AuthenticatingHttpClient implements IHttpClient {\r\n private initialized = false;\r\n\r\n constructor(\r\n private baseClient: IHttpClient,\r\n private tokenCache: ITokenCache\r\n ) {}\r\n\r\n /**\r\n * 确保 token 缓存已初始化\r\n */\r\n private async ensureInitialized(): Promise<void> {\r\n if (!this.initialized) {\r\n const tokenManager = getTokenManager();\r\n await tokenManager.initTokenCache();\r\n this.initialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * 解析 JWT exp 字段(用于诊断)\r\n */\r\n private parseJwtExp(token: string): number | null {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) return null;\r\n const payload = JSON.parse(\r\n Buffer.from(parts[1], 'base64url').toString('utf-8')\r\n );\r\n return typeof payload.exp === 'number' ? payload.exp * 1000 : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * 刷新 token,并确保当前客户端使用的缓存已同步到新 token。\r\n * ts-retoken@0.2.0 不会等待 async setTokens,因此这里显式同步并持久化。\r\n */\r\n private async refreshTokenAndPersist(retoken = getRetoken()): Promise<void> {\r\n const tokens = await retoken.refreshToken();\r\n\r\n if (tokens?.accessToken && tokens?.refreshToken) {\r\n this.tokenCache.setTokens(\r\n tokens.accessToken,\r\n tokens.refreshToken,\r\n tokens.ystAccessToken ?? null,\r\n tokens.ystRefreshToken ?? null\r\n );\r\n\r\n const tokenManager = getTokenManager();\r\n await tokenManager.saveToken({\r\n accessToken: tokens.accessToken,\r\n refreshToken: tokens.refreshToken,\r\n ystAccessToken: tokens.ystAccessToken,\r\n ystRefreshToken: tokens.ystRefreshToken,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * 发起认证的 HTTP 请求\r\n * 实现方案:手动预刷新 + 401 重试\r\n */\r\n async request<T = any>(\r\n endpoint: string,\r\n options: any = {}\r\n ): Promise<T> {\r\n await this.ensureInitialized();\r\n\r\n const retoken = getRetoken();\r\n const config = getOceanetConfig();\r\n const debug = config.DEBUG || (global as any).__debugMode;\r\n\r\n // === 诊断点 1: 检查 token 状态 ===\r\n if (debug) {\r\n const accessToken = this.tokenCache.getAccessToken();\r\n if (accessToken) {\r\n const exp = this.parseJwtExp(accessToken);\r\n console.log('');\r\n console.log('=== [DIAGNOSTIC] Token State Before Request ===');\r\n console.log(' Token exists:', !!accessToken);\r\n console.log(' Token length:', accessToken?.length || 0);\r\n console.log(' JWT exp:', exp ? new Date(exp).toISOString() : 'null');\r\n if (exp) {\r\n const timeUntilExpiry = exp - Date.now();\r\n console.log(' Seconds until expiry:', Math.floor(timeUntilExpiry / 1000));\r\n }\r\n console.log('');\r\n }\r\n }\r\n\r\n // === 诊断点 2: 检查 isTokenExpiringSoon ===\r\n const isExpiringSoon = await retoken.isTokenExpiringSoon();\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] isTokenExpiringSoon() ===');\r\n console.log(' Result:', isExpiringSoon);\r\n console.log('');\r\n }\r\n\r\n // ✅ 主动检查 token 是否即将过期(利用 ts-retoken 的能力)\r\n if (isExpiringSoon) {\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] Proactive Refresh Triggered ===');\r\n }\r\n // 尝试主动刷新,如果失败则继续使用旧 token(让被动刷新处理)\r\n try {\r\n const refreshStart = Date.now();\r\n await this.refreshTokenAndPersist(retoken);\r\n const refreshTime = Date.now() - refreshStart;\r\n if (debug) {\r\n console.log(' Proactive refresh SUCCESS (took ' + refreshTime + 'ms)');\r\n console.log('');\r\n }\r\n } catch (refreshError: any) {\r\n // ✅ 改为 console.log 确保能看到\r\n console.log('');\r\n console.log('=== [DIAGNOSTIC] Proactive Refresh Failed ===');\r\n console.log(' Error:', refreshError?.message || String(refreshError));\r\n console.log(' Error code:', (refreshError as any)?.code);\r\n console.log(' Will retry with reactive refresh if 9913 occurs');\r\n console.log('');\r\n }\r\n }\r\n\r\n // 第一次尝试\r\n try {\r\n return await this.tryRequest<T>(endpoint, options);\r\n } catch (error) {\r\n // === 诊断点 3: 检查错误类型 ===\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] First Request Failed ===');\r\n console.log(' Error:', error instanceof ApiError ? `ApiError(code=${error.code})` : String(error));\r\n console.log('');\r\n }\r\n\r\n // ✅ 检查是否是 9913 错误(token 过期)\r\n if (error instanceof ApiError && error.code === 9913) {\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] Reactive Refresh Triggered (9913) ===');\r\n }\r\n await this.refreshTokenAndPersist(retoken);\r\n // ✅ 重试\r\n return await this.tryRequest<T>(endpoint, options);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 执行单次请求(辅助方法)\r\n * 委托给 BaseHttpClient,遵守装饰器模式\r\n */\r\n private async tryRequest<T>(\r\n endpoint: string,\r\n options: any = {}\r\n ): Promise<T> {\r\n const accessToken = this.tokenCache.getAccessToken();\r\n if (!accessToken) {\r\n throw new Error(\r\n 'Not authenticated. Please run: wukong-cli auth login'\r\n );\r\n }\r\n\r\n // ✅ 委托给 BaseHttpClient(遵守约定)\r\n const data = await this.baseClient.request<OceanetApiResponse<T>>(\r\n endpoint,\r\n {\r\n ...options,\r\n headers: {\r\n ...options.headers,\r\n 'Authorization': `Bearer ${accessToken}`,\r\n },\r\n }\r\n );\r\n\r\n // ✅ 检查业务错误码 9913\r\n if (data.code === 9913) {\r\n throw new ApiError(data.code, data.message || 'Token expired', true);\r\n }\r\n\r\n // ✅ 处理其他业务错误\r\n const errorHandler = getApiErrorHandler();\r\n errorHandler.handle(data);\r\n\r\n return data.result;\r\n }\r\n\r\n /**\r\n * GET 请求\r\n */\r\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'GET', params });\r\n }\r\n\r\n /**\r\n * POST 请求\r\n */\r\n async post<T = any>(\r\n endpoint: string,\r\n data?: any,\r\n headers?: Record<string, string>\r\n ): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'POST',\r\n body: data,\r\n headers,\r\n });\r\n }\r\n\r\n /**\r\n * PUT 请求\r\n */\r\n async put<T = any>(\r\n endpoint: string,\r\n data?: any,\r\n headers?: Record<string, string>\r\n ): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PUT',\r\n body: data,\r\n headers,\r\n });\r\n }\r\n\r\n /**\r\n * DELETE 请求\r\n */\r\n async delete<T = any>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'DELETE' });\r\n }\r\n\r\n /**\r\n * PATCH 请求\r\n */\r\n async patch<T = any>(\r\n endpoint: string,\r\n data?: any,\r\n headers?: Record<string, string>\r\n ): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PATCH',\r\n body: data,\r\n headers,\r\n });\r\n }\r\n\r\n /**\r\n * 检查 token 是否即将过期\r\n */\r\n async isTokenExpiringSoon(): Promise<boolean> {\r\n await this.ensureInitialized();\r\n const retoken = getRetoken();\r\n return retoken.isTokenExpiringSoon();\r\n }\r\n\r\n /**\r\n * 手动刷新 token\r\n */\r\n async refreshToken(): Promise<void> {\r\n await this.ensureInitialized();\r\n await this.refreshTokenAndPersist();\r\n }\r\n}\r\n","/**\r\n * API 错误处理器 - 处理 Oceanet API 特定错误\r\n */\r\n\r\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\r\nimport chalk from 'chalk';\r\n\r\n/**\r\n * API 错误类\r\n */\r\nexport class ApiError extends Error {\r\n constructor(\r\n public code: number,\r\n message: string,\r\n public retryable: boolean = false\r\n ) {\r\n super(message);\r\n this.name = 'ApiError';\r\n }\r\n}\r\n\r\n/**\r\n * 错误处理函数类型\r\n */\r\ntype ErrorHandler = (response: OceanetApiResponse) => void | never;\r\n\r\n/**\r\n * API 错误处理器\r\n * 负责处理 Oceanet API 的业务错误码\r\n */\r\nexport class ApiErrorHandler {\r\n private errorHandlers: Map<number, ErrorHandler> = new Map();\r\n\r\n constructor() {\r\n // 注册默认错误处理器\r\n this.registerDefaultHandlers();\r\n }\r\n\r\n /**\r\n * 注册默认的 Oceanet 错误处理器\r\n */\r\n private registerDefaultHandlers(): void {\r\n // 9913 = token 不存在或已失效\r\n this.register(9913, (response) => {\r\n const error = new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Token expired or invalid',\r\n true // 可重试\r\n );\r\n throw error;\r\n });\r\n\r\n // 9909 = 没有访问权限\r\n this.register(9909, (response) => {\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Access denied',\r\n false\r\n );\r\n });\r\n\r\n // 9914 = refresh_token 过期,需重新登录\r\n this.register(9914, (response) => {\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Session expired, please login again',\r\n false\r\n );\r\n });\r\n\r\n // 其他认证错误\r\n [401, 403].forEach(code => {\r\n this.register(code, (response) => {\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Authentication failed',\r\n code === 401 // 401 可以尝试刷新 token\r\n );\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * 注册错误处理器\r\n * @param code 错误码\r\n * @param handler 处理函数\r\n */\r\n register(code: number, handler: ErrorHandler): void {\r\n this.errorHandlers.set(code, handler);\r\n }\r\n\r\n /**\r\n * 处理 API 响应\r\n * @param response API 响应\r\n * @throws {ApiError} 当响应包含错误时\r\n */\r\n handle(response: OceanetApiResponse): void {\r\n if (response.code !== 200) {\r\n const handler = this.errorHandlers.get(response.code);\r\n\r\n if (handler) {\r\n handler(response);\r\n }\r\n\r\n // 没有特定处理器,使用默认处理(优先级:msg > errorMsg > message)\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Unknown API error'\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * 检查响应是否为错误\r\n * @param response API 响应\r\n * @returns 是否为错误\r\n */\r\n isError(response: OceanetApiResponse): boolean {\r\n return response.code !== 200;\r\n }\r\n\r\n /**\r\n * 尝试从错误中恢复\r\n * @param error 错误对象\r\n * @param recoverFunction 恢复函数\r\n * @returns 恢复结果或抛出错误\r\n */\r\n async tryRecover<T>(\r\n error: unknown,\r\n recoverFunction: () => Promise<T>\r\n ): Promise<T> {\r\n if (error instanceof ApiError && error.retryable) {\r\n console.log('');\r\n console.log(chalk.yellow('⚠ Token expired, attempting refresh...'));\r\n try {\r\n return await recoverFunction();\r\n } catch (refreshError: any) {\r\n console.log('');\r\n console.log(chalk.yellow('⚠ Auto-refresh failed:'), chalk.dim(refreshError.message));\r\n throw new ApiError(\r\n error.code,\r\n `${error.message} (Auto-refresh failed)`\r\n );\r\n }\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * 获取全局错误处理器实例\r\n */\r\nlet errorHandlerInstance: ApiErrorHandler | null = null;\r\n\r\nexport function getApiErrorHandler(): ApiErrorHandler {\r\n if (!errorHandlerInstance) {\r\n errorHandlerInstance = new ApiErrorHandler();\r\n }\r\n return errorHandlerInstance;\r\n}\r\n","/**\r\n * HTTP 拦截器 - Token 刷新和 401 重试逻辑\r\n * 使用 ts-retoken 实现\r\n */\r\n\r\nimport { createRetoken } from 'ts-retoken';\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\nimport type { Tokens } from '../../types/oceanet.js';\r\nimport type { ICredentialStore } from '../../providers/credential-store.js';\r\nimport type { ITokenCache } from '../auth/token-cache.js';\r\n\r\nfunction createFetchWithTimeout(timeoutMs: number) {\r\n return async (url: string, options: any = {}) => {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: controller.signal,\r\n });\r\n clearTimeout(timeoutId);\r\n return response;\r\n } catch (error: unknown) {\r\n clearTimeout(timeoutId);\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n throw new Error(`Request timeout after ${timeoutMs}ms`);\r\n }\r\n throw error;\r\n }\r\n };\r\n}\r\n\r\nexport function createRetokenInstance(\r\n credentialStore?: ICredentialStore,\r\n tokenCache?: ITokenCache\r\n) {\r\n const config = getOceanetConfig();\r\n\r\n const store = credentialStore || (require('../../providers/credential-store.js').getCredentialStore());\r\n const cache = tokenCache || (require('../auth/token-cache.js').getGlobalTokenCache());\r\n\r\n return createRetoken({\r\n refreshEndpoint: {\r\n url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,\r\n method: 'POST',\r\n buildBody: (token) => JSON.stringify({ param: token }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n parseResponse: (data: any) => {\r\n if (config.DEBUG || (global as any).__debugMode) {\r\n console.log('');\r\n console.log('=== HTTP Request ===');\r\n console.log(`POST ${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`);\r\n console.log('Headers:');\r\n console.log(' Content-Type: application/json');\r\n console.log('Body:');\r\n const refreshToken = cache.getRefreshToken();\r\n const truncated = refreshToken && refreshToken.length > 50\r\n ? refreshToken.substring(0, 50) + '...'\r\n : refreshToken || '(none)';\r\n console.log(` {\"param\":\"${truncated}\"}`);\r\n console.log('');\r\n console.log('=== HTTP Response ===');\r\n console.log(JSON.stringify(data, null, 2));\r\n console.log('');\r\n }\r\n\r\n if (data.code === 401 || data.code === 403) {\r\n const error: any = new Error(data.message || 'Refresh token expired or invalid');\r\n error.code = data.code;\r\n error.isAuthFailure = true;\r\n throw error;\r\n }\r\n\r\n const result = data.result || data;\r\n\r\n if (!result.access_token && !result.accessToken) {\r\n throw new Error('Invalid token response: missing access_token field');\r\n }\r\n if (!result.refresh_token && !result.refreshToken) {\r\n throw new Error('Invalid token response: missing refresh_token field');\r\n }\r\n\r\n return {\r\n accessToken: result.access_token || result.accessToken,\r\n refreshToken: result.refresh_token || result.refreshToken,\r\n ...(result.yst_access_token ? { ystAccessToken: result.yst_access_token } : {}),\r\n ...(result.yst_refresh_token ? { ystRefreshToken: result.yst_refresh_token } : {}),\r\n };\r\n },\r\n },\r\n getAccessToken: () => {\r\n return cache.getAccessToken();\r\n },\r\n getRefreshToken: () => {\r\n return cache.getRefreshToken();\r\n },\r\n setTokens: (tokens: Tokens) => {\r\n const accessToken = tokens?.accessToken;\r\n const refreshToken = tokens?.refreshToken;\r\n\r\n if (!accessToken || !refreshToken) {\r\n throw new Error('Invalid tokens: missing access_token or refresh_token');\r\n }\r\n\r\n const cfg = getOceanetConfig();\r\n\r\n cache.setTokens(\r\n accessToken,\r\n refreshToken,\r\n tokens?.ystAccessToken ?? null,\r\n tokens?.ystRefreshToken ?? null\r\n );\r\n\r\n void Promise.all([\r\n store.setPassword(cfg.SERVICE_NAME, 'access_token', accessToken),\r\n store.setPassword(cfg.SERVICE_NAME, 'refresh_token', refreshToken),\r\n ...(tokens?.ystAccessToken ? [store.setPassword(cfg.SERVICE_NAME, 'yst_access_token', tokens.ystAccessToken)] : []),\r\n ...(tokens?.ystRefreshToken ? [store.setPassword(cfg.SERVICE_NAME, 'yst_refresh_token', tokens.ystRefreshToken)] : []),\r\n ]).catch((error) => {\r\n if (cfg.DEBUG || (global as any).__debugMode) {\r\n console.log('');\r\n console.log('=== Token Persist Failed ===');\r\n console.log(error?.message || String(error));\r\n console.log('');\r\n }\r\n });\r\n\r\n if (cfg.DEBUG || (global as any).__debugMode) {\r\n console.log('');\r\n console.log('=== Token Saved ===');\r\n console.log('Access token saved (length:', accessToken.length, ')');\r\n console.log('Refresh token saved (length:', refreshToken.length, ')');\r\n if (tokens?.ystAccessToken) {\r\n console.log('YST access token saved (length:', tokens.ystAccessToken.length, ')');\r\n }\r\n if (tokens?.ystRefreshToken) {\r\n console.log('YST refresh token saved (length:', tokens.ystRefreshToken.length, ')');\r\n }\r\n console.log('');\r\n }\r\n },\r\n clearTokens: async () => {\r\n const cfg = getOceanetConfig();\r\n await Promise.all([\r\n store.deletePassword(cfg.SERVICE_NAME, 'access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'refresh_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n cache.clear();\r\n },\r\n expirationLeeway: 60,\r\n retryStatuses: [401],\r\n onAuthFailure: async () => {\r\n const cfg = getOceanetConfig();\r\n try {\r\n await Promise.all([\r\n store.deletePassword(cfg.SERVICE_NAME, 'access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'refresh_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n cache.clear();\r\n } catch {\r\n // 忽略清除错误\r\n }\r\n },\r\n });\r\n}\r\n\r\nconst retokenInstances: Record<string, ReturnType<typeof createRetokenInstance>> = {};\r\n\r\nexport function getRetoken() {\r\n const config = getOceanetConfig();\r\n const env = config.ENVIRONMENT;\r\n\r\n if (!retokenInstances[env]) {\r\n retokenInstances[env] = createRetokenInstance();\r\n }\r\n\r\n return retokenInstances[env];\r\n}\r\n","/**\r\n * HTTP 测试命令\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport ora from 'ora';\r\nimport chalk from 'chalk';\r\nimport { getClient } from '../core/http/client.js';\r\nimport { getAccessToken, getYstAccessToken } from '../core/auth/token-manager.js';\r\nimport { OCEANET_CONFIG } from '../config/oceanet.js';\r\nimport { debugRequest } from '../utils/debug.js';\r\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\r\nimport { ApiError } from '../core/http/api-error-handler.js';\r\n\r\ninterface RequestOptions {\r\n baseUrl?: string;\r\n headers: string[];\r\n data?: string;\r\n params?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * 修复 Git Bash 路径转换问题\r\n */\r\nfunction fixGitBashPath(url: string): string {\r\n if (url.includes(':') && !url.startsWith('http')) {\r\n const oceanetIndex = url.indexOf('/oceanet-');\r\n if (oceanetIndex >= 0) {\r\n return url.substring(oceanetIndex);\r\n }\r\n }\r\n return url;\r\n}\r\n\r\n/**\r\n * 解析自定义头\r\n */\r\nfunction parseHeaders(headers: string[]): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n if (Array.isArray(headers)) {\r\n for (const h of headers) {\r\n const [key, ...valueParts] = h.split(':');\r\n if (key && valueParts.length > 0) {\r\n result[key.trim()] = valueParts.join(':').trim();\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * 构建完整 URL\r\n */\r\nfunction buildUrl(url: string, baseUrl?: string): string {\r\n const cleanUrl = fixGitBashPath(url);\r\n if (cleanUrl.startsWith('http')) {\r\n return cleanUrl;\r\n }\r\n const config = OCEANET_CONFIG();\r\n const base = baseUrl || config.API_BASE_URL;\r\n return `${base}${cleanUrl}`;\r\n}\r\n\r\n/**\r\n * 解析查询参数\r\n */\r\nfunction parseParams(params?: Record<string, string>): string {\r\n if (!params || Object.keys(params).length === 0) {\r\n return '';\r\n }\r\n const searchParams = new URLSearchParams();\r\n for (const [key, value] of Object.entries(params)) {\r\n searchParams.append(key, value);\r\n }\r\n return `?${searchParams.toString()}`;\r\n}\r\n\r\n/**\r\n * 执行 HTTP 请求(使用 AuthenticatingHttpClient)\r\n */\r\nasync function executeRequest(\r\n method: string,\r\n url: string,\r\n options: RequestOptions\r\n): Promise<void> {\r\n const spinner = ora('Sending request...').start();\r\n\r\n try {\r\n // 检查是否已认证\r\n const accessToken = await getAccessToken();\r\n if (!accessToken) {\r\n spinner.fail('Not authenticated');\r\n console.error(chalk.red('Please run: wukong-cli auth login'));\r\n process.exit(1);\r\n }\r\n\r\n // 构建完整 URL\r\n const fullUrl = buildUrl(url, options.baseUrl);\r\n\r\n // 解析自定义头\r\n const customHeaders = parseHeaders(options.headers);\r\n\r\n // 解析请求数据\r\n const requestData = options.data ? JSON.parse(options.data) : undefined;\r\n\r\n // 检测是否为 YST 接口(路径包含 /yst-)\r\n const isYstRequest = fullUrl.includes('/yst-');\r\n\r\n if (isYstRequest) {\r\n const ystAccessToken = await getYstAccessToken();\r\n if (!ystAccessToken) {\r\n spinner.fail('YST token not available');\r\n console.error(chalk.red('YST token not found. Please re-login: wukong-cli auth login'));\r\n process.exit(1);\r\n }\r\n\r\n spinner.text = `${method} ${chalk.cyan(fullUrl)} (using YST token)`;\r\n\r\n const startTime = Date.now();\r\n\r\n const fetchOptions: RequestInit = {\r\n method: method.toUpperCase(),\r\n headers: {\r\n 'Authorization': `Bearer ${ystAccessToken}`,\r\n 'Content-Type': 'application/json',\r\n ...customHeaders,\r\n },\r\n };\r\n\r\n if (requestData) {\r\n fetchOptions.body = JSON.stringify(requestData);\r\n }\r\n\r\n const response = await fetch(fullUrl + parseParams(options.params), fetchOptions);\r\n const duration = Date.now() - startTime;\r\n\r\n if (!response.ok) {\r\n const errText = await response.text().catch(() => '');\r\n spinner.fail(`Request failed (${response.status})`);\r\n console.error(chalk.red(`HTTP ${response.status}: ${errText.substring(0, 200)}`));\r\n process.exit(1);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n spinner.succeed('Response received');\r\n console.log('');\r\n console.log(chalk.dim('Status:'), `${response.status} ${response.statusText}`);\r\n console.log(chalk.dim('Token:'), 'YST');\r\n console.log(chalk.dim('Duration:'), `${duration}ms`);\r\n console.log('');\r\n console.log(chalk.dim('Response:'));\r\n console.log(JSON.stringify(data, null, 2));\r\n return;\r\n }\r\n\r\n // 使用 OceanetClient(自动处理token刷新)\r\n const client = getClient();\r\n\r\n spinner.text = `${method} ${chalk.cyan(fullUrl)}`;\r\n\r\n const startTime = Date.now();\r\n\r\n let data: any;\r\n\r\n // 根据方法调用相应的客户端方法\r\n switch (method.toUpperCase()) {\r\n case 'GET':\r\n const getUrl = fullUrl + parseParams(options.params);\r\n data = await client.get(getUrl);\r\n break;\r\n\r\n case 'POST':\r\n data = await client.post(fullUrl, requestData, customHeaders);\r\n break;\r\n\r\n case 'PUT':\r\n data = await client.put(fullUrl, requestData, customHeaders);\r\n break;\r\n\r\n case 'DELETE':\r\n data = await client.delete(fullUrl);\r\n break;\r\n\r\n case 'PATCH':\r\n data = await client.patch(fullUrl, requestData, customHeaders);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unsupported method: ${method}`);\r\n }\r\n\r\n const duration = Date.now() - startTime;\r\n\r\n spinner.succeed('Response received');\r\n\r\n // 显示响应\r\n console.log('');\r\n console.log(chalk.dim('Status:'), '200 OK');\r\n console.log('');\r\n console.log(chalk.dim('Response:'));\r\n console.log(JSON.stringify(data, null, 2));\r\n\r\n } catch (error) {\r\n spinner.fail('Request failed');\r\n\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n process.exit(1);\r\n }\r\n\r\n // Handle ApiError with code and message\r\n if (error instanceof ApiError) {\r\n console.log('');\r\n console.log(chalk.red(`API Error (code: ${error.code})`));\r\n console.log(chalk.red(error.message));\r\n console.log('');\r\n process.exit(1);\r\n }\r\n\r\n // Handle other errors\r\n if (error instanceof Error) {\r\n console.error(chalk.red(error.message));\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n\r\nexport const httpCommand = new Command('http');\r\n\r\nhttpCommand.description('HTTP commands for making API requests');\r\n\r\n// GET 请求\r\nhttpCommand\r\n .command('get <url>')\r\n .description('Send GET request (uses configured base URL or override with -b)')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('GET', url, options);\r\n });\r\n\r\n// POST 请求\r\nhttpCommand\r\n .command('post <url>')\r\n .description('Send POST request with JSON data')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .option('-d, --data <json>', 'Request body as JSON string')\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('POST', url, options);\r\n });\r\n\r\n// PUT 请求\r\nhttpCommand\r\n .command('put <url>')\r\n .description('Send PUT request with JSON data')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .option('-d, --data <json>', 'Request body as JSON string')\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('PUT', url, options);\r\n });\r\n\r\n// PATCH 请求\r\nhttpCommand\r\n .command('patch <url>')\r\n .description('Send PATCH request with JSON data')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .option('-d, --data <json>', 'Request body as JSON string')\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('PATCH', url, options);\r\n });\r\n\r\n// DELETE 请求\r\nhttpCommand\r\n .command('delete <url>')\r\n .description('Send DELETE request')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('DELETE', url, options);\r\n });\r\n","/**\n * Init Command\n * 重新生成配置文件\n */\n\nimport { Command } from 'commander';\nimport { writeFileSync, existsSync, readFileSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport chalk from 'chalk';\n\n// 配置文件目录\nconst CONFIG_DIR = join(homedir(), '.wukong-cli');\n// 配置文件路径\nconst CONFIG_FILE_PATH = join(CONFIG_DIR, 'wukong-cli.json');\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 * 确保配置目录存在\n */\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\n/**\n * 执行init命令\n */\nexport async function executeInit(): Promise<void> {\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 ensureConfigDir();\n\n // 读取模板文件\n const templateContent = readFileSync(templatePath, 'utf-8');\n\n // 检查是否覆盖现有文件\n const configExists = existsSync(CONFIG_FILE_PATH);\n if (configExists) {\n console.log(chalk.yellow('⚠️ Existing configuration file will be overwritten'));\n }\n\n // 写入配置文件\n writeFileSync(CONFIG_FILE_PATH, templateContent, 'utf-8');\n\n console.log(chalk.green('✅ Configuration file created successfully'));\n console.log(chalk.gray(`Location: ${CONFIG_FILE_PATH}`));\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/wukong-cli.json)')\n .action(async () => {\n await executeInit();\n });\n","/**\n * Update command - update wukong-cli through npm global install.\n */\n\nimport { Command } from 'commander';\nimport { NpmUpdater, type IUpdater } from '../core/update/npm-updater.js';\nimport {\n compareVersions,\n describeVersionComparison,\n NpmVersionProvider,\n type IVersionProvider,\n} from '../utils/version/index.js';\n\nconst MANUAL_UPDATE_COMMAND = 'npm install -g @zrhsh/wukong-cli@latest';\n\nexport interface CommandOutput {\n log(message: string): void;\n error(message: string): void;\n}\n\nexport interface RunUpdateCommandOptions {\n currentVersion: string;\n versionProvider: IVersionProvider;\n updater: IUpdater;\n output: CommandOutput;\n}\n\nexport async function runUpdateCommand({\n currentVersion,\n versionProvider,\n updater,\n output,\n}: RunUpdateCommandOptions): Promise<number> {\n const latestVersion = await versionProvider.getLatestVersion();\n\n if (!latestVersion) {\n output.error('Unable to fetch latest version from npm registry.');\n output.error(`Manual update: ${MANUAL_UPDATE_COMMAND}`);\n return 1;\n }\n\n output.log(`Current version: ${currentVersion}`);\n output.log(`Latest version: ${latestVersion}`);\n output.log(\n `Compare result: ${describeVersionComparison(currentVersion, latestVersion)}`\n );\n\n const comparison = compareVersions(currentVersion, latestVersion);\n\n if (comparison === 0) {\n output.log('Already up to date.');\n return 0;\n }\n\n if (comparison > 0) {\n output.log('Skip update.');\n return 0;\n }\n\n output.log('Updating with npm...');\n\n try {\n await updater.updateToLatest();\n output.log('✅ Update completed successfully!');\n output.log(`Updated from ${currentVersion} to ${latestVersion}`);\n output.log('Run: wukong-cli --version to verify.');\n return 0;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n output.error(`Update failed: ${message}`);\n output.error(`Manual update: ${MANUAL_UPDATE_COMMAND}`);\n return 1;\n }\n}\n\nexport const updateCommand = new Command('update')\n .description('Update wukong-cli to the latest npm version')\n .action(async () => {\n const exitCode = await runUpdateCommand({\n currentVersion: CLI_VERSION,\n versionProvider: new NpmVersionProvider(\n '@zrhsh/wukong-cli',\n 'https://registry.npmjs.org'\n ),\n updater: new NpmUpdater(),\n output: console,\n });\n\n if (exitCode !== 0) {\n process.exitCode = exitCode;\n }\n });\n","/**\n * NPM updater for globally installed wukong-cli.\n */\n\nimport { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { platform } from 'node:process';\n\nexport interface IUpdater {\n updateToLatest(): Promise<void>;\n}\n\nexport class UpdateExecutionError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number | null = null\n ) {\n super(message);\n this.name = 'UpdateExecutionError';\n }\n}\n\ntype SpawnFunction = typeof spawn;\n\nexport class NpmUpdater implements IUpdater {\n constructor(private readonly spawnFn: SpawnFunction = spawn) {}\n\n private getSpawnOptions() {\n // On Windows, npm is a batch file (npm.cmd), so we need shell: true\n // to properly execute it. This is safe for our controlled use case.\n return platform === 'win32'\n ? { shell: true, stdio: ['ignore', 'pipe', 'pipe'] as const }\n : { stdio: ['ignore', 'pipe', 'pipe'] as const };\n }\n\n updateToLatest(): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = this.spawnFn(\n 'npm',\n ['install', '-g', '@zrhsh/wukong-cli@latest'],\n this.getSpawnOptions()\n ) as ChildProcess;\n\n child.stdout?.pipe(process.stdout);\n child.stderr?.pipe(process.stderr);\n\n child.on('error', (error) => {\n reject(\n new UpdateExecutionError(\n `Failed to start npm: ${error.message}`,\n null\n )\n );\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new UpdateExecutionError(\n `npm install failed with exit code ${code}`,\n code\n )\n );\n });\n });\n }\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","mkdirSync","join","dirname","homedir","fileURLToPath","require","writeFileSync","readFileSync","existsSync","mkdirSync","join","homedir","Command","chalk","chalk","ora","chalk","getDeviceFlowService","OraUICallbacks","ora","getCredentialStore","getGlobalTokenCache","url","chalk","getGlobalTokenCache","currentEnv","chalk","ora","decodeJwt","Command","ora","chalk","buildUrl","ora","chalk","startTime","duration","data","Command","Command","writeFileSync","existsSync","readFileSync","mkdirSync","join","dirname","homedir","fileURLToPath","chalk","CONFIG_DIR","CONFIG_FILE_PATH","getProjectRoot","ensureConfigDir","Command","Command","Command"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/debug.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/utils/version/checker.ts","../src/utils/version/cache.ts","../src/utils/version/compare.ts","../src/utils/version/provider.ts","../src/utils/version/persistent-cache.ts","../src/utils/version/notifier.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","../src/commands/update.ts","../src/core/update/npm-updater.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('');\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 * 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","/**\r\n * 配置常量\r\n * 只包含常量定义,不包含环境配置\r\n */\r\n\r\n/**\r\n * 配置文件名\r\n */\r\nexport const CONFIG_FILE = '.wukong-cli.json';\r\n\r\n/**\r\n * Keytar 服务名\r\n */\r\nexport const KEYTAR_SERVICE = 'wukong-cli';\r\n\r\n/**\r\n * Keytar 账户名\r\n */\r\nexport const KEYTAR_ACCOUNTS = {\r\n ACCESS_TOKEN: 'access_token',\r\n REFRESH_TOKEN: 'refresh_token',\r\n YST_ACCESS_TOKEN: 'yst_access_token',\r\n YST_REFRESH_TOKEN: 'yst_refresh_token',\r\n} as const;\r\n\r\n/**\r\n * API 端点路径\r\n */\r\nexport const API_ENDPOINTS = {\r\n AUTH: {\r\n DEVICE_AUTHORIZE: '/oceanet-auth/pkce/device/authorize',\r\n DEVICE_TOKEN: '/oceanet-auth/pkce/device/token',\r\n REFRESH_TOKEN: '/oceanet-auth/manage/refreshToken',\r\n REFRESH_TOKEN_NRP: '/oceanet-auth/manage/refreshTokenNRP',\r\n LOGOUT: '/oceanet-auth/manage/logout',\r\n },\r\n API: {\r\n USER_INFO: '/oceanet-auth/web/userInfo',\r\n },\r\n} as const;\r\n\r\n/**\r\n * 轮询配置\r\n */\r\nexport const POLL_CONFIG = {\r\n INTERVAL: 3, // 轮询间隔(秒)\r\n TIMEOUT: 300, // 轮询超时(秒)\r\n} as const;\r\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 */\nconst CONFIG_DIR = join(homedir(), '.wukong-cli');\nconst CONFIG_FILE_PATH = join(CONFIG_DIR, 'wukong-cli.json');\n\n/**\n * 获取用户配置文件路径\n * 配置文件位于 ~/.wukong-cli/wukong-cli.json\n */\nexport function getUserConfigPath(): string {\n return CONFIG_FILE_PATH;\n}\n\n/**\n * 确保配置目录存在\n */\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\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 ensureConfigDir();\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","/**\r\n * Device Flow Service - 设备码授权流程(纯业务逻辑)\r\n * 从 device-flow.ts 提取,移除 UI 依赖\r\n */\r\n\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\r\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\r\n\r\n/**\r\n * 设备流程服务接口\r\n * 定义设备码授权流程的核心操作\r\n */\r\nexport interface IDeviceFlowService {\r\n /**\r\n * 获取设备授权码\r\n * @returns 设备授权响应,包含验证 URL 和设备码\r\n */\r\n getDeviceCode(): Promise<DeviceCodeResponse>;\r\n\r\n /**\r\n * 轮询获取 token\r\n * @param deviceCode 设备码\r\n * @returns Token 对\r\n */\r\n pollToken(deviceCode: string): Promise<TokenPair>;\r\n}\r\n\r\n/**\r\n * 设备流程服务实现\r\n * 纯业务逻辑,不包含 UI 依赖\r\n */\r\nexport class DeviceFlowService implements IDeviceFlowService {\r\n /**\r\n * 获取设备授权码\r\n */\r\n async getDeviceCode(): Promise<DeviceCodeResponse> {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_AUTHORIZE}`;\r\n const requestBody = {\r\n param: {\r\n clientId: config.CLIENT_ID,\r\n },\r\n };\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n // 打印请求(调试模式)\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n const data = await response.json();\r\n\r\n // 打印响应(调试模式)\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n if (data.code !== 200) {\r\n throw new Error(\r\n `(${data.code}) ${data.message || 'Failed to get device code'}`\r\n );\r\n }\r\n\r\n const { verificationUri, expiresIn, interval } = data.result;\r\n\r\n // 从 URL 中提取 deviceCode\r\n const urlObj = new URL(verificationUri);\r\n const deviceCode = urlObj.searchParams.get('code') || '';\r\n\r\n return {\r\n verificationUri,\r\n deviceCode,\r\n expiresIn,\r\n interval: interval || config.POLL.INTERVAL,\r\n };\r\n }\r\n\r\n /**\r\n * 轮询获取 token\r\n */\r\n async pollToken(deviceCode: string): Promise<TokenPair> {\r\n const startTime = Date.now();\r\n const config = getOceanetConfig();\r\n\r\n while (Date.now() - startTime < config.POLL.TIMEOUT * 1000) {\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_TOKEN}`;\r\n const requestBody = {\r\n param: {\r\n clientId: config.CLIENT_ID,\r\n deviceCode,\r\n },\r\n };\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n // 打印请求(调试模式)\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const requestStartTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - requestStartTime;\r\n const data = await response.json();\r\n\r\n // 打印响应(调试模式)\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n // 检查 API 错误(忽略 PENDING 状态)\r\n if (data.code !== 200) {\r\n // 静默跳过错误状态,继续轮询\r\n await new Promise((resolve) =>\r\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\r\n );\r\n continue;\r\n }\r\n\r\n // result 为 null 或空表示 PENDING,继续轮询\r\n if (!data.result) {\r\n await new Promise((resolve) =>\r\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\r\n );\r\n continue;\r\n }\r\n\r\n // 成功获取 token\r\n const {\r\n access_token,\r\n refresh_token,\r\n expires_in,\r\n token_type,\r\n scope,\r\n yst_access_token,\r\n yst_refresh_token,\r\n } = data.result;\r\n\r\n return {\r\n accessToken: access_token,\r\n refreshToken: refresh_token,\r\n expiresIn: expires_in,\r\n tokenType: token_type,\r\n scope: Array.isArray(scope) ? scope : [scope || ''],\r\n ...(yst_access_token ? { ystAccessToken: yst_access_token } : {}),\r\n ...(yst_refresh_token ? { ystRefreshToken: yst_refresh_token } : {}),\r\n };\r\n }\r\n\r\n // 超时\r\n throw new Error('Authorization timed out. Please try again.');\r\n }\r\n}\r\n\r\n/**\r\n * 获取设备流程服务实例\r\n */\r\nexport function getDeviceFlowService(): IDeviceFlowService {\r\n return new DeviceFlowService();\r\n}\r\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","/**\r\n * Token Cache 接口 - Token 缓存抽象\r\n * 用于替代全局变量 (global as any).__cachedAccessToken\r\n */\r\n\r\n/**\r\n * Token 缓存接口\r\n * 定义了 token 的读取、设置和清除操作\r\n */\r\nexport interface ITokenCache {\r\n getAccessToken(): string | null;\r\n getRefreshToken(): string | null;\r\n getYstAccessToken(): string | null;\r\n getYstRefreshToken(): string | null;\r\n setTokens(accessToken: string | null, refreshToken: string | null, ystAccessToken?: string | null, ystRefreshToken?: string | null): void;\r\n clear(): void;\r\n hasAccessToken(): boolean;\r\n hasRefreshToken(): boolean;\r\n}\r\n\r\n/**\r\n * 内存 Token 缓存实现\r\n * 将 token 存储在内存中,适用于单次 CLI 会话\r\n */\r\nexport class MemoryTokenCache implements ITokenCache {\r\n private accessToken: string | null = null;\r\n private refreshToken: string | null = null;\r\n private ystAccessToken: string | null = null;\r\n private ystRefreshToken: string | null = null;\r\n\r\n getAccessToken(): string | null {\r\n return this.accessToken;\r\n }\r\n\r\n getRefreshToken(): string | null {\r\n return this.refreshToken;\r\n }\r\n\r\n getYstAccessToken(): string | null {\r\n return this.ystAccessToken;\r\n }\r\n\r\n getYstRefreshToken(): string | null {\r\n return this.ystRefreshToken;\r\n }\r\n\r\n setTokens(accessToken: string | null, refreshToken: string | null, ystAccessToken?: string | null, ystRefreshToken?: string | null): void {\r\n if (accessToken !== null) this.accessToken = accessToken;\r\n if (refreshToken !== null) this.refreshToken = refreshToken;\r\n if (ystAccessToken !== undefined && ystAccessToken !== null) this.ystAccessToken = ystAccessToken;\r\n if (ystRefreshToken !== undefined && ystRefreshToken !== null) this.ystRefreshToken = ystRefreshToken;\r\n }\r\n\r\n clear(): void {\r\n this.accessToken = null;\r\n this.refreshToken = null;\r\n this.ystAccessToken = null;\r\n this.ystRefreshToken = null;\r\n }\r\n\r\n hasAccessToken(): boolean {\r\n return this.accessToken !== null && this.accessToken.length > 0;\r\n }\r\n\r\n hasRefreshToken(): boolean {\r\n return this.refreshToken !== null && this.refreshToken.length > 0;\r\n }\r\n}\r\n\r\n/**\r\n * 全局 Token 缓存实例(单例)\r\n * 用于在整个 CLI 会话中共享同一个缓存实例\r\n */\r\nlet globalCacheInstance: ITokenCache | null = null;\r\n\r\n/**\r\n * 获取全局 Token 缓存实例\r\n * 如果不存在则创建一个新的 MemoryTokenCache 实例\r\n */\r\nexport function getGlobalTokenCache(): ITokenCache {\r\n if (!globalCacheInstance) {\r\n globalCacheInstance = new MemoryTokenCache();\r\n }\r\n return globalCacheInstance;\r\n}\r\n\r\n/**\r\n * 重置全局 Token 缓存实例\r\n * 用于测试或环境切换\r\n */\r\nexport function resetGlobalTokenCache(): void {\r\n globalCacheInstance = null;\r\n}\r\n\r\n/**\r\n * 初始化 Token 缓存\r\n * 从持久化存储加载 token 到内存缓存\r\n */\r\nexport async function initializeTokenCache(\r\n loadTokens: () => Promise<{ accessToken: string | null; refreshToken: string | null }>\r\n): Promise<void> {\r\n const cache = getGlobalTokenCache();\r\n const { accessToken, refreshToken } = await loadTokens();\r\n\r\n if (accessToken && refreshToken) {\r\n cache.setTokens(accessToken, refreshToken);\r\n }\r\n}\r\n","/**\n * Wukong CLI 主入口\n * 命令结构: wukong-cli <command> [subcommand] [options]\n */\n\ndeclare const CLI_VERSION: string;\n\nimport { Command } from 'commander';\nimport { setDebugMode } from './utils/debug.js';\nimport { getVersionChecker } from './utils/version/index.js';\nimport { ConsoleNotifier } from './utils/version/notifier.js';\nimport { authCommands } from './commands/auth.js';\nimport { httpCommand } from './commands/http.js';\nimport { initCommand } from './commands/init.js';\nimport { updateCommand } from './commands/update.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// 添加 update 命令\nprogram.addCommand(updateCommand);\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(CLI_VERSION);\n const notifier = new ConsoleNotifier();\n\n versionChecker.checkInBackground(notifier).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\nimport { VersionChecker } from './checker.js';\nimport { NpmVersionProvider } from './provider.js';\nimport { PersistentVersionCache } from './persistent-cache.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\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';\nexport { compareVersions, describeVersionComparison } from './compare.js';\nexport type { VersionComparison } from './compare.js';\nexport { PersistentVersionCache } from './persistent-cache.js';\nexport { ConsoleNotifier } from './notifier.js';\nexport type { UpdateNotifier } from './notifier.js';\n\n/**\n * Create VersionChecker instance (singleton pattern)\n */\nlet versionCheckerInstance: VersionChecker | null = null;\n\nexport function getVersionChecker(currentVersion: string): VersionChecker {\n if (versionCheckerInstance) {\n return versionCheckerInstance;\n }\n\n const cacheFilePath = join(homedir(), '.wukong-cli', 'version-cache.json');\n const provider = new NpmVersionProvider(\n '@zrhsh/wukong-cli',\n 'https://registry.npmjs.org'\n );\n\n const instance: VersionChecker = new VersionChecker(\n provider,\n currentVersion,\n new PersistentVersionCache(cacheFilePath)\n );\n\n versionCheckerInstance = instance;\n return instance;\n}\n\n/**\n * Reset version checker instance (for testing)\n */\nexport function resetVersionChecker(): void {\n versionCheckerInstance = null;\n}\n","/**\n * Version Checker\n * Coordinates version checking with caching\n */\n\nimport type { IVersionProvider } from './provider.js';\nimport { VersionCache } from './cache.js';\nimport { compareVersions } from './compare.js';\nimport type { UpdateNotifier } from './notifier.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 * 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: 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: 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(notifier?: UpdateNotifier): Promise<void> {\n try {\n const result = await this.checkForUpdate();\n if (result.hasUpdate && notifier && result.latestVersion) {\n notifier.notify(result.currentVersion, result.latestVersion);\n }\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.lastCheck,\n cachedVersion: this.cache.version,\n };\n }\n}\n","/**\n * Version Cache\n * Manages caching of version check results\n */\n\nexport class VersionCache {\n protected lastCheckTime: number = 0;\n protected 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 /** Last check timestamp */\n get lastCheck(): number {\n return this.lastCheckTime;\n }\n\n /** Cached version string */\n get version(): string | null {\n return this.cachedVersion;\n }\n}\n","/**\n * Version comparison utilities.\n */\n\nexport type VersionComparison = -1 | 0 | 1;\n\nexport function compareVersions(v1: string, v2: string): VersionComparison {\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\nexport function describeVersionComparison(\n currentVersion: string,\n latestVersion: string\n): string {\n const comparison = compareVersions(currentVersion, latestVersion);\n\n if (comparison > 0) {\n return 'current version is newer than latest';\n }\n\n if (comparison < 0) {\n return 'latest version is newer';\n }\n\n return 'current version is equal to latest';\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","import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { VersionCache } from './cache.js';\n\ninterface CacheData {\n lastCheckTime: number;\n version: string;\n}\n\nexport class PersistentVersionCache extends VersionCache {\n private readonly cacheFilePath: string;\n\n constructor(cacheFilePath: string, checkInterval?: number) {\n super(checkInterval);\n this.cacheFilePath = cacheFilePath;\n this.loadFromFile();\n }\n\n private loadFromFile(): void {\n try {\n const content = readFileSync(this.cacheFilePath, 'utf-8');\n const data: CacheData = JSON.parse(content);\n\n if (typeof data.lastCheckTime === 'number' && typeof data.version === 'string') {\n this.lastCheckTime = data.lastCheckTime;\n this.cachedVersion = data.version;\n }\n } catch {\n // 文件不存在或内容损坏,使用默认空状态\n }\n }\n\n private saveToFile(): void {\n try {\n mkdirSync(dirname(this.cacheFilePath), { recursive: true });\n const data: CacheData = {\n lastCheckTime: this.lastCheckTime,\n version: this.cachedVersion ?? '',\n };\n writeFileSync(this.cacheFilePath, JSON.stringify(data), 'utf-8');\n } catch {\n // 写入失败,静默跳过,内存缓存仍然有效\n }\n }\n\n set(version: string): void {\n super.set(version);\n this.saveToFile();\n }\n\n clear(): void {\n super.clear();\n this.saveToFile();\n }\n}\n","import chalk from 'chalk';\n\nexport interface UpdateNotifier {\n notify(currentVersion: string, latestVersion: string): void;\n}\n\nexport class ConsoleNotifier implements UpdateNotifier {\n notify(currentVersion: string, latestVersion: string): void {\n const message = `New version available: ${currentVersion} → ${latestVersion}, run 'wukong-cli update' to update.`;\n console.log(chalk.yellow(message));\n }\n}\n","/**\r\n * Auth 命令组 - 基于 Oceanet Auth\r\n * wukong-cli auth <subcommand>\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport chalk from 'chalk';\r\nimport ora from 'ora';\r\nimport { printEnvironmentInfo } from '../utils/environment.js';\r\nimport { success, error } from '../utils/symbols.js';\r\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\r\nimport { createCliDeviceFlowAdapter } from '../adapters/cli-device-flow.js';\r\nimport {\r\n saveToken,\r\n getAccessToken,\r\n getRefreshToken,\r\n getYstAccessToken,\r\n getYstRefreshToken,\r\n getTokenManager,\r\n logout,\r\n} from '../core/auth/token-manager.js';\r\nimport { getClient } from '../core/http/client.js';\r\nimport {\r\n Environment,\r\n ENVIRONMENTS,\r\n} from '../config/environments.js';\r\nimport { setCurrentEnvironment, getOceanetConfig, getCurrentEnvironment } from '../config/oceanet.js';\r\nimport { getAllEnvironments } from '../config/config-loader.js';\r\n\r\nexport const authCommands = new Command('auth')\r\n .description('Authentication commands');\r\n\r\n// 登录命令\r\nauthCommands\r\n .command('login')\r\n .description('Login using Device Authorization Flow')\r\n .action(async () => {\r\n try {\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n // 设置当前环境\r\n setCurrentEnvironment(env as Environment);\r\n const config = getOceanetConfig();\r\n const envConfig = allEnvs[env];\r\n\r\n console.log('');\r\n console.log(chalk.bgBlue.white.bold(' Wukong CLI Login '));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log('');\r\n\r\n // 步骤 1: 获取设备授权链接(使用新 API)\r\n const adapter = createCliDeviceFlowAdapter();\r\n const { verificationUri, deviceCode, expiresIn, interval } =\r\n await adapter.getDeviceCode();\r\n\r\n // 显示授权信息\r\n console.log('');\r\n console.log(chalk.bold('='.repeat(50)));\r\n console.log(chalk.bold(' Please complete authorization'));\r\n console.log(chalk.bold('='.repeat(50)));\r\n console.log('');\r\n console.log(chalk.green(' Authorization URL:'));\r\n console.log('');\r\n\r\n // 用多种方式显示链接,确保用户能看到\r\n console.log(chalk.cyan(` ${verificationUri}`));\r\n console.log('');\r\n\r\n // 同时输出到 stderr(Claude Code 能捕获)\r\n console.error(chalk.yellow.bold('>>> Please open this link in your browser <<<'));\r\n console.error(chalk.cyan(verificationUri));\r\n console.error('');\r\n\r\n // 尝试自动打开浏览器(如果环境支持)\r\n const open = await import('open').catch(() => null);\r\n if (open) {\r\n try {\r\n await open.default(verificationUri);\r\n console.log(chalk.dim(' Browser opened automatically'));\r\n } catch {\r\n console.log(chalk.dim(' Please copy link to browser'));\r\n }\r\n } else {\r\n console.log(chalk.dim(' Please copy link to browser'));\r\n }\r\n console.log('');\r\n\r\n console.log(chalk.dim('═'.repeat(50)));\r\n console.log(chalk.dim(` Device Code: ${deviceCode}`));\r\n console.log(chalk.dim(` Expires in: ${expiresIn} seconds`));\r\n console.log(chalk.dim('═'.repeat(50)));\r\n console.log('');\r\n\r\n // 步骤 2: 轮询获取 Token(使用新 API)\r\n const tokens = await adapter.pollToken(deviceCode);\r\n\r\n // 步骤 3: 保存 Token\r\n await saveToken({\r\n accessToken: tokens.accessToken,\r\n refreshToken: tokens.refreshToken,\r\n ystAccessToken: tokens.ystAccessToken,\r\n ystRefreshToken: tokens.ystRefreshToken,\r\n });\r\n\r\n console.log('');\r\n console.log(chalk.bgGreen.black.bold(' [OK] Login Successful '));\r\n console.log('');\r\n console.log(chalk.green('[OK] Tokens saved securely'));\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));\r\n console.log('');\r\n console.log(chalk.dim('Next:'), chalk.cyan('wukong-cli auth status'));\r\n console.log('');\r\n\r\n } catch (error) {\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // Handle other errors\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n console.log('');\r\n }\r\n });\r\n\r\n// 登出命令\r\nauthCommands\r\n .command('logout')\r\n .description('Logout and clear saved tokens')\r\n .action(async () => {\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n setCurrentEnvironment(env as Environment);\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const accessToken = await getAccessToken();\r\n const ystAccessToken = await getYstAccessToken();\r\n\r\n if (accessToken) {\r\n await logout(accessToken, ystAccessToken ?? undefined);\r\n }\r\n\r\n console.log('');\r\n console.log(chalk.green(`[OK] Logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\r\n console.log('');\r\n } catch {\r\n console.log('');\r\n console.log(chalk.yellow(`○ Already logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\r\n console.log('');\r\n }\r\n });\r\n\r\n// 刷新 token 命令\r\nauthCommands\r\n .command('refresh')\r\n .description('Manually refresh access token')\r\n .action(async () => {\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const accessToken = await getAccessToken();\r\n\r\n if (!accessToken) {\r\n console.log('');\r\n console.log(chalk.yellow('[ERROR] Not authenticated'));\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log('');\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n return; // 不使用 process.exit,让程序自然退出\r\n }\r\n\r\n const spinner = ora('Refreshing access token...').start();\r\n\r\n try {\r\n const client = getClient();\r\n await client.refreshToken();\r\n\r\n spinner.succeed('Token refreshed successfully!');\r\n\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim('New tokens saved securely'));\r\n console.log('');\r\n } catch (error) {\r\n spinner.fail('Token refresh failed');\r\n throw error;\r\n }\r\n } catch (error) {\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // Handle other errors\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Your session may have expired. Please run:`));\r\n console.log(chalk.dim(` wukong-cli auth login`));\r\n console.log('');\r\n // 不使用 process.exit,让程序自然退出\r\n }\r\n });\r\n\r\n// 状态命令\r\nauthCommands\r\n .command('status')\r\n .description('Show authentication status')\r\n .action(async () => {\r\n console.log('');\r\n\r\n // 获取当前环境(从环境变量或配置文件)\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n setCurrentEnvironment(env as Environment);\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const accessToken = await getAccessToken();\r\n\r\n if (!accessToken) {\r\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // 尝试获取用户信息来验证 token 是否真的有效\r\n try {\r\n const client = getClient();\r\n const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;\r\n const userInfo = await client.get(userInfoUrl);\r\n\r\n // 只有 API 调用成功才显示已认证\r\n console.log(chalk.green('[OK] Authenticated'));\r\n console.log('');\r\n\r\n const displayUser = userInfo.firstName\r\n ? `${userInfo.firstName} (${userInfo.username})`\r\n : userInfo.username || 'N/A';\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim('User:'), chalk.cyan(displayUser));\r\n console.log(chalk.dim('Email:'), chalk.cyan(userInfo.email || 'N/A'));\r\n console.log(chalk.dim('OrgCode:'), chalk.cyan(userInfo.ouCode || 'N/A'));\r\n console.log(chalk.dim('OrgName:'), chalk.cyan(userInfo.ouName || 'N/A'));\r\n console.log('');\r\n } catch (error: any) {\r\n const errorMsg = error instanceof Error ? error.message : String(error);\r\n\r\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\r\n console.log('');\r\n\r\n console.log(chalk.red('Error:'), chalk.dim(errorMsg));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n }\r\n } catch (error) {\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n // Handle other errors\r\n console.log(chalk.yellow(`✗ Not authenticated`));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim(`Run: wukong-cli auth login`));\r\n console.log('');\r\n }\r\n });\r\n\r\n// Token 信息命令\r\nauthCommands\r\n .command('token')\r\n .description('Display current token structure and JWT payload claims')\r\n .action(async () => {\r\n console.log('');\r\n\r\n const env = getCurrentEnvironment();\r\n const allEnvs = getAllEnvironments();\r\n\r\n setCurrentEnvironment(env as Environment);\r\n const envConfig = allEnvs[env];\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const accessToken = await getAccessToken();\r\n const refreshToken = await getRefreshToken();\r\n\r\n if (!accessToken) {\r\n console.log(chalk.yellow('[ERROR] Not authenticated'));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log(chalk.dim('Run: wukong-cli auth login'));\r\n console.log('');\r\n return;\r\n }\r\n\r\n function decodeJwt(token: string): { header: Record<string, unknown>; payload: Record<string, unknown> } | null {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) return null;\r\n const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString('utf-8'));\r\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));\r\n return { header, payload };\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n console.log(chalk.bgGreen.black.bold(' Token Information '));\r\n console.log('');\r\n printEnvironmentInfo(env, envConfig.displayName);\r\n console.log('');\r\n\r\n const decoded = decodeJwt(accessToken);\r\n\r\n if (!decoded) {\r\n console.log(chalk.yellow('[WARNING] Access token is not a valid JWT'));\r\n console.log('');\r\n console.log(chalk.dim('Access Token (raw):'), chalk.cyan(accessToken.substring(0, 40) + '...'));\r\n if (refreshToken) {\r\n console.log(chalk.dim('Refresh Token:'), chalk.cyan(refreshToken.substring(0, 20) + '...' + refreshToken.slice(-4)));\r\n }\r\n console.log('');\r\n return;\r\n }\r\n\r\n console.log(chalk.bold('JWT Header:'));\r\n console.log(chalk.dim(' alg:'), chalk.cyan(String(decoded.header.alg ?? 'N/A')));\r\n console.log(chalk.dim(' typ:'), chalk.cyan(String(decoded.header.typ ?? 'N/A')));\r\n console.log('');\r\n\r\n console.log(chalk.bold('JWT Payload:'));\r\n const skipKeys = new Set(['exp', 'iat', 'nbf', 'jti']);\r\n for (const [key, value] of Object.entries(decoded.payload)) {\r\n if (skipKeys.has(key)) continue;\r\n console.log(chalk.dim(` ${key}:`), chalk.cyan(String(value)));\r\n }\r\n console.log('');\r\n\r\n const now = Date.now();\r\n const exp = typeof decoded.payload.exp === 'number' ? decoded.payload.exp * 1000 : null;\r\n const iat = typeof decoded.payload.iat === 'number' ? decoded.payload.iat * 1000 : null;\r\n\r\n console.log(chalk.bold('Expiration:'));\r\n if (exp) {\r\n const expDate = new Date(exp);\r\n const diffMs = exp - now;\r\n\r\n if (diffMs <= 0) {\r\n console.log(chalk.dim(' Status:'), chalk.red('EXPIRED'));\r\n console.log(chalk.dim(' Expired at:'), chalk.red(expDate.toLocaleString()));\r\n } else if (diffMs < 5 * 60 * 1000) {\r\n console.log(chalk.dim(' Status:'), chalk.yellow('Expiring soon'));\r\n console.log(chalk.dim(' Expires at:'), chalk.yellow(expDate.toLocaleString()));\r\n console.log(chalk.dim(' Remaining:'), chalk.yellow(`${Math.floor(diffMs / 60000)} minutes`));\r\n } else {\r\n console.log(chalk.dim(' Status:'), chalk.green('Valid'));\r\n console.log(chalk.dim(' Expires at:'), chalk.green(expDate.toLocaleString()));\r\n console.log(chalk.dim(' Remaining:'), chalk.green(`${Math.floor(diffMs / 60000)} minutes`));\r\n }\r\n } else {\r\n console.log(chalk.dim(' exp:'), chalk.yellow('N/A'));\r\n }\r\n\r\n if (iat) {\r\n console.log(chalk.dim(' Issued at:'), chalk.cyan(new Date(iat).toLocaleString()));\r\n }\r\n console.log('');\r\n\r\n if (refreshToken) {\r\n console.log(chalk.bold('Refresh Token:'));\r\n console.log(chalk.dim(' Token:'), chalk.cyan(refreshToken.substring(0, 20) + '...' + refreshToken.slice(-4)));\r\n console.log(chalk.dim(' Length:'), chalk.cyan(`${refreshToken.length} characters`));\r\n console.log('');\r\n } else {\r\n console.log(chalk.dim('Refresh Token:'), chalk.yellow('Not available'));\r\n console.log('');\r\n }\r\n\r\n // YST Token 信息\r\n const ystAccessToken = await getYstAccessToken();\r\n const ystRefreshToken = await getYstRefreshToken();\r\n\r\n if (ystAccessToken || ystRefreshToken) {\r\n console.log(chalk.bold('YST Token (NRP):'));\r\n if (ystAccessToken) {\r\n console.log(chalk.dim(' Access Token:'), chalk.cyan(ystAccessToken.substring(0, 20) + '...' + ystAccessToken.slice(-4)));\r\n console.log(chalk.dim(' Length:'), chalk.cyan(`${ystAccessToken.length} characters`));\r\n\r\n const ystDecoded = decodeJwt(ystAccessToken);\r\n if (ystDecoded) {\r\n const ystExp = typeof ystDecoded.payload.exp === 'number' ? ystDecoded.payload.exp * 1000 : null;\r\n if (ystExp) {\r\n const ystDiffMs = ystExp - now;\r\n if (ystDiffMs <= 0) {\r\n console.log(chalk.dim(' JWT Status:'), chalk.red('EXPIRED'));\r\n console.log(chalk.dim(' Expires at:'), chalk.red(new Date(ystExp).toLocaleString()));\r\n } else if (ystDiffMs < 5 * 60 * 1000) {\r\n console.log(chalk.dim(' JWT Status:'), chalk.yellow('Expiring soon'));\r\n console.log(chalk.dim(' Expires at:'), chalk.yellow(new Date(ystExp).toLocaleString()));\r\n } else {\r\n console.log(chalk.dim(' JWT Status:'), chalk.green('Valid'));\r\n console.log(chalk.dim(' Expires at:'), chalk.green(new Date(ystExp).toLocaleString()));\r\n console.log(chalk.dim(' Remaining:'), chalk.green(`${Math.floor(ystDiffMs / 60000)} minutes`));\r\n }\r\n }\r\n }\r\n\r\n // 服务端校验 yst token\r\n console.log(chalk.dim(' Server:'));\r\n try {\r\n const ystVerifyUrl = `${config.API_BASE_URL}/yst-system/sys/users/current`;\r\n const ystResponse = await fetch(ystVerifyUrl, {\r\n headers: { 'Authorization': `Bearer ${ystAccessToken}` },\r\n });\r\n if (ystResponse.ok) {\r\n console.log(chalk.dim(' Status:'), chalk.green('Valid (server verified)'));\r\n } else {\r\n const ystErrText = await ystResponse.text().catch(() => '');\r\n console.log(chalk.dim(' Status:'), chalk.red(`Invalid (HTTP ${ystResponse.status})`));\r\n if (ystErrText) {\r\n console.log(chalk.dim(' Error:'), chalk.red(ystErrText.substring(0, 100)));\r\n }\r\n }\r\n } catch (ystVerifyError) {\r\n console.log(chalk.dim(' Status:'), chalk.yellow('Unable to verify (network error)'));\r\n }\r\n } else {\r\n console.log(chalk.dim(' Access Token:'), chalk.yellow('Not available'));\r\n }\r\n if (ystRefreshToken) {\r\n console.log(chalk.dim(' Refresh Token:'), chalk.cyan(ystRefreshToken.substring(0, 20) + '...' + ystRefreshToken.slice(-4)));\r\n console.log(chalk.dim(' Refresh Length:'), chalk.cyan(`${ystRefreshToken.length} characters`));\r\n } else {\r\n console.log(chalk.dim(' Refresh Token:'), chalk.yellow('Not available'));\r\n }\r\n console.log('');\r\n }\r\n\r\n } catch (error) {\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red('[ERROR] Configuration Error'));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n return;\r\n }\r\n\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n console.log('');\r\n }\r\n });\r\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","/**\r\n * Token Manager - Token 存储和刷新管理\r\n * 从 oceanet.ts 提取的 token 管理逻辑\r\n */\r\n\r\nimport ora from 'ora';\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\r\nimport type { TokenPair } from '../../types/auth.js';\r\nimport type { ICredentialStore } from '../../providers/credential-store.js';\r\nimport type { ITokenCache } from './token-cache.js';\r\n\r\nexport interface SaveTokenOptions {\r\n accessToken: string;\r\n refreshToken: string;\r\n ystAccessToken?: string;\r\n ystRefreshToken?: string;\r\n}\r\n\r\n/**\r\n * Token Manager 类\r\n * 负责与底层凭据存储和 token 缓存的交互\r\n */\r\nexport class TokenManager {\r\n constructor(\r\n private credentialStore: ICredentialStore,\r\n private tokenCache: ITokenCache\r\n ) {}\r\n\r\n async saveToken(options: SaveTokenOptions): Promise<void> {\r\n const config = getOceanetConfig();\r\n const { accessToken, refreshToken, ystAccessToken, ystRefreshToken } = options;\r\n\r\n await Promise.all([\r\n this.credentialStore.setPassword(config.SERVICE_NAME, 'access_token', accessToken),\r\n this.credentialStore.setPassword(config.SERVICE_NAME, 'refresh_token', refreshToken),\r\n ...(ystAccessToken ? [this.credentialStore.setPassword(config.SERVICE_NAME, 'yst_access_token', ystAccessToken)] : []),\r\n ...(ystRefreshToken ? [this.credentialStore.setPassword(config.SERVICE_NAME, 'yst_refresh_token', ystRefreshToken)] : []),\r\n ]);\r\n\r\n this.tokenCache.setTokens(accessToken, refreshToken, ystAccessToken ?? null, ystRefreshToken ?? null);\r\n }\r\n\r\n async getAccessToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getAccessToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(token, null);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async getRefreshToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getRefreshToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(null, token);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async getYstAccessToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getYstAccessToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_access_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(null, null, token, null);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async getYstRefreshToken(): Promise<string | null> {\r\n const cached = this.tokenCache.getYstRefreshToken();\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const config = getOceanetConfig();\r\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_refresh_token');\r\n\r\n if (token) {\r\n this.tokenCache.setTokens(null, null, null, token);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n async refreshAccessToken(\r\n refreshToken: string\r\n ): Promise<TokenPair> {\r\n const spinner = ora('Refreshing access token...').start();\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n const requestBody = { param: refreshToken };\r\n\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n const data = await response.json();\r\n\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n if (data.code !== 200) {\r\n spinner.fail('Token refresh failed');\r\n throw new Error(data.message || 'Refresh token failed');\r\n }\r\n\r\n const {\r\n access_token,\r\n refresh_token: new_refresh_token,\r\n expires_in,\r\n token_type,\r\n scope,\r\n yst_access_token,\r\n yst_refresh_token: yst_new_refresh_token,\r\n } = data.result;\r\n\r\n spinner.succeed('Token refreshed');\r\n\r\n return {\r\n accessToken: access_token,\r\n refreshToken: new_refresh_token,\r\n expiresIn: expires_in,\r\n tokenType: token_type,\r\n scope: Array.isArray(scope) ? scope : [scope || ''],\r\n ...(yst_access_token ? { ystAccessToken: yst_access_token } : {}),\r\n ...(yst_new_refresh_token ? { ystRefreshToken: yst_new_refresh_token } : {}),\r\n };\r\n } catch (error) {\r\n spinner.fail('Token refresh error');\r\n throw error;\r\n }\r\n }\r\n\r\n async refreshYstAccessToken(\r\n ystRefreshToken: string\r\n ): Promise<{ ystAccessToken: string; ystRefreshToken: string }> {\r\n const spinner = ora('Refreshing YST access token...').start();\r\n\r\n try {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN_NRP}`;\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n const requestBody = { param: ystRefreshToken };\r\n\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n const data = await response.json();\r\n\r\n debugResponse(response.status, response.statusText, data, duration);\r\n\r\n if (data.code !== 200) {\r\n spinner.fail('YST token refresh failed');\r\n throw new Error(data.message || 'YST refresh token failed');\r\n }\r\n\r\n const { access_token, refresh_token } = data.result;\r\n\r\n spinner.succeed('YST token refreshed');\r\n\r\n return {\r\n ystAccessToken: access_token,\r\n ystRefreshToken: refresh_token,\r\n };\r\n } catch (error) {\r\n spinner.fail('YST token refresh error');\r\n throw error;\r\n }\r\n }\r\n\r\n async clearTokens(): Promise<void> {\r\n const config = getOceanetConfig();\r\n await Promise.all([\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'access_token'),\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'refresh_token'),\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'yst_access_token'),\r\n this.credentialStore.deletePassword(config.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n\r\n this.tokenCache.clear();\r\n }\r\n\r\n async logout(accessToken: string, ocAccessToken?: string): Promise<void> {\r\n try {\r\n const config = getOceanetConfig();\r\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`;\r\n\r\n const requestHeaders = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n const requestBody: Record<string, string> = {\r\n access_token: accessToken,\r\n };\r\n if (ocAccessToken) {\r\n requestBody.oc_access_token = ocAccessToken;\r\n }\r\n\r\n debugRequest('POST', url, requestHeaders, requestBody);\r\n\r\n const startTime = Date.now();\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: requestHeaders,\r\n body: JSON.stringify(requestBody),\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n\r\n let data;\r\n try {\r\n data = await response.json();\r\n } catch {\r\n // 响应可能为空\r\n }\r\n\r\n debugResponse(response.status, response.statusText, data || 'No response body', duration);\r\n } catch (error) {\r\n // 忽略退出登录错误\r\n }\r\n\r\n await this.clearTokens();\r\n }\r\n\r\n async initTokenCache(): Promise<void> {\r\n const config = getOceanetConfig();\r\n\r\n const [accessToken, refreshToken, ystAccessToken, ystRefreshToken] = await Promise.all([\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token'),\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token'),\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_access_token'),\r\n this.credentialStore.getPassword(config.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n\r\n if (accessToken || refreshToken || ystAccessToken || ystRefreshToken) {\r\n this.tokenCache.setTokens(\r\n accessToken || null,\r\n refreshToken || null,\r\n ystAccessToken || null,\r\n ystRefreshToken || null\r\n );\r\n }\r\n }\r\n}\r\n\r\n// ============ 便利函数(向后兼容) ============\r\n\r\nlet tokenManagerInstance: TokenManager | null = null;\r\n\r\nexport function getTokenManager(): TokenManager {\r\n if (!tokenManagerInstance) {\r\n const { getCredentialStore } = require('../../providers/credential-store.js');\r\n const { getGlobalTokenCache } = require('./token-cache.js');\r\n\r\n const credentialStore = getCredentialStore();\r\n const tokenCache = getGlobalTokenCache();\r\n\r\n tokenManagerInstance = new TokenManager(credentialStore, tokenCache);\r\n }\r\n return tokenManagerInstance;\r\n}\r\n\r\nexport function resetTokenManager(): void {\r\n tokenManagerInstance = null;\r\n}\r\n\r\n/**\r\n * 保存 Token(便利函数,向后兼容)\r\n * 支持两种调用方式:\r\n * saveToken(accessToken, refreshToken)\r\n * saveToken({ accessToken, refreshToken, ystAccessToken?, ystRefreshToken? })\r\n */\r\nexport async function saveToken(\r\n accessTokenOrOptions: string | SaveTokenOptions,\r\n refreshToken?: string\r\n): Promise<void> {\r\n const manager = getTokenManager();\r\n\r\n const options: SaveTokenOptions = typeof accessTokenOrOptions === 'string'\r\n ? { accessToken: accessTokenOrOptions, refreshToken: refreshToken! }\r\n : accessTokenOrOptions;\r\n\r\n await manager.saveToken(options);\r\n}\r\n\r\nexport async function getAccessToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getAccessToken();\r\n}\r\n\r\nexport async function getRefreshToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getRefreshToken();\r\n}\r\n\r\nexport async function getYstAccessToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getYstAccessToken();\r\n}\r\n\r\nexport async function getYstRefreshToken(): Promise<string | null> {\r\n const manager = getTokenManager();\r\n return await manager.getYstRefreshToken();\r\n}\r\n\r\nexport async function refreshAccessToken(\r\n refreshToken: string\r\n): Promise<TokenPair> {\r\n const manager = getTokenManager();\r\n return await manager.refreshAccessToken(refreshToken);\r\n}\r\n\r\nexport async function refreshYstAccessToken(\r\n ystRefreshToken: string\r\n): Promise<{ ystAccessToken: string; ystRefreshToken: string }> {\r\n const manager = getTokenManager();\r\n return await manager.refreshYstAccessToken(ystRefreshToken);\r\n}\r\n\r\nexport async function clearTokens(): Promise<void> {\r\n const manager = getTokenManager();\r\n await manager.clearTokens();\r\n}\r\n\r\nexport async function logout(accessToken: string, ocAccessToken?: string): Promise<void> {\r\n const manager = getTokenManager();\r\n await manager.logout(accessToken, ocAccessToken);\r\n}\r\n\r\nexport async function initTokenCache(): Promise<void> {\r\n const manager = getTokenManager();\r\n await manager.initTokenCache();\r\n}\r\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(\n endpoint: string,\n options: {\n baseUrl?: string;\n params?: Record<string, string>;\n } = {}\n): string {\n const { baseUrl, params } = options;\n\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 const base = baseUrl || config.API_BASE_URL;\n let url = `${base}${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 * 支持运行时 baseUrl 覆盖(用于多域名支持)\n */\n async request<T = any>(\n endpoint: string,\n options: RequestOptions & { baseUrl?: string } = {}\n ): Promise<T> {\n const {\n method = 'GET',\n headers = {},\n body,\n params,\n baseUrl,\n } = options;\n\n const url = buildUrl(endpoint, { baseUrl, 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","/**\r\n * 认证 HTTP 客户端 - 添加认证和自动刷新功能\r\n * 装饰器模式,为基础 HTTP 客户端添加认证能力\r\n */\r\n\r\nimport type { IHttpClient } from './http-client-interface.js';\r\nimport type { ITokenCache } from '../auth/token-cache.js';\r\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\r\nimport { getApiErrorHandler, ApiError } from './api-error-handler.js';\r\nimport { getRetoken } from './interceptors.js';\r\nimport { getTokenManager } from '../auth/token-manager.js';\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\n\r\n/**\r\n * 认证 HTTP 客户端\r\n * 为基础 HTTP 客户端添加:\r\n * 1. 自动添加 Authorization 头\r\n * 2. 401 自动刷新 token 并重试\r\n * 3. 业务错误处理\r\n */\r\nexport class AuthenticatingHttpClient implements IHttpClient {\r\n private initialized = false;\r\n\r\n constructor(\r\n private baseClient: IHttpClient,\r\n private tokenCache: ITokenCache\r\n ) {}\r\n\r\n /**\r\n * 确保 token 缓存已初始化\r\n */\r\n private async ensureInitialized(): Promise<void> {\r\n if (!this.initialized) {\r\n const tokenManager = getTokenManager();\r\n await tokenManager.initTokenCache();\r\n this.initialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * 解析 JWT exp 字段(用于诊断)\r\n */\r\n private parseJwtExp(token: string): number | null {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) return null;\r\n const payload = JSON.parse(\r\n Buffer.from(parts[1], 'base64url').toString('utf-8')\r\n );\r\n return typeof payload.exp === 'number' ? payload.exp * 1000 : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * 刷新 token,并确保当前客户端使用的缓存已同步到新 token。\r\n * ts-retoken@0.2.0 不会等待 async setTokens,因此这里显式同步并持久化。\r\n */\r\n private async refreshTokenAndPersist(retoken = getRetoken()): Promise<void> {\r\n const tokens = await retoken.refreshToken();\r\n\r\n if (tokens?.accessToken && tokens?.refreshToken) {\r\n this.tokenCache.setTokens(\r\n tokens.accessToken,\r\n tokens.refreshToken,\r\n tokens.ystAccessToken ?? null,\r\n tokens.ystRefreshToken ?? null\r\n );\r\n\r\n const tokenManager = getTokenManager();\r\n await tokenManager.saveToken({\r\n accessToken: tokens.accessToken,\r\n refreshToken: tokens.refreshToken,\r\n ystAccessToken: tokens.ystAccessToken,\r\n ystRefreshToken: tokens.ystRefreshToken,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * 发起认证的 HTTP 请求\r\n * 实现方案:手动预刷新 + 401 重试\r\n */\r\n async request<T = any>(\r\n endpoint: string,\r\n options: any = {}\r\n ): Promise<T> {\r\n await this.ensureInitialized();\r\n\r\n const retoken = getRetoken();\r\n const config = getOceanetConfig();\r\n const debug = config.DEBUG || (global as any).__debugMode;\r\n\r\n // === 诊断点 1: 检查 token 状态 ===\r\n if (debug) {\r\n const accessToken = this.tokenCache.getAccessToken();\r\n if (accessToken) {\r\n const exp = this.parseJwtExp(accessToken);\r\n console.log('');\r\n console.log('=== [DIAGNOSTIC] Token State Before Request ===');\r\n console.log(' Token exists:', !!accessToken);\r\n console.log(' Token length:', accessToken?.length || 0);\r\n console.log(' JWT exp:', exp ? new Date(exp).toISOString() : 'null');\r\n if (exp) {\r\n const timeUntilExpiry = exp - Date.now();\r\n console.log(' Seconds until expiry:', Math.floor(timeUntilExpiry / 1000));\r\n }\r\n console.log('');\r\n }\r\n }\r\n\r\n // === 诊断点 2: 检查 isTokenExpiringSoon ===\r\n const isExpiringSoon = await retoken.isTokenExpiringSoon();\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] isTokenExpiringSoon() ===');\r\n console.log(' Result:', isExpiringSoon);\r\n console.log('');\r\n }\r\n\r\n // ✅ 主动检查 token 是否即将过期(利用 ts-retoken 的能力)\r\n if (isExpiringSoon) {\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] Proactive Refresh Triggered ===');\r\n }\r\n // 尝试主动刷新,如果失败则继续使用旧 token(让被动刷新处理)\r\n try {\r\n const refreshStart = Date.now();\r\n await this.refreshTokenAndPersist(retoken);\r\n const refreshTime = Date.now() - refreshStart;\r\n if (debug) {\r\n console.log(' Proactive refresh SUCCESS (took ' + refreshTime + 'ms)');\r\n console.log('');\r\n }\r\n } catch (refreshError: any) {\r\n // ✅ 改为 console.log 确保能看到\r\n console.log('');\r\n console.log('=== [DIAGNOSTIC] Proactive Refresh Failed ===');\r\n console.log(' Error:', refreshError?.message || String(refreshError));\r\n console.log(' Error code:', (refreshError as any)?.code);\r\n console.log(' Will retry with reactive refresh if 9913 occurs');\r\n console.log('');\r\n }\r\n }\r\n\r\n // 第一次尝试\r\n try {\r\n return await this.tryRequest<T>(endpoint, options);\r\n } catch (error) {\r\n // === 诊断点 3: 检查错误类型 ===\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] First Request Failed ===');\r\n console.log(' Error:', error instanceof ApiError ? `ApiError(code=${error.code})` : String(error));\r\n console.log('');\r\n }\r\n\r\n // ✅ 检查是否是 9913 错误(token 过期)\r\n if (error instanceof ApiError && error.code === 9913) {\r\n if (debug) {\r\n console.log('=== [DIAGNOSTIC] Reactive Refresh Triggered (9913) ===');\r\n }\r\n await this.refreshTokenAndPersist(retoken);\r\n // ✅ 重试\r\n return await this.tryRequest<T>(endpoint, options);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 执行单次请求(辅助方法)\r\n * 委托给 BaseHttpClient,遵守装饰器模式\r\n */\r\n private async tryRequest<T>(\r\n endpoint: string,\r\n options: any = {}\r\n ): Promise<T> {\r\n const accessToken = this.tokenCache.getAccessToken();\r\n if (!accessToken) {\r\n throw new Error(\r\n 'Not authenticated. Please run: wukong-cli auth login'\r\n );\r\n }\r\n\r\n // ✅ 委托给 BaseHttpClient(遵守约定)\r\n const data = await this.baseClient.request<OceanetApiResponse<T>>(\r\n endpoint,\r\n {\r\n ...options,\r\n headers: {\r\n ...options.headers,\r\n 'Authorization': `Bearer ${accessToken}`,\r\n },\r\n }\r\n );\r\n\r\n // ✅ 检查业务错误码 9913\r\n if (data.code === 9913) {\r\n throw new ApiError(data.code, data.message || 'Token expired', true);\r\n }\r\n\r\n // ✅ 处理其他业务错误\r\n const errorHandler = getApiErrorHandler();\r\n errorHandler.handle(data);\r\n\r\n return data.result;\r\n }\r\n\r\n /**\r\n * GET 请求\r\n */\r\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'GET', params });\r\n }\r\n\r\n /**\r\n * POST 请求\r\n */\r\n async post<T = any>(\r\n endpoint: string,\r\n data?: any,\r\n headers?: Record<string, string>\r\n ): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'POST',\r\n body: data,\r\n headers,\r\n });\r\n }\r\n\r\n /**\r\n * PUT 请求\r\n */\r\n async put<T = any>(\r\n endpoint: string,\r\n data?: any,\r\n headers?: Record<string, string>\r\n ): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PUT',\r\n body: data,\r\n headers,\r\n });\r\n }\r\n\r\n /**\r\n * DELETE 请求\r\n */\r\n async delete<T = any>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'DELETE' });\r\n }\r\n\r\n /**\r\n * PATCH 请求\r\n */\r\n async patch<T = any>(\r\n endpoint: string,\r\n data?: any,\r\n headers?: Record<string, string>\r\n ): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PATCH',\r\n body: data,\r\n headers,\r\n });\r\n }\r\n\r\n /**\r\n * 检查 token 是否即将过期\r\n */\r\n async isTokenExpiringSoon(): Promise<boolean> {\r\n await this.ensureInitialized();\r\n const retoken = getRetoken();\r\n return retoken.isTokenExpiringSoon();\r\n }\r\n\r\n /**\r\n * 手动刷新 token\r\n */\r\n async refreshToken(): Promise<void> {\r\n await this.ensureInitialized();\r\n await this.refreshTokenAndPersist();\r\n }\r\n}\r\n","/**\r\n * API 错误处理器 - 处理 Oceanet API 特定错误\r\n */\r\n\r\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\r\nimport chalk from 'chalk';\r\n\r\n/**\r\n * API 错误类\r\n */\r\nexport class ApiError extends Error {\r\n constructor(\r\n public code: number,\r\n message: string,\r\n public retryable: boolean = false\r\n ) {\r\n super(message);\r\n this.name = 'ApiError';\r\n }\r\n}\r\n\r\n/**\r\n * 错误处理函数类型\r\n */\r\ntype ErrorHandler = (response: OceanetApiResponse) => void | never;\r\n\r\n/**\r\n * API 错误处理器\r\n * 负责处理 Oceanet API 的业务错误码\r\n */\r\nexport class ApiErrorHandler {\r\n private errorHandlers: Map<number, ErrorHandler> = new Map();\r\n\r\n constructor() {\r\n // 注册默认错误处理器\r\n this.registerDefaultHandlers();\r\n }\r\n\r\n /**\r\n * 注册默认的 Oceanet 错误处理器\r\n */\r\n private registerDefaultHandlers(): void {\r\n // 9913 = token 不存在或已失效\r\n this.register(9913, (response) => {\r\n const error = new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Token expired or invalid',\r\n true // 可重试\r\n );\r\n throw error;\r\n });\r\n\r\n // 9909 = 没有访问权限\r\n this.register(9909, (response) => {\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Access denied',\r\n false\r\n );\r\n });\r\n\r\n // 9914 = refresh_token 过期,需重新登录\r\n this.register(9914, (response) => {\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Session expired, please login again',\r\n false\r\n );\r\n });\r\n\r\n // 其他认证错误\r\n [401, 403].forEach(code => {\r\n this.register(code, (response) => {\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Authentication failed',\r\n code === 401 // 401 可以尝试刷新 token\r\n );\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * 注册错误处理器\r\n * @param code 错误码\r\n * @param handler 处理函数\r\n */\r\n register(code: number, handler: ErrorHandler): void {\r\n this.errorHandlers.set(code, handler);\r\n }\r\n\r\n /**\r\n * 处理 API 响应\r\n * @param response API 响应\r\n * @throws {ApiError} 当响应包含错误时\r\n */\r\n handle(response: OceanetApiResponse): void {\r\n if (response.code !== 200) {\r\n const handler = this.errorHandlers.get(response.code);\r\n\r\n if (handler) {\r\n handler(response);\r\n }\r\n\r\n // 没有特定处理器,使用默认处理(优先级:msg > errorMsg > message)\r\n throw new ApiError(\r\n response.code,\r\n response.msg || response.errorMsg || response.message || 'Unknown API error'\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * 检查响应是否为错误\r\n * @param response API 响应\r\n * @returns 是否为错误\r\n */\r\n isError(response: OceanetApiResponse): boolean {\r\n return response.code !== 200;\r\n }\r\n\r\n /**\r\n * 尝试从错误中恢复\r\n * @param error 错误对象\r\n * @param recoverFunction 恢复函数\r\n * @returns 恢复结果或抛出错误\r\n */\r\n async tryRecover<T>(\r\n error: unknown,\r\n recoverFunction: () => Promise<T>\r\n ): Promise<T> {\r\n if (error instanceof ApiError && error.retryable) {\r\n console.log('');\r\n console.log(chalk.yellow('⚠ Token expired, attempting refresh...'));\r\n try {\r\n return await recoverFunction();\r\n } catch (refreshError: any) {\r\n console.log('');\r\n console.log(chalk.yellow('⚠ Auto-refresh failed:'), chalk.dim(refreshError.message));\r\n throw new ApiError(\r\n error.code,\r\n `${error.message} (Auto-refresh failed)`\r\n );\r\n }\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * 获取全局错误处理器实例\r\n */\r\nlet errorHandlerInstance: ApiErrorHandler | null = null;\r\n\r\nexport function getApiErrorHandler(): ApiErrorHandler {\r\n if (!errorHandlerInstance) {\r\n errorHandlerInstance = new ApiErrorHandler();\r\n }\r\n return errorHandlerInstance;\r\n}\r\n","/**\r\n * HTTP 拦截器 - Token 刷新和 401 重试逻辑\r\n * 使用 ts-retoken 实现\r\n */\r\n\r\nimport { createRetoken } from 'ts-retoken';\r\nimport { getOceanetConfig } from '../../config/oceanet.js';\r\nimport type { Tokens } from '../../types/oceanet.js';\r\nimport type { ICredentialStore } from '../../providers/credential-store.js';\r\nimport type { ITokenCache } from '../auth/token-cache.js';\r\n\r\nfunction createFetchWithTimeout(timeoutMs: number) {\r\n return async (url: string, options: any = {}) => {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: controller.signal,\r\n });\r\n clearTimeout(timeoutId);\r\n return response;\r\n } catch (error: unknown) {\r\n clearTimeout(timeoutId);\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n throw new Error(`Request timeout after ${timeoutMs}ms`);\r\n }\r\n throw error;\r\n }\r\n };\r\n}\r\n\r\nexport function createRetokenInstance(\r\n credentialStore?: ICredentialStore,\r\n tokenCache?: ITokenCache\r\n) {\r\n const config = getOceanetConfig();\r\n\r\n const store = credentialStore || (require('../../providers/credential-store.js').getCredentialStore());\r\n const cache = tokenCache || (require('../auth/token-cache.js').getGlobalTokenCache());\r\n\r\n return createRetoken({\r\n refreshEndpoint: {\r\n url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,\r\n method: 'POST',\r\n buildBody: (token) => JSON.stringify({ param: token }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n parseResponse: (data: any) => {\r\n if (config.DEBUG || (global as any).__debugMode) {\r\n console.log('');\r\n console.log('=== HTTP Request ===');\r\n console.log(`POST ${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`);\r\n console.log('Headers:');\r\n console.log(' Content-Type: application/json');\r\n console.log('Body:');\r\n const refreshToken = cache.getRefreshToken();\r\n const truncated = refreshToken && refreshToken.length > 50\r\n ? refreshToken.substring(0, 50) + '...'\r\n : refreshToken || '(none)';\r\n console.log(` {\"param\":\"${truncated}\"}`);\r\n console.log('');\r\n console.log('=== HTTP Response ===');\r\n console.log(JSON.stringify(data, null, 2));\r\n console.log('');\r\n }\r\n\r\n if (data.code === 401 || data.code === 403) {\r\n const error: any = new Error(data.message || 'Refresh token expired or invalid');\r\n error.code = data.code;\r\n error.isAuthFailure = true;\r\n throw error;\r\n }\r\n\r\n const result = data.result || data;\r\n\r\n if (!result.access_token && !result.accessToken) {\r\n throw new Error('Invalid token response: missing access_token field');\r\n }\r\n if (!result.refresh_token && !result.refreshToken) {\r\n throw new Error('Invalid token response: missing refresh_token field');\r\n }\r\n\r\n return {\r\n accessToken: result.access_token || result.accessToken,\r\n refreshToken: result.refresh_token || result.refreshToken,\r\n ...(result.yst_access_token ? { ystAccessToken: result.yst_access_token } : {}),\r\n ...(result.yst_refresh_token ? { ystRefreshToken: result.yst_refresh_token } : {}),\r\n };\r\n },\r\n },\r\n getAccessToken: () => {\r\n return cache.getAccessToken();\r\n },\r\n getRefreshToken: () => {\r\n return cache.getRefreshToken();\r\n },\r\n setTokens: (tokens: Tokens) => {\r\n const accessToken = tokens?.accessToken;\r\n const refreshToken = tokens?.refreshToken;\r\n\r\n if (!accessToken || !refreshToken) {\r\n throw new Error('Invalid tokens: missing access_token or refresh_token');\r\n }\r\n\r\n const cfg = getOceanetConfig();\r\n\r\n cache.setTokens(\r\n accessToken,\r\n refreshToken,\r\n tokens?.ystAccessToken ?? null,\r\n tokens?.ystRefreshToken ?? null\r\n );\r\n\r\n void Promise.all([\r\n store.setPassword(cfg.SERVICE_NAME, 'access_token', accessToken),\r\n store.setPassword(cfg.SERVICE_NAME, 'refresh_token', refreshToken),\r\n ...(tokens?.ystAccessToken ? [store.setPassword(cfg.SERVICE_NAME, 'yst_access_token', tokens.ystAccessToken)] : []),\r\n ...(tokens?.ystRefreshToken ? [store.setPassword(cfg.SERVICE_NAME, 'yst_refresh_token', tokens.ystRefreshToken)] : []),\r\n ]).catch((error) => {\r\n if (cfg.DEBUG || (global as any).__debugMode) {\r\n console.log('');\r\n console.log('=== Token Persist Failed ===');\r\n console.log(error?.message || String(error));\r\n console.log('');\r\n }\r\n });\r\n\r\n if (cfg.DEBUG || (global as any).__debugMode) {\r\n console.log('');\r\n console.log('=== Token Saved ===');\r\n console.log('Access token saved (length:', accessToken.length, ')');\r\n console.log('Refresh token saved (length:', refreshToken.length, ')');\r\n if (tokens?.ystAccessToken) {\r\n console.log('YST access token saved (length:', tokens.ystAccessToken.length, ')');\r\n }\r\n if (tokens?.ystRefreshToken) {\r\n console.log('YST refresh token saved (length:', tokens.ystRefreshToken.length, ')');\r\n }\r\n console.log('');\r\n }\r\n },\r\n clearTokens: async () => {\r\n const cfg = getOceanetConfig();\r\n await Promise.all([\r\n store.deletePassword(cfg.SERVICE_NAME, 'access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'refresh_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n cache.clear();\r\n },\r\n expirationLeeway: 60,\r\n retryStatuses: [401],\r\n onAuthFailure: async () => {\r\n const cfg = getOceanetConfig();\r\n try {\r\n await Promise.all([\r\n store.deletePassword(cfg.SERVICE_NAME, 'access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'refresh_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_access_token'),\r\n store.deletePassword(cfg.SERVICE_NAME, 'yst_refresh_token'),\r\n ]);\r\n cache.clear();\r\n } catch {\r\n // 忽略清除错误\r\n }\r\n },\r\n });\r\n}\r\n\r\nconst retokenInstances: Record<string, ReturnType<typeof createRetokenInstance>> = {};\r\n\r\nexport function getRetoken() {\r\n const config = getOceanetConfig();\r\n const env = config.ENVIRONMENT;\r\n\r\n if (!retokenInstances[env]) {\r\n retokenInstances[env] = createRetokenInstance();\r\n }\r\n\r\n return retokenInstances[env];\r\n}\r\n","/**\r\n * HTTP 测试命令\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport ora from 'ora';\r\nimport chalk from 'chalk';\r\nimport { getClient } from '../core/http/client.js';\r\nimport { getAccessToken, getYstAccessToken } from '../core/auth/token-manager.js';\r\nimport { OCEANET_CONFIG } from '../config/oceanet.js';\r\nimport { debugRequest } from '../utils/debug.js';\r\nimport { ConfigFileError } from '../config/errors/config-file-error.js';\r\nimport { ApiError } from '../core/http/api-error-handler.js';\r\n\r\ninterface RequestOptions {\r\n baseUrl?: string;\r\n headers: string[];\r\n data?: string;\r\n params?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * 修复 Git Bash 路径转换问题\r\n */\r\nfunction fixGitBashPath(url: string): string {\r\n if (url.includes(':') && !url.startsWith('http')) {\r\n const oceanetIndex = url.indexOf('/oceanet-');\r\n if (oceanetIndex >= 0) {\r\n return url.substring(oceanetIndex);\r\n }\r\n }\r\n return url;\r\n}\r\n\r\n/**\r\n * 解析自定义头\r\n */\r\nfunction parseHeaders(headers: string[]): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n if (Array.isArray(headers)) {\r\n for (const h of headers) {\r\n const [key, ...valueParts] = h.split(':');\r\n if (key && valueParts.length > 0) {\r\n result[key.trim()] = valueParts.join(':').trim();\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * 构建完整 URL\r\n */\r\nfunction buildUrl(url: string, baseUrl?: string): string {\r\n const cleanUrl = fixGitBashPath(url);\r\n if (cleanUrl.startsWith('http')) {\r\n return cleanUrl;\r\n }\r\n const config = OCEANET_CONFIG();\r\n const base = baseUrl || config.API_BASE_URL;\r\n return `${base}${cleanUrl}`;\r\n}\r\n\r\n/**\r\n * 解析查询参数\r\n */\r\nfunction parseParams(params?: Record<string, string>): string {\r\n if (!params || Object.keys(params).length === 0) {\r\n return '';\r\n }\r\n const searchParams = new URLSearchParams();\r\n for (const [key, value] of Object.entries(params)) {\r\n searchParams.append(key, value);\r\n }\r\n return `?${searchParams.toString()}`;\r\n}\r\n\r\n/**\r\n * 执行 HTTP 请求(使用 AuthenticatingHttpClient)\r\n */\r\nasync function executeRequest(\r\n method: string,\r\n url: string,\r\n options: RequestOptions\r\n): Promise<void> {\r\n const spinner = ora('Sending request...').start();\r\n\r\n try {\r\n // 检查是否已认证\r\n const accessToken = await getAccessToken();\r\n if (!accessToken) {\r\n spinner.fail('Not authenticated');\r\n console.error(chalk.red('Please run: wukong-cli auth login'));\r\n process.exit(1);\r\n }\r\n\r\n // 构建完整 URL\r\n const fullUrl = buildUrl(url, options.baseUrl);\r\n\r\n // 解析自定义头\r\n const customHeaders = parseHeaders(options.headers);\r\n\r\n // 解析请求数据\r\n const requestData = options.data ? JSON.parse(options.data) : undefined;\r\n\r\n // 检测是否为 YST 接口(路径包含 /yst-)\r\n const isYstRequest = fullUrl.includes('/yst-');\r\n\r\n if (isYstRequest) {\r\n const ystAccessToken = await getYstAccessToken();\r\n if (!ystAccessToken) {\r\n spinner.fail('YST token not available');\r\n console.error(chalk.red('YST token not found. Please re-login: wukong-cli auth login'));\r\n process.exit(1);\r\n }\r\n\r\n spinner.text = `${method} ${chalk.cyan(fullUrl)} (using YST token)`;\r\n\r\n const startTime = Date.now();\r\n\r\n const fetchOptions: RequestInit = {\r\n method: method.toUpperCase(),\r\n headers: {\r\n 'Authorization': `Bearer ${ystAccessToken}`,\r\n 'Content-Type': 'application/json',\r\n ...customHeaders,\r\n },\r\n };\r\n\r\n if (requestData) {\r\n fetchOptions.body = JSON.stringify(requestData);\r\n }\r\n\r\n const response = await fetch(fullUrl + parseParams(options.params), fetchOptions);\r\n const duration = Date.now() - startTime;\r\n\r\n if (!response.ok) {\r\n const errText = await response.text().catch(() => '');\r\n spinner.fail(`Request failed (${response.status})`);\r\n console.error(chalk.red(`HTTP ${response.status}: ${errText.substring(0, 200)}`));\r\n process.exit(1);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n spinner.succeed('Response received');\r\n console.log('');\r\n console.log(chalk.dim('Status:'), `${response.status} ${response.statusText}`);\r\n console.log(chalk.dim('Token:'), 'YST');\r\n console.log(chalk.dim('Duration:'), `${duration}ms`);\r\n console.log('');\r\n console.log(chalk.dim('Response:'));\r\n console.log(JSON.stringify(data, null, 2));\r\n return;\r\n }\r\n\r\n // 使用 OceanetClient(自动处理token刷新)\r\n const client = getClient();\r\n\r\n spinner.text = `${method} ${chalk.cyan(fullUrl)}`;\r\n\r\n const startTime = Date.now();\r\n\r\n let data: any;\r\n\r\n // 根据方法调用相应的客户端方法\r\n switch (method.toUpperCase()) {\r\n case 'GET':\r\n const getUrl = fullUrl + parseParams(options.params);\r\n data = await client.get(getUrl);\r\n break;\r\n\r\n case 'POST':\r\n data = await client.post(fullUrl, requestData, customHeaders);\r\n break;\r\n\r\n case 'PUT':\r\n data = await client.put(fullUrl, requestData, customHeaders);\r\n break;\r\n\r\n case 'DELETE':\r\n data = await client.delete(fullUrl);\r\n break;\r\n\r\n case 'PATCH':\r\n data = await client.patch(fullUrl, requestData, customHeaders);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unsupported method: ${method}`);\r\n }\r\n\r\n const duration = Date.now() - startTime;\r\n\r\n spinner.succeed('Response received');\r\n\r\n // 显示响应\r\n console.log('');\r\n console.log(chalk.dim('Status:'), '200 OK');\r\n console.log('');\r\n console.log(chalk.dim('Response:'));\r\n console.log(JSON.stringify(data, null, 2));\r\n\r\n } catch (error) {\r\n spinner.fail('Request failed');\r\n\r\n // Handle ConfigFileError with structured error messages\r\n if (error instanceof ConfigFileError) {\r\n console.log('');\r\n console.log(chalk.red(`[ERROR] Configuration Error`));\r\n console.log('');\r\n console.log(chalk.red(error.toUserMessage()));\r\n console.log('');\r\n process.exit(1);\r\n }\r\n\r\n // Handle ApiError with code and message\r\n if (error instanceof ApiError) {\r\n console.log('');\r\n console.log(chalk.red(`API Error (code: ${error.code})`));\r\n console.log(chalk.red(error.message));\r\n console.log('');\r\n process.exit(1);\r\n }\r\n\r\n // Handle other errors\r\n if (error instanceof Error) {\r\n console.error(chalk.red(error.message));\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n\r\nexport const httpCommand = new Command('http');\r\n\r\nhttpCommand.description('HTTP commands for making API requests');\r\n\r\n// GET 请求\r\nhttpCommand\r\n .command('get <url>')\r\n .description('Send GET request (uses configured base URL or override with -b)')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('GET', url, options);\r\n });\r\n\r\n// POST 请求\r\nhttpCommand\r\n .command('post <url>')\r\n .description('Send POST request with JSON data')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .option('-d, --data <json>', 'Request body as JSON string')\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('POST', url, options);\r\n });\r\n\r\n// PUT 请求\r\nhttpCommand\r\n .command('put <url>')\r\n .description('Send PUT request with JSON data')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .option('-d, --data <json>', 'Request body as JSON string')\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('PUT', url, options);\r\n });\r\n\r\n// PATCH 请求\r\nhttpCommand\r\n .command('patch <url>')\r\n .description('Send PATCH request with JSON data')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .option('-d, --data <json>', 'Request body as JSON string')\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('PATCH', url, options);\r\n });\r\n\r\n// DELETE 请求\r\nhttpCommand\r\n .command('delete <url>')\r\n .description('Send DELETE request')\r\n .option('-b, --base-url <url>', 'Override base URL')\r\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\r\n .action(async (url: string, options: RequestOptions) => {\r\n await executeRequest('DELETE', url, options);\r\n });\r\n","/**\n * Init Command\n * 重新生成配置文件\n */\n\nimport { Command } from 'commander';\nimport { writeFileSync, existsSync, readFileSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport chalk from 'chalk';\n\n// 配置文件目录\nconst CONFIG_DIR = join(homedir(), '.wukong-cli');\n// 配置文件路径\nconst CONFIG_FILE_PATH = join(CONFIG_DIR, 'wukong-cli.json');\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 * 确保配置目录存在\n */\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\n/**\n * 执行init命令\n */\nexport async function executeInit(): Promise<void> {\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 ensureConfigDir();\n\n // 读取模板文件\n const templateContent = readFileSync(templatePath, 'utf-8');\n\n // 检查是否覆盖现有文件\n const configExists = existsSync(CONFIG_FILE_PATH);\n if (configExists) {\n console.log(chalk.yellow('⚠️ Existing configuration file will be overwritten'));\n }\n\n // 写入配置文件\n writeFileSync(CONFIG_FILE_PATH, templateContent, 'utf-8');\n\n console.log(chalk.green('✅ Configuration file created successfully'));\n console.log(chalk.gray(`Location: ${CONFIG_FILE_PATH}`));\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/wukong-cli.json)')\n .action(async () => {\n await executeInit();\n });\n","/**\n * Update command - update wukong-cli through npm global install.\n */\n\nimport { Command } from 'commander';\nimport { NpmUpdater, type IUpdater } from '../core/update/npm-updater.js';\nimport {\n compareVersions,\n describeVersionComparison,\n NpmVersionProvider,\n type IVersionProvider,\n} from '../utils/version/index.js';\n\nconst MANUAL_UPDATE_COMMAND = 'npm install -g @zrhsh/wukong-cli@latest';\n\nexport interface CommandOutput {\n log(message: string): void;\n error(message: string): void;\n}\n\nexport interface RunUpdateCommandOptions {\n currentVersion: string;\n versionProvider: IVersionProvider;\n updater: IUpdater;\n output: CommandOutput;\n}\n\nexport async function runUpdateCommand({\n currentVersion,\n versionProvider,\n updater,\n output,\n}: RunUpdateCommandOptions): Promise<number> {\n const latestVersion = await versionProvider.getLatestVersion();\n\n if (!latestVersion) {\n output.error('Unable to fetch latest version from npm registry.');\n output.error(`Manual update: ${MANUAL_UPDATE_COMMAND}`);\n return 1;\n }\n\n output.log(`Current version: ${currentVersion}`);\n output.log(`Latest version: ${latestVersion}`);\n output.log(\n `Compare result: ${describeVersionComparison(currentVersion, latestVersion)}`\n );\n\n const comparison = compareVersions(currentVersion, latestVersion);\n\n if (comparison === 0) {\n output.log('Already up to date.');\n return 0;\n }\n\n if (comparison > 0) {\n output.log('Skip update (current version is newer)');\n return 0;\n }\n\n output.log('Updating wukong-cli...');\n\n try {\n await updater.updateToLatest();\n output.log('Update completed successfully!');\n output.log(`Updated from ${currentVersion} to ${latestVersion}`);\n output.log('Run: wukong-cli --version to verify.');\n return 0;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n output.error('Update failed!');\n output.error(message);\n output.error('');\n output.error(`Manual update: ${MANUAL_UPDATE_COMMAND}`);\n return 1;\n }\n}\n\nexport const updateCommand = new Command('update')\n .description('Update wukong-cli to the latest npm version')\n .action(async () => {\n const exitCode = await runUpdateCommand({\n currentVersion: CLI_VERSION,\n versionProvider: new NpmVersionProvider(\n '@zrhsh/wukong-cli',\n 'https://registry.npmjs.org'\n ),\n updater: new NpmUpdater(),\n output: console,\n });\n\n if (exitCode !== 0) {\n process.exitCode = exitCode;\n }\n });\n","/**\n * NPM updater for globally installed wukong-cli.\n */\n\nimport { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { platform } from 'node:process';\n\nexport interface IUpdater {\n updateToLatest(): Promise<void>;\n}\n\nexport class UpdateExecutionError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number | null = null\n ) {\n super(message);\n this.name = 'UpdateExecutionError';\n }\n}\n\ntype SpawnFunction = typeof spawn;\n\nexport class NpmUpdater implements IUpdater {\n constructor(private readonly spawnFn: SpawnFunction = spawn) {}\n\n private getSpawnOptions() {\n // On Windows, npm is a batch file (npm.cmd), so we need shell: true\n // to properly execute it. This is safe for our controlled use case.\n return platform === 'win32'\n ? { shell: true, stdio: ['ignore', 'pipe', 'pipe'] as const }\n : { stdio: ['ignore', 'pipe', 'pipe'] as const };\n }\n\n updateToLatest(): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = this.spawnFn(\n 'npm',\n [\n 'install',\n '-g',\n '@zrhsh/wukong-cli@latest',\n '--loglevel=error', // Only show errors\n '--no-audit', // Disable audit report\n '--no-fund', // Disable funding message\n ],\n this.getSpawnOptions()\n ) as ChildProcess;\n\n // Capture output instead of piping directly\n let stderr = '';\n\n child.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n child.on('error', (error) => {\n reject(\n new UpdateExecutionError(\n `Failed to start npm: ${error.message}`,\n null\n )\n );\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n // Only show relevant error information\n const errorMessage = stderr.trim()\n ? `npm install failed: ${stderr.trim()}`\n : `npm install failed with exit code ${code}`;\n\n reject(new UpdateExecutionError(errorMessage, code));\n });\n });\n }\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","mkdirSync","join","dirname","homedir","fileURLToPath","require","writeFileSync","readFileSync","existsSync","mkdirSync","join","homedir","Command","chalk","chalk","ora","chalk","getDeviceFlowService","OraUICallbacks","ora","getCredentialStore","getGlobalTokenCache","url","chalk","getGlobalTokenCache","currentEnv","chalk","ora","decodeJwt","Command","ora","chalk","buildUrl","ora","chalk","startTime","duration","data","Command","Command","writeFileSync","existsSync","readFileSync","mkdirSync","join","dirname","homedir","fileURLToPath","chalk","CONFIG_DIR","CONFIG_FILE_PATH","getProjectRoot","ensureConfigDir","Command","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zrhsh/wukong-cli",
3
- "version": "0.4.15",
3
+ "version": "0.4.16",
4
4
  "description": "Wukong CLI - TypeScript with auto token refresh",
5
5
  "private": false,
6
6
  "type": "module",