@round2ai/r2-cli 1.0.1 → 1.0.3

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/index.js CHANGED
@@ -1,236 +1,848 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from "commander";
2
+
3
+ // src/index.ts
4
+ import { Command as Command8 } from "commander";
3
5
  import fse from "fs-extra";
4
- import path from "node:path";
5
- import chalk from "chalk";
6
- import inquirer from "inquirer";
6
+ import path2 from "node:path";
7
+ import chalk8 from "chalk";
7
8
  import figlet from "figlet";
8
- // 显示欢迎信息
9
- console.log(chalk.cyan(figlet.textSync("R2-CLI,向 AI 开放二手潮奢交易全链路能力", {
10
- font: "Standard",
11
- horizontalLayout: "full",
12
- })));
13
- const pkgJson = fse.readJSONSync(path.join(import.meta.dirname, "../package.json"));
14
- const program = new Command();
15
- // 当前版本号
16
- program.name("r2").description("R2-CLI,向 AI 开放二手潮奢交易全链路能力").version(pkgJson.version, "-v, --version");
17
- // auth 命令
18
- const authCommand = program.command("auth").description("授权管理");
19
- authCommand
20
- .command("login")
21
- .description("登录 Round2AI 账户")
22
- .action(async () => {
23
- const answers = await inquirer.prompt([
24
- {
25
- type: "input",
26
- name: "username",
27
- message: "请输入用户名:",
28
- validate: (input) => input.trim() !== "",
29
- },
30
- {
31
- type: "password",
32
- name: "password",
33
- message: "请输入密码:",
34
- validate: (input) => input.trim() !== "",
35
- },
36
- ]);
37
- console.log(chalk.green("登录成功!"));
38
- console.log(chalk.blue(`欢迎回来,${answers.username}!`));
39
- });
40
- // 数据对接命令
41
- program
42
- .command("ingest")
43
- .description("对接主流 ERP,统一多渠道经营数据")
44
- .action(() => {
45
- console.log(chalk.blue("正在对接 ERP 数据..."));
46
- console.log(chalk.green("✅ 已对接线上电商数据"));
47
- console.log(chalk.green("✅ 已对接线下门店数据"));
48
- console.log(chalk.green("✅ 已对接仓储履约数据"));
49
- console.log(chalk.blue("数据对接完成!"));
50
- });
51
- // 经营分析命令
52
- const reportCommand = program.command("report").description("生成经营日报/周报");
53
- reportCommand.option("--type <type>", "报告类型: daily, weekly", "daily").action((options) => {
54
- console.log(chalk.blue(`生成${options.type === "daily" ? "日报" : "周报"}...`));
55
- console.log(chalk.green("📊 销售数据"));
56
- console.log(chalk.green("📈 毛利分析"));
57
- console.log(chalk.green("⏰ 库龄分析"));
58
- console.log(chalk.green("⚠️ 异常波动"));
59
- console.log(chalk.blue(`${options.type === "daily" ? "日报" : "周报"}生成完成!`));
60
- });
61
- program
62
- .command("ask")
63
- .description("自然语言查询经营数据")
64
- .action(async () => {
65
- const { question } = await inquirer.prompt([
66
- {
67
- type: "input",
68
- name: "question",
69
- message: "请输入您的问题:",
70
- validate: (input) => input.trim() !== "",
9
+
10
+ // src/commands/setup.ts
11
+ import "commander";
12
+ import chalk7 from "chalk";
13
+
14
+ // src/commands/auth/login.ts
15
+ import { Command } from "commander";
16
+ import chalk from "chalk";
17
+
18
+ // src/query/executor.ts
19
+ async function* executePollingQuery(query, options) {
20
+ const { interval, timeout, condition, onProgress } = options;
21
+ const startTime = Date.now();
22
+ yield {
23
+ type: "start",
24
+ message: `\u5F00\u59CB\u8F6E\u8BE2: ${query.description}`,
25
+ timestamp: startTime
26
+ };
27
+ let attempts = 0;
28
+ let lastData = null;
29
+ while (Date.now() - startTime < timeout) {
30
+ attempts++;
31
+ if (query.deps.signal?.aborted) {
32
+ throw new Error("\u67E5\u8BE2\u88AB\u4E2D\u6B62");
33
+ }
34
+ try {
35
+ const data = await query.execute(query.deps);
36
+ lastData = data;
37
+ const progress = Math.min(
38
+ Math.floor((Date.now() - startTime) / timeout * 100),
39
+ 99
40
+ );
41
+ onProgress?.(progress, `\u8F6E\u8BE2\u4E2D... (\u7B2C ${attempts} \u6B21)`);
42
+ yield {
43
+ type: "update",
44
+ message: `\u8F6E\u8BE2\u4E2D... (\u7B2C ${attempts} \u6B21)`,
45
+ progress,
46
+ timestamp: Date.now()
47
+ };
48
+ if (condition(data)) {
49
+ const duration = Date.now() - startTime;
50
+ yield {
51
+ type: "complete",
52
+ message: `\u8F6E\u8BE2\u5B8C\u6210 (\u5171 ${attempts} \u6B21)`,
53
+ progress: 100,
54
+ timestamp: Date.now()
55
+ };
56
+ return {
57
+ data,
58
+ metadata: {
59
+ duration,
60
+ success: true,
61
+ attempts
62
+ }
63
+ };
64
+ }
65
+ } catch (error) {
66
+ const errorMessage = error instanceof Error ? error.message : String(error);
67
+ yield {
68
+ type: "error",
69
+ message: `\u8F6E\u8BE2\u9519\u8BEF: ${errorMessage}`,
70
+ timestamp: Date.now()
71
+ };
72
+ throw error;
73
+ }
74
+ await sleep(interval);
75
+ }
76
+ throw new Error(
77
+ `\u8F6E\u8BE2\u8D85\u65F6: ${query.description} (\u5DF2\u7B49\u5F85 ${timeout}ms, \u5171 ${attempts} \u6B21)`
78
+ );
79
+ }
80
+ function sleep(ms) {
81
+ return new Promise((resolve) => setTimeout(resolve, ms));
82
+ }
83
+
84
+ // src/errors/index.ts
85
+ var R2Error = class _R2Error extends Error {
86
+ constructor(message, code, details) {
87
+ super(message);
88
+ this.code = code;
89
+ this.details = details;
90
+ this.name = "R2Error";
91
+ if (Error.captureStackTrace) {
92
+ Error.captureStackTrace(this, _R2Error);
93
+ }
94
+ }
95
+ code;
96
+ details;
97
+ };
98
+ var ApiError = class extends R2Error {
99
+ constructor(message, status, response) {
100
+ super(message, "API_ERROR", response);
101
+ this.status = status;
102
+ this.response = response;
103
+ this.name = "ApiError";
104
+ }
105
+ status;
106
+ response;
107
+ };
108
+ var StorageError = class extends R2Error {
109
+ constructor(message, path3, code) {
110
+ super(message, "STORAGE_ERROR", { path: path3, code });
111
+ this.path = path3;
112
+ this.code = code;
113
+ this.name = "StorageError";
114
+ }
115
+ path;
116
+ code;
117
+ };
118
+ var AuthError = class extends R2Error {
119
+ constructor(message) {
120
+ super(message, "AUTH_ERROR");
121
+ this.name = "AuthError";
122
+ }
123
+ };
124
+ var PollingError = class extends R2Error {
125
+ constructor(message, attempts, timeout) {
126
+ super(message, "POLLING_ERROR", { attempts, timeout });
127
+ this.attempts = attempts;
128
+ this.timeout = timeout;
129
+ this.name = "PollingError";
130
+ }
131
+ attempts;
132
+ timeout;
133
+ };
134
+
135
+ // src/services/api/api-client.service.ts
136
+ var R2_API_URL = "https://api.puresnake.com";
137
+ var ApiClientService = class {
138
+ config;
139
+ token = null;
140
+ constructor(config = {}) {
141
+ this.config = {
142
+ baseUrl: config.baseUrl ?? R2_API_URL,
143
+ version: config.version ?? "v3",
144
+ debug: config.debug ?? false
145
+ };
146
+ console.log("this.config", this.config);
147
+ }
148
+ /**
149
+ * 设置认证令牌
150
+ */
151
+ setToken(token) {
152
+ this.token = token;
153
+ }
154
+ /**
155
+ * 获取认证令牌
156
+ */
157
+ getToken() {
158
+ return this.token;
159
+ }
160
+ /**
161
+ * 构建 URL
162
+ */
163
+ buildUrl(path3) {
164
+ const cleanPath = path3.startsWith("/") ? path3.slice(1) : path3;
165
+ return `${this.config.baseUrl}/${this.config.version}/${cleanPath}`;
166
+ }
167
+ /**
168
+ * 构建 HTTP 头
169
+ */
170
+ buildHeaders() {
171
+ const headers = {
172
+ "Content-Type": "application/json"
173
+ };
174
+ if (this.token) {
175
+ headers["token"] = this.token;
176
+ }
177
+ return headers;
178
+ }
179
+ /**
180
+ * 处理响应
181
+ */
182
+ async handleResponse(response) {
183
+ if (!response.ok) {
184
+ const errorText = await response.text();
185
+ throw new ApiError(`HTTP ${response.status}: ${response.statusText} - ${errorText}`, response.status);
186
+ }
187
+ const result = await response.json();
188
+ if (this.config.debug) {
189
+ console.log("[API Response]", result);
190
+ }
191
+ if (!result.success || result.status !== 0) {
192
+ throw new ApiError(`API Error: status=${result.status}, success=${result.success}, message=${result.msg}`, void 0, result);
193
+ }
194
+ return result.data;
195
+ }
196
+ /**
197
+ * 执行请求
198
+ */
199
+ async request(path3, config) {
200
+ const url = this.buildUrl(path3);
201
+ const { method, headers, body } = config;
202
+ const init = {
203
+ method,
204
+ headers: { ...this.buildHeaders(), ...headers }
205
+ };
206
+ if (body !== void 0) {
207
+ init.body = JSON.stringify(body);
208
+ }
209
+ if (this.config.debug) {
210
+ console.log(`[API ${method}]`, url, body);
211
+ }
212
+ const response = await fetch(url, init);
213
+ return this.handleResponse(response);
214
+ }
215
+ /**
216
+ * GET 请求
217
+ */
218
+ async get(path3, params) {
219
+ let url = this.buildUrl(path3);
220
+ if (params && params.size > 0) {
221
+ url += `?${params.toString()}`;
222
+ }
223
+ const init = {
224
+ method: "GET",
225
+ headers: this.buildHeaders()
226
+ };
227
+ if (this.config.debug) {
228
+ console.log(`[API GET]`, url);
229
+ }
230
+ const response = await fetch(url, init);
231
+ return this.handleResponse(response);
232
+ }
233
+ /**
234
+ * POST 请求
235
+ */
236
+ async post(path3, body) {
237
+ const config = { method: "POST", body };
238
+ return this.request(path3, config);
239
+ }
240
+ /**
241
+ * PUT 请求
242
+ */
243
+ async put(path3, body) {
244
+ const config = { method: "PUT", body };
245
+ return this.request(path3, config);
246
+ }
247
+ /**
248
+ * DELETE 请求
249
+ */
250
+ async delete(path3) {
251
+ const config = { method: "DELETE" };
252
+ return this.request(path3, config);
253
+ }
254
+ };
255
+ var QRCodeAuthApiService = class {
256
+ client;
257
+ constructor(client) {
258
+ this.client = client;
259
+ }
260
+ /**
261
+ * 生成二维码
262
+ */
263
+ async generateQRCode() {
264
+ return this.client.post("app/qrcode/generate");
265
+ }
266
+ /**
267
+ * 查询二维码状态
268
+ */
269
+ async getQRCodeStatus(qrToken) {
270
+ const params = new URLSearchParams();
271
+ params.append("qrToken", qrToken);
272
+ return this.client.get("app/qrcode/status", params);
273
+ }
274
+ /**
275
+ * 确认登录
276
+ */
277
+ async confirmLogin(qrToken) {
278
+ return this.client.post("app/qrcode/confirm", {
279
+ qrToken
280
+ });
281
+ }
282
+ };
283
+
284
+ // src/services/storage/index.ts
285
+ import { promises as fs } from "node:fs";
286
+ import path from "node:path";
287
+ import os from "node:os";
288
+ import { stat, mkdir } from "node:fs/promises";
289
+ var CONFIG_FILE_NAME = ".r2-cli";
290
+ var StorageService = class {
291
+ configPath;
292
+ config;
293
+ constructor() {
294
+ const homeDir = os.homedir();
295
+ const configDir = path.join(homeDir, CONFIG_FILE_NAME);
296
+ this.configPath = path.join(configDir, "config.json");
297
+ this.config = { credentials: null };
298
+ }
299
+ /**
300
+ * 获取配置文件路径
301
+ */
302
+ getConfigPath() {
303
+ return this.configPath;
304
+ }
305
+ /**
306
+ * 加载配置
307
+ */
308
+ async loadConfig() {
309
+ try {
310
+ const content = await fs.readFile(this.configPath, "utf-8");
311
+ const config = JSON.parse(content);
312
+ this.config = config;
313
+ return config;
314
+ } catch (error) {
315
+ if (error.code === "ENOENT") {
316
+ return { credentials: null };
317
+ }
318
+ throw new StorageError(
319
+ "Failed to load config",
320
+ this.configPath,
321
+ error.code
322
+ );
323
+ }
324
+ }
325
+ /**
326
+ * 保存配置
327
+ */
328
+ async saveConfig(config) {
329
+ this.config = config;
330
+ const content = JSON.stringify(config, null, 2);
331
+ const dirPath = path.dirname(this.configPath);
332
+ try {
333
+ await stat(dirPath);
334
+ } catch (error) {
335
+ if (error.code === "ENOENT") {
336
+ await mkdir(dirPath, { recursive: true });
337
+ } else {
338
+ throw new StorageError(
339
+ "Failed to create directory",
340
+ dirPath,
341
+ error.code
342
+ );
343
+ }
344
+ }
345
+ try {
346
+ await fs.writeFile(this.configPath, content, "utf-8");
347
+ } catch (error) {
348
+ throw new StorageError(
349
+ "Failed to save config",
350
+ this.configPath,
351
+ error.code
352
+ );
353
+ }
354
+ }
355
+ /**
356
+ * 保存登录凭证
357
+ */
358
+ async saveCredentials(token, userInfo) {
359
+ const credentials = {
360
+ token,
361
+ userInfo,
362
+ timestamp: Date.now()
363
+ };
364
+ let config;
365
+ try {
366
+ config = await this.loadConfig();
367
+ } catch (error) {
368
+ config = { credentials: null };
369
+ }
370
+ config.credentials = credentials;
371
+ await this.saveConfig(config);
372
+ }
373
+ /**
374
+ * 获取登录凭证
375
+ */
376
+ async getCredentials() {
377
+ const config = await this.loadConfig();
378
+ return config.credentials;
379
+ }
380
+ /**
381
+ * 清除登录凭证
382
+ */
383
+ async clearCredentials() {
384
+ const config = await this.loadConfig();
385
+ config.credentials = null;
386
+ await this.saveConfig(config);
387
+ }
388
+ /**
389
+ * 获取 token
390
+ */
391
+ async getToken() {
392
+ const credentials = await this.getCredentials();
393
+ return credentials?.token ?? null;
394
+ }
395
+ /**
396
+ * 获取用户信息
397
+ */
398
+ async getUserInfo() {
399
+ const credentials = await this.getCredentials();
400
+ return credentials?.userInfo ?? null;
401
+ }
402
+ /**
403
+ * 检查是否已登录
404
+ */
405
+ async isLoggedIn() {
406
+ const credentials = await this.getCredentials();
407
+ return credentials !== null;
408
+ }
409
+ };
410
+ function createStorageService() {
411
+ return new StorageService();
412
+ }
413
+
414
+ // src/commands/auth/login.ts
415
+ import { createRequire } from "node:module";
416
+ var require2 = createRequire(import.meta.url);
417
+ var qrcodeTerminal = require2("qrcode-terminal");
418
+ var LoginService = class {
419
+ authApi;
420
+ storage;
421
+ constructor(authApi, storage) {
422
+ this.authApi = authApi ?? new QRCodeAuthApiService(new ApiClientService());
423
+ this.storage = storage ?? createStorageService();
424
+ }
425
+ /**
426
+ * 执行扫码登录
427
+ */
428
+ async login(signal) {
429
+ console.log(chalk.cyan("\n\u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55..."));
430
+ const qrData = await this.authApi.generateQRCode();
431
+ console.log(chalk.green("\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\n"));
432
+ this.displayQRCode(qrData);
433
+ const query = {
434
+ id: "qrcode-status-poll",
435
+ description: "\u67E5\u8BE2\u4E8C\u7EF4\u7801\u767B\u5F55\u72B6\u6001",
436
+ deps: {
437
+ signal: signal ?? null,
438
+ uuid: () => Math.random().toString(36),
439
+ api: {
440
+ get: async (url) => {
441
+ return this.authApi.getQRCodeStatus(qrData.qrToken);
442
+ },
443
+ post: async (_url, _body) => {
444
+ throw new Error("Not implemented");
445
+ }
71
446
  },
72
- ]);
73
- console.log(chalk.blue("正在分析您的问题..."));
74
- console.log(chalk.green(`根据您的问题 "${question}",以下是分析结果:`));
75
- console.log(chalk.yellow("📊 数据结果将在此显示"));
76
- });
77
- // 市场分析命令
78
- const demandCommand = program.command("demand").description("扫描市场需求热度与供需缺口");
79
- demandCommand
80
- .option("--sku <sku>", "商品SKU")
81
- .option("--region <region>", "区域")
82
- .action((options) => {
83
- console.log(chalk.blue("正在扫描市场需求..."));
84
- console.log(chalk.green(`SKU: ${options.sku || "全部"}`));
85
- console.log(chalk.green(`区域: ${options.region || "全国"}`));
86
- console.log(chalk.yellow("🔥 需求热度: 高"));
87
- console.log(chalk.yellow("📈 供需缺口: 20%"));
88
- console.log(chalk.blue("市场需求分析完成!"));
89
- });
90
- const simulateCommand = program.command("simulate").description("竞价成交模拟");
91
- simulateCommand
92
- .option("--sku <sku>", "商品SKU")
93
- .option("--price <price>", "出价")
94
- .action((options) => {
95
- console.log(chalk.blue("正在模拟竞价成交..."));
96
- console.log(chalk.green(`SKU: ${options.sku}`));
97
- console.log(chalk.green(`出价: ¥${options.price}`));
98
- console.log(chalk.yellow("📊 预估成交率: 85%"));
99
- console.log(chalk.yellow("💰 预估利润空间: 15%"));
100
- console.log(chalk.blue("竞价模拟完成!"));
101
- });
102
- program
103
- .command("bidding-strategy")
104
- .description("基于预算与品类生成竞价策略建议")
105
- .action(() => {
106
- console.log(chalk.blue("正在生成竞价策略..."));
107
- console.log(chalk.green("🎯 策略目标: 最大化成交率"));
108
- console.log(chalk.green("💸 预算分配: 高需求品类 60%,中需求品类 30%,低需求品类 10%"));
109
- console.log(chalk.yellow("📈 建议出价区间: ¥800-¥1200"));
110
- console.log(chalk.blue("竞价策略生成完成!"));
111
- });
112
- // 价格分析命令
113
- const pricingCommand = program.command("pricing").description("基于真实成交数据给出收货价与售卖价建议");
114
- pricingCommand
115
- .option("--sku <sku>", "商品SKU")
116
- .option("--condition <condition>", "商品成色")
117
- .action((options) => {
118
- console.log(chalk.blue("正在分析价格数据..."));
119
- console.log(chalk.green(`SKU: ${options.sku}`));
120
- console.log(chalk.green(`成色: ${options.condition}`));
121
- console.log(chalk.yellow("💰 建议收货价: ¥8000"));
122
- console.log(chalk.yellow("💸 建议售卖价: ¥12000"));
123
- console.log(chalk.blue("价格分析完成!"));
124
- });
125
- program
126
- .command("sell-optimize")
127
- .description("在售商品的定价与渠道优化建议")
128
- .action(() => {
129
- console.log(chalk.blue("正在优化在售商品..."));
130
- console.log(chalk.green("📊 定价优化:"));
131
- console.log(chalk.green(" - 高需求商品: 上调 5%"));
132
- console.log(chalk.green(" - 低需求商品: 下调 10%"));
133
- console.log(chalk.green("📈 渠道优化:"));
134
- console.log(chalk.green(" - 线上电商: 60% 库存"));
135
- console.log(chalk.green(" - 线下门店: 30% 库存"));
136
- console.log(chalk.green(" - 二手平台: 10% 库存"));
137
- console.log(chalk.blue("优化建议生成完成!"));
138
- });
139
- // 库存与履约命令
140
- const inventoryCommand = program.command("inventory").description("库存管理");
141
- inventoryCommand
142
- .command("risk")
143
- .description("库存风险识别")
144
- .option("--warehouse <warehouse>", "仓库代码")
145
- .action((options) => {
146
- console.log(chalk.blue("正在识别库存风险..."));
147
- console.log(chalk.green(`仓库: ${options.warehouse || "全部"}`));
148
- console.log(chalk.yellow("⚠️ 滞销预警: 15 件商品"));
149
- console.log(chalk.yellow("📉 贬值通道: 8 件商品"));
150
- console.log(chalk.yellow("⏰ 库龄超期: 5 件商品"));
151
- console.log(chalk.blue("库存风险识别完成!"));
152
- });
153
- program
154
- .command("fulfillment")
155
- .description("履约全链路追踪")
156
- .action(() => {
157
- console.log(chalk.blue("正在追踪履约全链路..."));
158
- console.log(chalk.green("📦 收货: 完成"));
159
- console.log(chalk.green("🔍 质检: 完成"));
160
- console.log(chalk.green("🏠 入库: 完成"));
161
- console.log(chalk.green("🚚 发货: 进行中"));
162
- console.log(chalk.blue("履约追踪完成!"));
163
- });
164
- // 经营决策命令
165
- const decideCommand = program.command("decide").description("综合数据输出经营动作建议");
166
- decideCommand
167
- .option("--store <store>", "店铺代码")
168
- .option("--horizon <horizon>", "预测周期")
169
- .action((options) => {
170
- console.log(chalk.blue("正在分析经营数据..."));
171
- console.log(chalk.green(`店铺: ${options.store || "全部"}`));
172
- console.log(chalk.green(`预测周期: ${options.horizon || "7d"}`));
173
- console.log(chalk.yellow("📈 补货建议: Air Jordan 1 Retro High OG (20 双)"));
174
- console.log(chalk.yellow("📉 清仓建议: Louis Vuitton Neverfull (5 个)"));
175
- console.log(chalk.yellow("💰 调价建议: Chanel Classic Flap (上调 5%)"));
176
- console.log(chalk.yellow("⚠️ 风控建议: 加强高价值商品的质检流程"));
177
- console.log(chalk.blue("经营决策建议生成完成!"));
178
- });
179
- // AI 命令模块
180
- const aiCommand = program.command("ai").description("AI 相关功能");
181
- aiCommand
182
- .command("chat")
183
- .description("与 AI 助手聊天,获取经营建议")
184
- .action(async () => {
185
- const { message } = await inquirer.prompt([
186
- {
187
- type: "input",
188
- name: "message",
189
- message: "请输入您的问题或需求:",
190
- validate: (input) => input.trim() !== "",
447
+ log: {
448
+ info: (msg) => console.log(chalk.blue(`[INFO] ${msg}`)),
449
+ error: (msg) => console.error(chalk.red(`[ERROR] ${msg}`)),
450
+ debug: (msg) => console.log(chalk.gray(`[DEBUG] ${msg}`))
451
+ }
452
+ },
453
+ execute: async () => {
454
+ return this.authApi.getQRCodeStatus(qrData.qrToken);
455
+ },
456
+ options: {
457
+ timeout: Number.parseInt(qrData.expireTime, 10),
458
+ enableProgress: true
459
+ }
460
+ };
461
+ try {
462
+ const result = await this.pollLoginStatus(query, qrData);
463
+ if (result.data.token && result.data.userInfo) {
464
+ await this.saveCredentials(result.data.token, result.data.userInfo);
465
+ console.log(chalk.green("\n\u2705 \u767B\u5F55\u6210\u529F\uFF01\n"));
466
+ this.displayUserInfo(result.data.userInfo);
467
+ return {
468
+ userInfo: result.data.userInfo,
469
+ token: result.data.token
470
+ };
471
+ }
472
+ throw new AuthError("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1");
473
+ } catch (error) {
474
+ console.log("error", error);
475
+ console.log(chalk.red("\n\u274C \u767B\u5F55\u5931\u8D25\n"));
476
+ if (error instanceof Error) {
477
+ throw error;
478
+ }
479
+ throw new AuthError("\u767B\u5F55\u5931\u8D25: \u672A\u77E5\u9519\u8BEF");
480
+ }
481
+ }
482
+ /**
483
+ * 显示二维码
484
+ */
485
+ displayQRCode(qrData) {
486
+ console.log(chalk.yellow("\u{1F4F1} \u8BF7\u4F7F\u7528 \u7B2C\u4E8C\u56DE\u5408APP \u626B\u63CF\u4E8C\u7EF4\u7801\u767B\u5F55\n"));
487
+ qrcodeTerminal.generate(`r2://auth/login?qrToken=${qrData.qrContent}`, { small: true });
488
+ const expireTimeMs = Number.parseInt(qrData.expireTime, 10);
489
+ const pollIntervalMs = Number.parseInt(qrData.pollInterval, 10);
490
+ console.log(chalk.yellow("\n\u23F3 \u7B49\u5F85\u626B\u7801..."));
491
+ }
492
+ /**
493
+ * 轮询登录状态
494
+ */
495
+ async pollLoginStatus(query, qrData) {
496
+ let lastStatus = "waiting";
497
+ const expireTimeMs = Number.parseInt(qrData.expireTime, 10);
498
+ const pollIntervalMs = Number.parseInt(qrData.pollInterval, 10);
499
+ const pollingIterator = executePollingQuery(query, {
500
+ interval: pollIntervalMs,
501
+ timeout: expireTimeMs,
502
+ condition: (data) => {
503
+ if (data.status !== lastStatus) {
504
+ lastStatus = data.status;
505
+ switch (data.status) {
506
+ case "scanned":
507
+ console.log(chalk.cyan(`
508
+ \u{1F50D} \u5DF2\u626B\u7801: ${data.userInfo?.nickname || "\u672A\u77E5\u7528\u6237"}`));
509
+ console.log(chalk.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"));
510
+ break;
511
+ case "confirmed":
512
+ console.log(chalk.green("\n\u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55"));
513
+ break;
514
+ case "expired":
515
+ console.log(chalk.red("\n\u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F"));
516
+ break;
517
+ case "canceled":
518
+ console.log(chalk.red("\n\u{1F6AB} \u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"));
519
+ break;
520
+ }
521
+ }
522
+ return data.status === "confirmed";
523
+ }
524
+ });
525
+ let result = null;
526
+ let done = false;
527
+ while (!done) {
528
+ const { value, done: iterationDone } = await pollingIterator.next();
529
+ done = iterationDone ?? true;
530
+ if (done) {
531
+ if (value && "data" in value) {
532
+ result = { data: value.data };
533
+ }
534
+ } else {
535
+ }
536
+ }
537
+ if (result) {
538
+ return result;
539
+ }
540
+ throw new PollingError("\u8F6E\u8BE2\u5F02\u5E38\u7EC8\u6B62");
541
+ }
542
+ /**
543
+ * 显示用户信息
544
+ */
545
+ displayUserInfo(userInfo) {
546
+ console.log(chalk.white("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
547
+ console.log(chalk.cyan("\u7528\u6237\u4FE1\u606F:"));
548
+ console.log(chalk.white(" \u7528\u6237\u540D: ") + chalk.yellow(userInfo.username));
549
+ console.log(chalk.white(" \u6635\u79F0: ") + chalk.yellow(userInfo.nickname));
550
+ console.log(chalk.white(" \u624B\u673A\u53F7: ") + chalk.yellow(userInfo.mobile));
551
+ console.log(chalk.white(" \u7528\u6237ID: ") + chalk.yellow(userInfo.userId.toString()));
552
+ console.log(chalk.white("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
553
+ }
554
+ /**
555
+ * 保存登录凭证
556
+ */
557
+ async saveCredentials(token, userInfo) {
558
+ await this.storage.saveCredentials(token, userInfo);
559
+ const credentials = await this.storage.getCredentials();
560
+ }
561
+ /**
562
+ * 登出
563
+ */
564
+ async logout() {
565
+ console.log(chalk.cyan("\n\u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55..."));
566
+ await this.clearCredentials();
567
+ console.log(chalk.green("\u2705 \u5DF2\u9000\u51FA\u767B\u5F55\n"));
568
+ }
569
+ /**
570
+ * 查看登录状态
571
+ */
572
+ async status() {
573
+ console.log(chalk.cyan("\n\u{1F4CA} \u67E5\u770B\u767B\u5F55\u72B6\u6001...\n"));
574
+ const isLoggedIn = await this.storage.isLoggedIn();
575
+ if (!isLoggedIn) {
576
+ console.log(chalk.yellow("\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F\n"));
577
+ return;
578
+ }
579
+ const credentials = await this.storage.getCredentials();
580
+ const userInfo = credentials.userInfo;
581
+ const lastLogin = new Date(credentials.timestamp);
582
+ const daysSinceLogin = Math.floor((Date.now() - credentials.timestamp) / (1e3 * 60 * 60 * 24));
583
+ console.log(chalk.green("\u2705 \u5DF2\u767B\u5F55\n"));
584
+ this.displayUserInfo(userInfo);
585
+ console.log(chalk.gray("\n\u{1F4C5} \u6700\u540E\u767B\u5F55: " + lastLogin.toLocaleString()));
586
+ console.log(chalk.gray(" \u8DDD\u79BB\u4ECA\u5929: " + daysSinceLogin + " \u5929\u524D"));
587
+ }
588
+ /**
589
+ * 清除登录凭证
590
+ */
591
+ async clearCredentials() {
592
+ await this.storage.clearCredentials();
593
+ }
594
+ };
595
+ function createLoginCommand() {
596
+ const command = new Command("login");
597
+ command.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237");
598
+ command.option("--timeout <ms>", "\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09", "300000");
599
+ command.option("--debug", "\u542F\u7528\u8C03\u8BD5\u6A21\u5F0F", false);
600
+ command.action(async (options) => {
601
+ try {
602
+ const loginService = new LoginService();
603
+ const controller = new AbortController();
604
+ const timeout = setTimeout(
605
+ () => {
606
+ controller.abort();
191
607
  },
192
- ]);
193
- console.log(chalk.blue("正在与 AI 助手交流..."));
194
- console.log(chalk.green(`AI 助手: 正在分析您的需求 "${message}"`));
195
- console.log(chalk.yellow("📊 分析中..."));
196
- console.log(chalk.green("AI 助手: 基于您的需求,我建议您执行以下操作:"));
197
- console.log(chalk.green("1. 查看本周销售数据: r2 report --type weekly"));
198
- console.log(chalk.green('2. 分析热门商品: r2 demand --sku "Air Jordan 1"'));
199
- console.log(chalk.green("3. 检查库存风险: r2 inventory risk"));
200
- console.log(chalk.blue("AI 助手对话完成!"));
201
- });
202
- aiCommand
203
- .command("skills")
204
- .description("AI Agent 技能管理")
205
- .action(() => {
206
- console.log(chalk.blue("AI Agent 技能管理"));
207
- console.log(chalk.green("📚 已安装的技能:"));
208
- console.log(chalk.green(" - 经营分析技能"));
209
- console.log(chalk.green(" - 市场分析技能"));
210
- console.log(chalk.green(" - 价格分析技能"));
211
- console.log(chalk.green(" - 库存管理技能"));
212
- console.log(chalk.blue("技能管理完成!"));
213
- });
214
- // AI Agent 集成命令
215
- program
216
- .command("agent")
217
- .description("AI Agent 集成")
218
- .action(() => {
219
- console.log(chalk.blue("AI Agent 集成"));
220
- console.log(chalk.green("🔧 支持的 AI Agent 框架:"));
221
- console.log(chalk.green(" - Claude Code"));
222
- console.log(chalk.green(" - OpenClaw"));
223
- console.log(chalk.green(" - Codex"));
224
- console.log(chalk.blue("安装 Agent Skills:"));
225
- console.log(chalk.yellow("npx skills add Round2AI/r2-cli --all -y"));
226
- console.log(chalk.blue("AI Agent 集成完成!"));
227
- });
228
- // 全局错误处理
229
- program.configureOutput({
608
+ Number.parseInt(options.timeout ?? "300000", 10)
609
+ );
610
+ await loginService.login(controller.signal);
611
+ clearTimeout(timeout);
612
+ } catch (error) {
613
+ const errorMessage = error instanceof Error ? error.message : String(error);
614
+ console.error(chalk.red(`\u274C ${errorMessage}`));
615
+ process.exit(1);
616
+ }
617
+ });
618
+ return command;
619
+ }
620
+ function createLogoutCommand() {
621
+ const command = new Command("logout");
622
+ command.description("\u9000\u51FA\u767B\u5F55");
623
+ command.action(async () => {
624
+ try {
625
+ const loginService = new LoginService();
626
+ await loginService.logout();
627
+ } catch (error) {
628
+ const errorMessage = error instanceof Error ? error.message : String(error);
629
+ console.error(chalk.red(`\u274C ${errorMessage}`));
630
+ process.exit(1);
631
+ }
632
+ });
633
+ return command;
634
+ }
635
+ function createStatusCommand() {
636
+ const command = new Command("status");
637
+ command.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001");
638
+ command.action(async () => {
639
+ try {
640
+ const loginService = new LoginService();
641
+ await loginService.status();
642
+ } catch (error) {
643
+ const errorMessage = error instanceof Error ? error.message : String(error);
644
+ console.error(chalk.red(`\u274C ${errorMessage}`));
645
+ process.exit(1);
646
+ }
647
+ });
648
+ return command;
649
+ }
650
+
651
+ // src/commands/business/pricing.ts
652
+ import { Command as Command2 } from "commander";
653
+ import chalk2 from "chalk";
654
+ function createPricingCommand() {
655
+ const command = new Command2("pricing");
656
+ command.description("\u57FA\u4E8E\u771F\u5B9E\u6210\u4EA4\u6570\u636E\u7ED9\u51FA\u6536\u8D27\u4EF7\u4E0E\u552E\u5356\u4EF7\u5EFA\u8BAE");
657
+ command.option("--sku <sku>", "\u5546\u54C1SKU");
658
+ command.option("--condition <condition>", "\u5546\u54C1\u6210\u8272");
659
+ command.action((options) => {
660
+ console.log(chalk2.blue("\u6B63\u5728\u5206\u6790\u4EF7\u683C\u6570\u636E..."));
661
+ console.log(chalk2.green(`SKU: ${options.sku || "\u5168\u90E8"}`));
662
+ console.log(chalk2.green(`\u6210\u8272: ${options.condition || "\u5168\u65B0"}`));
663
+ console.log(chalk2.yellow("\u{1F4B0} \u5EFA\u8BAE\u6536\u8D27\u4EF7: \xA58000"));
664
+ console.log(chalk2.yellow("\u{1F4B8} \u5EFA\u8BAE\u552E\u5356\u4EF7: \xA512000"));
665
+ console.log(chalk2.blue("\u4EF7\u683C\u5206\u6790\u5B8C\u6210\uFF01"));
666
+ });
667
+ return command;
668
+ }
669
+
670
+ // src/commands/business/report.ts
671
+ import { Command as Command3 } from "commander";
672
+ import chalk3 from "chalk";
673
+ function createReportCommand() {
674
+ const command = new Command3("report");
675
+ command.description("\u751F\u6210\u7ECF\u8425\u65E5\u62A5/\u5468\u62A5");
676
+ command.option("--type <type>", "\u62A5\u544A\u7C7B\u578B: daily, weekly", "daily");
677
+ command.action((options) => {
678
+ console.log(chalk3.blue(`\u751F\u6210${options.type === "daily" ? "\u65E5\u62A5" : "\u5468\u62A5"}...`));
679
+ console.log(chalk3.green("\u{1F4CA} \u9500\u552E\u6570\u636E"));
680
+ console.log(chalk3.green("\u{1F4C8} \u6BDB\u5229\u5206\u6790"));
681
+ console.log(chalk3.green("\u23F0 \u5E93\u9F84\u5206\u6790"));
682
+ console.log(chalk3.green("\u26A0\uFE0F \u5F02\u5E38\u6CE2\u52A8"));
683
+ console.log(chalk3.blue(`${options.type === "daily" ? "\u65E5\u62A5" : "\u5468\u62A5"}\u751F\u6210\u5B8C\u6210\uFF01`));
684
+ });
685
+ return command;
686
+ }
687
+
688
+ // src/commands/inventory/risk.ts
689
+ import { Command as Command4 } from "commander";
690
+ import chalk4 from "chalk";
691
+ function createRiskCommand() {
692
+ const command = new Command4("risk");
693
+ command.description("\u5E93\u5B58\u98CE\u9669\u8BC6\u522B");
694
+ command.option("--warehouse <warehouse>", "\u4ED3\u5E93\u4EE3\u7801");
695
+ command.action((options) => {
696
+ console.log(chalk4.blue("\u6B63\u5728\u8BC6\u522B\u5E93\u5B58\u98CE\u9669..."));
697
+ console.log(chalk4.green(`\u4ED3\u5E93: ${options.warehouse || "\u5168\u90E8"}`));
698
+ console.log(chalk4.yellow("\u26A0\uFE0F \u6EDE\u9500\u9884\u8B66: 15 \u4EF6\u5546\u54C1"));
699
+ console.log(chalk4.yellow("\u{1F4C9} \u8D2C\u503C\u901A\u9053: 8 \u4EF6\u5546\u54C1"));
700
+ console.log(chalk4.yellow("\u23F0 \u5E93\u9F84\u8D85\u671F: 5 \u4EF6\u5546\u54C1"));
701
+ console.log(chalk4.blue("\u5E93\u5B58\u98CE\u9669\u8BC6\u522B\u5B8C\u6210\uFF01"));
702
+ });
703
+ return command;
704
+ }
705
+
706
+ // src/commands/ai/chat.ts
707
+ import { Command as Command5 } from "commander";
708
+ import chalk5 from "chalk";
709
+ function createChatCommand() {
710
+ const command = new Command5("chat");
711
+ command.description("\u4E0E AI \u52A9\u624B\u804A\u5929\uFF0C\u83B7\u53D6\u7ECF\u8425\u5EFA\u8BAE");
712
+ command.action(() => {
713
+ console.log(chalk5.blue("\u6B63\u5728\u8FDE\u63A5 AI \u52A9\u624B..."));
714
+ console.log(chalk5.green("\u2705 \u5DF2\u8FDE\u63A5 Claude AI"));
715
+ console.log(chalk5.yellow("\u{1F4AC} \u8BF7\u8F93\u5165\u60A8\u7684\u95EE\u9898..."));
716
+ console.log(chalk5.gray("\u793A\u4F8B\uFF1A\u5206\u6790\u672C\u5468\u9500\u552E\u6570\u636E"));
717
+ console.log(chalk5.blue("AI \u804A\u5929\u529F\u80FD\u5F00\u53D1\u4E2D..."));
718
+ });
719
+ return command;
720
+ }
721
+
722
+ // src/commands/ai/skills.ts
723
+ import { Command as Command6 } from "commander";
724
+ import chalk6 from "chalk";
725
+ function createSkillsCommand() {
726
+ const command = new Command6("skills");
727
+ command.description("AI Agent \u6280\u80FD\u7BA1\u7406");
728
+ command.action(() => {
729
+ console.log(chalk6.blue("AI Agent \u6280\u80FD\u7BA1\u7406"));
730
+ console.log(chalk6.green("\u{1F527} \u5DF2\u5B89\u88C5\u7684\u6280\u80FD:"));
731
+ console.log(chalk6.green(" - \u7ECF\u8425\u5206\u6790"));
732
+ console.log(chalk6.green(" - \u4EF7\u683C\u67E5\u8BE2"));
733
+ console.log(chalk6.green(" - \u5E93\u5B58\u7BA1\u7406"));
734
+ console.log(chalk6.yellow("\u{1F4A1} \u4F7F\u7528 'r2 ai chat' \u5F00\u59CB\u5BF9\u8BDD"));
735
+ });
736
+ return command;
737
+ }
738
+
739
+ // src/commands/setup.ts
740
+ function setupCommands(program2) {
741
+ const authCommand = program2.command("auth").description("\u6388\u6743\u7BA1\u7406");
742
+ authCommand.addCommand(createLoginCommand());
743
+ authCommand.addCommand(createLogoutCommand());
744
+ authCommand.addCommand(createStatusCommand());
745
+ program2.command("ingest").description("\u5BF9\u63A5\u4E3B\u6D41 ERP\uFF0C\u7EDF\u4E00\u591A\u6E20\u9053\u7ECF\u8425\u6570\u636E").action(() => {
746
+ console.log(chalk7.blue("\u6B63\u5728\u5BF9\u63A5 ERP \u6570\u636E..."));
747
+ console.log(chalk7.green("\u2705 \u5DF2\u5BF9\u63A5\u7EBF\u4E0A\u7535\u5546\u6570\u636E"));
748
+ console.log(chalk7.green("\u2705 \u5DF2\u5BF9\u63A5\u7EBF\u4E0B\u95E8\u5E97\u6570\u636E"));
749
+ console.log(chalk7.green("\u2705 \u5DF2\u5BF9\u63A5\u4ED3\u50A8\u5C65\u7EA6\u6570\u636E"));
750
+ console.log(chalk7.blue("\u6570\u636E\u5BF9\u63A5\u5B8C\u6210\uFF01"));
751
+ });
752
+ const reportCommand = program2.command("report").description("\u751F\u6210\u7ECF\u8425\u65E5\u62A5/\u5468\u62A5");
753
+ reportCommand.addCommand(createReportCommand());
754
+ program2.command("ask").description("\u81EA\u7136\u8BED\u8A00\u67E5\u8BE2\u7ECF\u8425\u6570\u636E").action(() => {
755
+ console.log("\u81EA\u7136\u8BED\u8A00\u67E5\u8BE2\u529F\u80FD\u5F00\u53D1\u4E2D...");
756
+ });
757
+ const demandCommand = program2.command("demand").description("\u626B\u63CF\u5E02\u573A\u9700\u6C42\u70ED\u5EA6\u4E0E\u4F9B\u9700\u7F3A\u53E3");
758
+ demandCommand.option("--sku <sku>", "\u5546\u54C1SKU").option("--region <region>", "\u533A\u57DF").action((options) => {
759
+ console.log(chalk7.blue("\u6B63\u5728\u626B\u63CF\u5E02\u573A\u9700\u6C42..."));
760
+ console.log(chalk7.green(`SKU: ${options.sku || "\u5168\u90E8"}`));
761
+ console.log(chalk7.green(`\u533A\u57DF: ${options.region || "\u5168\u56FD"}`));
762
+ console.log(chalk7.yellow("\u{1F525} \u9700\u6C42\u70ED\u5EA6: \u9AD8"));
763
+ console.log(chalk7.yellow("\u{1F4C8} \u4F9B\u9700\u7F3A\u53E3: 20%"));
764
+ console.log(chalk7.blue("\u5E02\u573A\u9700\u6C42\u5206\u6790\u5B8C\u6210\uFF01"));
765
+ });
766
+ const pricingCommand = program2.command("pricing").description("\u57FA\u4E8E\u771F\u5B9E\u6210\u4EA4\u6570\u636E\u7ED9\u51FA\u6536\u8D27\u4EF7\u4E0E\u552E\u5356\u4EF7\u5EFA\u8BAE");
767
+ pricingCommand.addCommand(createPricingCommand());
768
+ const inventoryCommand = program2.command("inventory").description("\u5E93\u5B58\u7BA1\u7406");
769
+ inventoryCommand.addCommand(createRiskCommand());
770
+ program2.command("fulfillment").description("\u5C65\u7EA6\u5168\u94FE\u8DEF\u8FFD\u8E2A").action(() => {
771
+ console.log(chalk7.blue("\u6B63\u5728\u8FFD\u8E2A\u5C65\u7EA6\u5168\u94FE\u8DEF..."));
772
+ console.log(chalk7.green("\u{1F4E6} \u6536\u8D27: \u5B8C\u6210"));
773
+ console.log(chalk7.green("\u{1F50D} \u8D28\u68C0: \u5B8C\u6210"));
774
+ console.log(chalk7.green("\u{1F3E0} \u5165\u5E93: \u5B8C\u6210"));
775
+ console.log(chalk7.green("\u{1F69A} \u53D1\u8D27: \u8FDB\u884C\u4E2D"));
776
+ console.log(chalk7.blue("\u5C65\u7EA6\u8FFD\u8E2A\u5B8C\u6210\uFF01"));
777
+ });
778
+ const aiCommand = program2.command("ai").description("AI \u76F8\u5173\u529F\u80FD");
779
+ aiCommand.addCommand(createChatCommand());
780
+ aiCommand.addCommand(createSkillsCommand());
781
+ const simulateCommand = program2.command("simulate").description("\u7ADE\u4EF7\u6210\u4EA4\u6A21\u62DF");
782
+ simulateCommand.option("--sku <sku>", "\u5546\u54C1SKU").option("--price <price>", "\u51FA\u4EF7").action((options) => {
783
+ console.log(chalk7.blue("\u6B63\u5728\u6A21\u62DF\u7ADE\u4EF7\u6210\u4EA4..."));
784
+ console.log(chalk7.green(`SKU: ${options.sku}`));
785
+ console.log(chalk7.green(`\u51FA\u4EF7: \xA5${options.price}`));
786
+ console.log(chalk7.yellow("\u{1F4CA} \u9884\u4F30\u6210\u4EA4\u7387: 85%"));
787
+ console.log(chalk7.yellow("\u{1F4B0} \u9884\u4F30\u5229\u6DA6\u7A7A\u95F4: 15%"));
788
+ console.log(chalk7.blue("\u7ADE\u4EF7\u6A21\u62DF\u5B8C\u6210\uFF01"));
789
+ });
790
+ program2.command("bidding-strategy").description("\u57FA\u4E8E\u9884\u7B97\u4E0E\u54C1\u7C7B\u751F\u6210\u7ADE\u4EF7\u7B56\u7565\u5EFA\u8BAE").action(() => {
791
+ console.log(chalk7.blue("\u6B63\u5728\u751F\u6210\u7ADE\u4EF7\u7B56\u7565..."));
792
+ console.log(chalk7.green("\u{1F3AF} \u7B56\u7565\u76EE\u6807: \u6700\u5927\u5316\u6210\u4EA4\u7387"));
793
+ console.log(chalk7.green("\u{1F4B8} \u9884\u7B97\u5206\u914D: \u9AD8\u9700\u6C42\u54C1\u7C7B 60%\uFF0C\u4E2D\u9700\u6C42\u54C1\u7C7B 30%\uFF0C\u4F4E\u9700\u6C42\u54C1\u7C7B 10%"));
794
+ console.log(chalk7.yellow("\u{1F4C8} \u5EFA\u8BAE\u51FA\u4EF7\u533A\u95F4: \xA5800-\xA51200"));
795
+ console.log(chalk7.blue("\u7ADE\u4EF7\u7B56\u7565\u751F\u6210\u5B8C\u6210\uFF01"));
796
+ });
797
+ const decideCommand = program2.command("decide").description("\u7EFC\u5408\u6570\u636E\u8F93\u51FA\u7ECF\u8425\u52A8\u4F5C\u5EFA\u8BAE");
798
+ decideCommand.option("--store <store>", "\u5E97\u94FA\u4EE3\u7801").option("--horizon <horizon>", "\u9884\u6D4B\u5468\u671F").action((options) => {
799
+ console.log(chalk7.blue("\u6B63\u5728\u5206\u6790\u7ECF\u8425\u6570\u636E..."));
800
+ console.log(chalk7.green(`\u5E97\u94FA: ${options.store || "\u5168\u90E8"}`));
801
+ console.log(chalk7.green(`\u9884\u6D4B\u5468\u671F: ${options.horizon || "7d"}`));
802
+ console.log(chalk7.yellow("\u{1F4C8} \u8865\u8D27\u5EFA\u8BAE: Air Jordan 1 Retro High OG (20 \u53CC)"));
803
+ console.log(chalk7.yellow("\u{1F4C9} \u6E05\u4ED3\u5EFA\u8BAE: Louis Vuitton Neverfull (5 \u4E2A)"));
804
+ console.log(chalk7.yellow("\u{1F4B0} \u8C03\u8C03\u4EF7\u5EFA\u8BAE: Chanel Classic Flap (\u4E0A\u8C03 5%)"));
805
+ console.log(chalk7.yellow("\u26A0\uFE0F \u98CE\u63A7\u5EFA\u8BAE: \u52A0\u5F3A\u9AD8\u4EF7\u503C\u5546\u54C1\u7684\u8D28\u68C0\u6D41\u7A0B"));
806
+ console.log(chalk7.blue("\u7ECF\u8425\u51B3\u7B56\u5EFA\u8BAE\u751F\u6210\u5B8C\u6210\uFF01"));
807
+ });
808
+ program2.command("agent").description("AI Agent \u96C6\u6210").action(() => {
809
+ console.log(chalk7.blue("AI Agent \u96C6\u6210"));
810
+ console.log(chalk7.green("\u{1F527} \u652F\u6301\u7684 AI Agent \u6846\u67B6:"));
811
+ console.log(chalk7.green(" - Claude Code"));
812
+ console.log(chalk7.green(" - OpenClaw"));
813
+ console.log(chalk7.green(" - Codex"));
814
+ console.log(chalk7.blue("\u5B89\u88C5 Agent Skills:"));
815
+ console.log(chalk7.yellow("npx skills add Round2AI/r2-cli --all -y"));
816
+ console.log(chalk7.blue("AI Agent \u96C6\u6210\u5B8C\u6210\uFF01"));
817
+ });
818
+ }
819
+
820
+ // src/index.ts
821
+ function displayWelcomeMessage() {
822
+ console.log(
823
+ chalk8.cyan(
824
+ figlet.textSync("R2-CLI", {
825
+ font: "Standard",
826
+ horizontalLayout: "full"
827
+ })
828
+ )
829
+ );
830
+ console.log(chalk8.gray("\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B\n"));
831
+ }
832
+ function setupCliApp() {
833
+ displayWelcomeMessage();
834
+ const pkgJson = fse.readJSONSync(path2.join(import.meta.dirname, "../package.json"));
835
+ const program2 = new Command8();
836
+ program2.name("r2").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B").version(pkgJson.version, "-v, --version");
837
+ program2.configureOutput({
230
838
  writeErr: (str) => {
231
- const error = str.replace("error:", "").trim();
232
- console.error(`❌ 错误: ${error}`);
233
- },
234
- });
235
- program.parse(process.argv); // 解析命令行参数
236
- //# sourceMappingURL=index.js.map
839
+ const error = str.replace("error:", "").trim();
840
+ console.error(`\u274C \u9519\u8BEF: ${error}`);
841
+ }
842
+ });
843
+ setupCommands(program2);
844
+ return program2;
845
+ }
846
+ var program = setupCliApp();
847
+ program.parse(process.argv);
848
+ //# sourceMappingURL=index.js.map