@optima-chat/bi-cli 0.3.4 → 0.3.6

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.
@@ -72,19 +72,38 @@ interface FunnelResponse {
72
72
  }
73
73
 
74
74
  export function createAnalyticsCommand(): Command {
75
- const analytics = new Command('analytics').description('Advanced analytics');
75
+ const analytics = new Command('analytics').description(
76
+ `Advanced analytics.
77
+
78
+ Period comparison, growth analysis, customer cohorts, order funnels.`
79
+ );
76
80
 
77
81
  // analytics compare
78
82
  analytics
79
83
  .command('compare')
80
- .description('Compare current period with previous period')
81
- .option('--days <number>', 'Number of days', '30')
82
- .option(
83
- '--compare-to <type>',
84
- 'Compare to: previous_period or previous_year',
85
- 'previous_period'
84
+ .description(
85
+ `Period comparison analysis.
86
+
87
+ Compare current period with previous period or year-over-year.
88
+
89
+ Returns JSON:
90
+ {
91
+ "current": { "revenue": 10000, "orders": 100, "avg_order_value": 100, "customers": 80 },
92
+ "previous": { "revenue": 8000, "orders": 90, ... },
93
+ "changes": {
94
+ "revenue": { "absolute": 2000, "percentage": 25.0 },
95
+ ...
96
+ }
97
+ }
98
+
99
+ Examples:
100
+ bi-cli analytics compare # Last 30 days vs previous 30
101
+ bi-cli analytics compare --days 7 # This week vs last week
102
+ bi-cli analytics compare --compare-to previous_year # Year-over-year`
86
103
  )
87
- .option('--pretty', 'Output in pretty table format')
104
+ .option('--days <number>', 'Number of days to compare (default: 30)', '30')
105
+ .option('--compare-to <type>', 'Compare to: previous_period | previous_year', 'previous_period')
106
+ .option('--pretty', 'Output as table')
88
107
  .action(async (options) => {
89
108
  const cfg = getConfig();
90
109
  if (!cfg.accessToken) {
@@ -167,10 +186,32 @@ export function createAnalyticsCommand(): Command {
167
186
  // analytics growth
168
187
  analytics
169
188
  .command('growth')
170
- .description('Get growth trends over time')
171
- .option('--period <type>', 'Period type: daily, weekly, monthly', 'daily')
172
- .option('--limit <number>', 'Number of periods', '30')
173
- .option('--pretty', 'Output in pretty table format')
189
+ .description(
190
+ `Growth trend analysis.
191
+
192
+ View revenue and order growth rates by day/week/month.
193
+
194
+ Returns JSON:
195
+ {
196
+ "trends": [
197
+ {
198
+ "period": "2024-01-01",
199
+ "revenue": 5000,
200
+ "orders": 50,
201
+ "customers": 40,
202
+ "revenue_growth": 15.5 // Growth rate vs previous period (%), null for first
203
+ }
204
+ ]
205
+ }
206
+
207
+ Examples:
208
+ bi-cli analytics growth # Daily, last 30 periods
209
+ bi-cli analytics growth --period weekly # Weekly
210
+ bi-cli analytics growth --period monthly --limit 12 # Monthly, last 12 months`
211
+ )
212
+ .option('--period <type>', 'Period type: daily | weekly | monthly', 'daily')
213
+ .option('--limit <number>', 'Number of periods (default: 30)', '30')
214
+ .option('--pretty', 'Output as table')
174
215
  .action(async (options) => {
175
216
  const cfg = getConfig();
176
217
  if (!cfg.accessToken) {
@@ -221,8 +262,27 @@ export function createAnalyticsCommand(): Command {
221
262
  // analytics cohort
222
263
  analytics
223
264
  .command('cohort')
224
- .description('Customer cohort analysis')
225
- .option('--pretty', 'Output in pretty table format')
265
+ .description(
266
+ `Customer cohort analysis.
267
+
268
+ Group customers by first purchase month and analyze lifetime value (LTV).
269
+
270
+ Returns JSON:
271
+ {
272
+ "cohorts": [
273
+ {
274
+ "month": "2024-01",
275
+ "customers": 100, // New customers in this month
276
+ "avg_lifetime_value": 500, // Average customer lifetime value
277
+ "avg_orders": 2.5, // Average orders per customer
278
+ "total_revenue": 50000 // Total revenue from this cohort
279
+ }
280
+ ]
281
+ }
282
+
283
+ Use case: Evaluate customer acquisition quality, optimize marketing strategy.`
284
+ )
285
+ .option('--pretty', 'Output as table')
226
286
  .action(async (options) => {
227
287
  const cfg = getConfig();
228
288
  if (!cfg.accessToken) {
@@ -270,9 +330,30 @@ export function createAnalyticsCommand(): Command {
270
330
  // analytics funnel
271
331
  analytics
272
332
  .command('funnel')
273
- .description('Order status funnel analysis')
274
- .option('--days <number>', 'Number of days', '30')
275
- .option('--pretty', 'Output in pretty table format')
333
+ .description(
334
+ `Order status funnel analysis.
335
+
336
+ Analyze conversion rates and drop-offs from order creation to delivery.
337
+
338
+ Returns JSON:
339
+ {
340
+ "total_orders": 1000,
341
+ "conversion_rate": 85.5, // Final completion rate (%)
342
+ "funnel": [
343
+ { "stage": "pending", "count": 1000, "amount": 100000, "percentage": 100 },
344
+ { "stage": "paid", "count": 950, "amount": 95000, "percentage": 95 },
345
+ { "stage": "shipped", "count": 900, "amount": 90000, "percentage": 90 },
346
+ { "stage": "delivered", "count": 855, "amount": 85500, "percentage": 85.5 }
347
+ ],
348
+ "dropoffs": [
349
+ { "status": "cancelled", "count": 50, "amount": 5000, "percentage": 5 }
350
+ ]
351
+ }
352
+
353
+ Use case: Identify order drop-off points, optimize fulfillment process.`
354
+ )
355
+ .option('--days <number>', 'Number of days (default: 30)', '30')
356
+ .option('--pretty', 'Output as table')
276
357
  .action(async (options) => {
277
358
  const cfg = getConfig();
278
359
  if (!cfg.accessToken) {
@@ -38,13 +38,25 @@ interface UserInfo {
38
38
  }
39
39
 
40
40
  export function createAuthCommand(): Command {
41
- const auth = new Command('auth').description('Authentication commands');
41
+ const auth = new Command('auth').description(
42
+ `Authentication commands.
43
+
44
+ You must login before using other commands. Tokens are saved to ~/.optima/token.json.`
45
+ );
42
46
 
43
47
  // auth login
44
48
  auth
45
49
  .command('login')
46
- .description('Login with OAuth 2.0 Device Flow')
47
- .option('--env <environment>', 'Environment (production|stage|development)', 'production')
50
+ .description(
51
+ `Login using OAuth 2.0 Device Flow.
52
+
53
+ Opens browser automatically for authorization. Token is saved after successful auth.
54
+
55
+ Examples:
56
+ bi-cli auth login # Login to production (default)
57
+ bi-cli auth login --env stage # Login to staging environment`
58
+ )
59
+ .option('--env <environment>', 'Environment: production | stage | development', 'production')
48
60
  .action(async (options) => {
49
61
  const env = options.env as Environment;
50
62
 
@@ -206,7 +218,7 @@ export function createAuthCommand(): Command {
206
218
  // auth logout
207
219
  auth
208
220
  .command('logout')
209
- .description('Logout and delete ~/.optima/token.json')
221
+ .description('Logout and delete local token file (~/.optima/token.json)')
210
222
  .action(() => {
211
223
  clearAuth();
212
224
  success('Logged out successfully');
@@ -216,7 +228,7 @@ export function createAuthCommand(): Command {
216
228
  // auth whoami
217
229
  auth
218
230
  .command('whoami')
219
- .description('Show current user information')
231
+ .description('Show current user info (email, role, merchant ID)')
220
232
  .action(async () => {
221
233
  const cfg = getConfig();
222
234
 
@@ -260,7 +272,7 @@ export function createAuthCommand(): Command {
260
272
  // auth status
261
273
  auth
262
274
  .command('status')
263
- .description('Show authentication status')
275
+ .description('Show authentication status (environment, login state, config path)')
264
276
  .action(() => {
265
277
  const cfg = getConfig();
266
278
 
@@ -88,15 +88,36 @@ interface PerformanceResponse {
88
88
  }
89
89
 
90
90
  export function createProductCommand(): Command {
91
- const product = new Command('product').description('Product analytics');
91
+ const product = new Command('product').description(
92
+ `Product analytics.
93
+
94
+ Analyze product performance, price distribution, ABC classification.`
95
+ );
92
96
 
93
97
  // product best-sellers
94
98
  product
95
99
  .command('best-sellers')
96
- .description('Get best selling products')
97
- .option('--limit <number>', 'Number of products to return', '10')
98
- .option('--sort <field>', 'Sort by: revenue, quantity, orders', 'revenue')
99
- .option('--pretty', 'Output in pretty table format')
100
+ .description(
101
+ `Get best selling products ranking.
102
+
103
+ Returns products sorted by revenue/quantity/orders with rank, revenue, units sold, revenue share.
104
+
105
+ Returns JSON:
106
+ {
107
+ "products": [
108
+ { "rank": 1, "title": "Product Name", "revenue": 1000, "units_sold": 50, "orders": 30, "revenue_share": 15.5 }
109
+ ],
110
+ "total_revenue": number
111
+ }
112
+
113
+ Examples:
114
+ bi-cli product best-sellers # Top 10 by revenue
115
+ bi-cli product best-sellers --limit 5 # Top 5
116
+ bi-cli product best-sellers --sort quantity # Sort by quantity`
117
+ )
118
+ .option('--limit <number>', 'Number of products to return (default: 10)', '10')
119
+ .option('--sort <field>', 'Sort by: revenue | quantity | orders', 'revenue')
120
+ .option('--pretty', 'Output as table')
100
121
  .action(async (options) => {
101
122
  const cfg = getConfig();
102
123
  if (!cfg.accessToken) {
@@ -147,8 +168,23 @@ export function createProductCommand(): Command {
147
168
  // product abc-analysis
148
169
  product
149
170
  .command('abc-analysis')
150
- .description('ABC inventory analysis')
151
- .option('--pretty', 'Output in pretty table format')
171
+ .description(
172
+ `ABC inventory analysis (Pareto analysis).
173
+
174
+ Classifies products by revenue contribution:
175
+ - A: High-value products contributing 70% of revenue (typically ~20% of products)
176
+ - B: Medium-value products contributing 20% of revenue
177
+ - C: Low-value products contributing 10% of revenue
178
+
179
+ Use case: Identify core products, optimize inventory and purchasing strategy.
180
+
181
+ Returns JSON:
182
+ {
183
+ "summary": { "A": {...}, "B": {...}, "C": {...} },
184
+ "products": [ { "title": "Product Name", "category": "A", "revenue": number, ... } ]
185
+ }`
186
+ )
187
+ .option('--pretty', 'Output as table')
152
188
  .action(async (options) => {
153
189
  const cfg = getConfig();
154
190
  if (!cfg.accessToken) {
@@ -205,8 +241,20 @@ export function createProductCommand(): Command {
205
241
  // product price-analysis
206
242
  product
207
243
  .command('price-analysis')
208
- .description('Price point analysis')
209
- .option('--pretty', 'Output in pretty table format')
244
+ .description(
245
+ `Price range analysis.
246
+
247
+ Analyze product count, revenue, and sales by price ranges.
248
+
249
+ Returns JSON:
250
+ {
251
+ "price_ranges": [
252
+ { "range": "¥0-50", "products": 10, "revenue": 5000, "units": 200, "revenue_share": 15.5 }
253
+ ],
254
+ "totals": { "revenue": number, "units": number }
255
+ }`
256
+ )
257
+ .option('--pretty', 'Output as table')
210
258
  .action(async (options) => {
211
259
  const cfg = getConfig();
212
260
  if (!cfg.accessToken) {
@@ -256,10 +304,36 @@ export function createProductCommand(): Command {
256
304
  // product performance
257
305
  product
258
306
  .command('performance')
259
- .description('Get product performance metrics')
260
- .option('--days <number>', 'Number of days', '30')
261
- .option('--limit <number>', 'Number of products', '20')
262
- .option('--pretty', 'Output in pretty table format')
307
+ .description(
308
+ `Product performance metrics.
309
+
310
+ Get sales, inventory, and margin metrics for each product.
311
+
312
+ Returns JSON:
313
+ {
314
+ "products": [
315
+ {
316
+ "title": "Product Name",
317
+ "price": 99.00, // Selling price
318
+ "inventory": 50, // Current stock
319
+ "sales": { "units": 100, "revenue": 9900, "orders": 80 },
320
+ "metrics": {
321
+ "margin_percent": 30.5, // Profit margin (%)
322
+ "days_of_stock": 15, // Estimated days of stock
323
+ "velocity": 6.7 // Daily sales rate
324
+ }
325
+ }
326
+ ]
327
+ }
328
+
329
+ Examples:
330
+ bi-cli product performance # Last 30 days, top 20 products
331
+ bi-cli product performance --days 7 # Last 7 days
332
+ bi-cli product performance --limit 50 # Top 50 products`
333
+ )
334
+ .option('--days <number>', 'Number of days (default: 30)', '30')
335
+ .option('--limit <number>', 'Number of products (default: 20)', '20')
336
+ .option('--pretty', 'Output as table')
263
337
  .action(async (options) => {
264
338
  const cfg = getConfig();
265
339
  if (!cfg.accessToken) {
@@ -33,14 +33,38 @@ interface SalesResponse {
33
33
  }
34
34
 
35
35
  export function createSalesCommand(): Command {
36
- const sales = new Command('sales').description('Sales analytics');
36
+ const sales = new Command('sales').description(
37
+ `Sales analytics.
38
+
39
+ Get sales summary and daily breakdown data.`
40
+ );
37
41
 
38
42
  // sales get
39
43
  sales
40
44
  .command('get')
41
- .description('Get sales data')
42
- .option('--days <number>', 'Number of days to fetch', '7')
43
- .option('--pretty', 'Output in pretty table format (default: JSON)')
45
+ .description(
46
+ `Get sales summary and daily breakdown.
47
+
48
+ Returns JSON:
49
+ {
50
+ "summary": {
51
+ "total_revenue": number, // Total revenue (CNY)
52
+ "total_orders": number, // Total order count
53
+ "avg_order_value": number, // Average order value (CNY)
54
+ "unique_customers": number // Unique customer count
55
+ },
56
+ "daily": [ // Daily breakdown array
57
+ { "date": "YYYY-MM-DD", "total_revenue": number, "order_count": number, ... }
58
+ ]
59
+ }
60
+
61
+ Examples:
62
+ bi-cli sales get # Get last 7 days
63
+ bi-cli sales get --days 30 # Get last 30 days
64
+ bi-cli sales get --days 7 --pretty # Output as table`
65
+ )
66
+ .option('--days <number>', 'Number of days from today (range: 1-365)', '7')
67
+ .option('--pretty', 'Output as table (default: JSON)')
44
68
  .action(async (options) => {
45
69
  const cfg = getConfig();
46
70
 
@@ -69,15 +69,44 @@ function formatDuration(seconds: number): string {
69
69
  }
70
70
 
71
71
  export function createTrafficCommand(): Command {
72
- const traffic = new Command('traffic').description('Traffic analytics');
72
+ const traffic = new Command('traffic').description(
73
+ `Traffic analytics.
74
+
75
+ Analyze website visits, traffic sources, conversion funnels, search keywords.`
76
+ );
73
77
 
74
78
  // traffic overview
75
79
  traffic
76
80
  .command('overview')
77
- .description('Get traffic overview')
78
- .option('--days <number>', 'Number of days', '30')
79
- .option('--product <id>', 'Filter by product ID')
80
- .option('--pretty', 'Output in pretty format (default: JSON)')
81
+ .description(
82
+ `Traffic overview.
83
+
84
+ Get page views, unique visitors, sessions, and comparison with previous period.
85
+
86
+ Returns JSON:
87
+ {
88
+ "period": { "start": "2024-01-01", "end": "2024-01-30", "days": 30 },
89
+ "summary": {
90
+ "page_views": 10000,
91
+ "unique_visitors": 3000,
92
+ "sessions": 5000,
93
+ "avg_session_duration": 180, // seconds
94
+ "bounce_rate": 0.35 // 35%
95
+ },
96
+ "comparison": {
97
+ "page_views_change": 0.15, // +15%
98
+ "unique_visitors_change": 0.10
99
+ }
100
+ }
101
+
102
+ Examples:
103
+ bi-cli traffic overview # Last 30 days, all pages
104
+ bi-cli traffic overview --days 7 # Last 7 days
105
+ bi-cli traffic overview --product <uuid> # Filter by product`
106
+ )
107
+ .option('--days <number>', 'Number of days (range: 1-365, default: 30)', '30')
108
+ .option('--product <id>', 'Filter by product ID (UUID format)')
109
+ .option('--pretty', 'Output as table (default: JSON)')
81
110
  .action(async (options) => {
82
111
  const cfg = getConfig();
83
112
 
@@ -129,10 +158,29 @@ export function createTrafficCommand(): Command {
129
158
  // traffic sources
130
159
  traffic
131
160
  .command('sources')
132
- .description('Get traffic sources')
133
- .option('--days <number>', 'Number of days', '30')
134
- .option('--limit <number>', 'Limit results', '10')
135
- .option('--pretty', 'Output in pretty format (default: JSON)')
161
+ .description(
162
+ `Traffic source analysis.
163
+
164
+ Analyze visitor sources (Google, WeChat, direct, etc.).
165
+
166
+ Returns JSON:
167
+ {
168
+ "sources": [
169
+ {
170
+ "source": "google",
171
+ "medium": "organic",
172
+ "visitors": 1000,
173
+ "page_views": 3000,
174
+ "percentage": 0.35 // 35%
175
+ }
176
+ ]
177
+ }
178
+
179
+ Use case: Evaluate channel effectiveness, optimize marketing spend.`
180
+ )
181
+ .option('--days <number>', 'Number of days (default: 30)', '30')
182
+ .option('--limit <number>', 'Number of results (default: 10)', '10')
183
+ .option('--pretty', 'Output as table (default: JSON)')
136
184
  .action(async (options) => {
137
185
  const cfg = getConfig();
138
186
 
@@ -179,10 +227,28 @@ export function createTrafficCommand(): Command {
179
227
  // traffic funnel
180
228
  traffic
181
229
  .command('funnel')
182
- .description('Get conversion funnel')
183
- .option('--days <number>', 'Number of days', '30')
184
- .option('--product <id>', 'Filter by product ID')
185
- .option('--pretty', 'Output in pretty format (default: JSON)')
230
+ .description(
231
+ `Conversion funnel analysis.
232
+
233
+ Analyze user journey from visit to purchase:
234
+ Visit → View Product → Add to Cart → Checkout → Purchase
235
+
236
+ Returns JSON:
237
+ {
238
+ "funnel": [
239
+ { "step": "page_view", "count": 10000, "rate": 1.0, "conversion": 1.0 },
240
+ { "step": "product_view", "count": 5000, "rate": 0.5, "conversion": 0.5 },
241
+ { "step": "add_to_cart", "count": 1000, "rate": 0.1, "conversion": 0.2 },
242
+ { "step": "checkout", "count": 500, "rate": 0.05, "conversion": 0.5 },
243
+ { "step": "purchase", "count": 300, "rate": 0.03, "conversion": 0.6 }
244
+ ]
245
+ }
246
+
247
+ Note: rate = ratio from start, conversion = conversion from previous step.`
248
+ )
249
+ .option('--days <number>', 'Number of days (default: 30)', '30')
250
+ .option('--product <id>', 'Filter by product ID (UUID format)')
251
+ .option('--pretty', 'Output as table (default: JSON)')
186
252
  .action(async (options) => {
187
253
  const cfg = getConfig();
188
254
 
@@ -227,11 +293,27 @@ export function createTrafficCommand(): Command {
227
293
  // traffic search
228
294
  traffic
229
295
  .command('search')
230
- .description('Get search analytics')
231
- .option('--days <number>', 'Number of days', '30')
232
- .option('--limit <number>', 'Limit results', '20')
233
- .option('--zero-results', 'Show only zero results queries')
234
- .option('--pretty', 'Output in pretty format (default: JSON)')
296
+ .description(
297
+ `Site search analytics.
298
+
299
+ Analyze search keywords, result counts, and click-through rates.
300
+
301
+ Returns JSON:
302
+ {
303
+ "searches": [
304
+ { "query": "dress", "count": 500, "avg_results": 25, "click_rate": 0.65 }
305
+ ],
306
+ "zero_results": [
307
+ { "query": "nonexistent product", "count": 10 }
308
+ ]
309
+ }
310
+
311
+ Use case: Optimize product titles, add missing products, improve search.`
312
+ )
313
+ .option('--days <number>', 'Number of days (default: 30)', '30')
314
+ .option('--limit <number>', 'Number of results (default: 20)', '20')
315
+ .option('--zero-results', 'Show only zero-result queries')
316
+ .option('--pretty', 'Output as table (default: JSON)')
235
317
  .action(async (options) => {
236
318
  const cfg = getConfig();
237
319
 
@@ -288,10 +370,28 @@ export function createTrafficCommand(): Command {
288
370
  // traffic pages
289
371
  traffic
290
372
  .command('pages')
291
- .description('Get top pages')
292
- .option('--days <number>', 'Number of days', '30')
293
- .option('--limit <number>', 'Limit results', '20')
294
- .option('--pretty', 'Output in pretty format (default: JSON)')
373
+ .description(
374
+ `Top pages analysis.
375
+
376
+ View most popular pages sorted by page views.
377
+
378
+ Returns JSON:
379
+ {
380
+ "pages": [
381
+ {
382
+ "path": "/products/xxx",
383
+ "page_views": 5000,
384
+ "unique_visitors": 2000,
385
+ "sessions": 3000
386
+ }
387
+ ]
388
+ }
389
+
390
+ Use case: Understand browsing patterns, optimize popular page experience.`
391
+ )
392
+ .option('--days <number>', 'Number of days (default: 30)', '30')
393
+ .option('--limit <number>', 'Number of results (default: 20)', '20')
394
+ .option('--pretty', 'Output as table (default: JSON)')
295
395
  .action(async (options) => {
296
396
  const cfg = getConfig();
297
397