@puyinkai/xiaobao-cli 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +13 -0
  2. package/dist/add-CCuWFy1O.mjs +21 -0
  3. package/dist/{admin-BzMFazEa.mjs → admin-BOL_otwc.mjs} +2 -2
  4. package/dist/analyze-mjHjOnz1.mjs +72 -0
  5. package/dist/{api-ChuNquZJ.mjs → api-BaX_r5S5.mjs} +3 -3
  6. package/dist/{api-client-ifJHc7hu.mjs → api-client-D3sCv6L3.mjs} +1 -1
  7. package/dist/{audio-CeNKUqeU.mjs → audio-CDt1rpEL.mjs} +3 -2
  8. package/dist/{auth-CdWYrfte.mjs → auth-sQwZSTNA.mjs} +4 -3
  9. package/dist/beautx-DytYVFvT.mjs +16 -0
  10. package/dist/cli.mjs +18 -13
  11. package/dist/config-GuXMTecJ.mjs +11 -0
  12. package/dist/{consultant-CO9zaJ7I.mjs → consultant-elv5arLG.mjs} +1 -1
  13. package/dist/{current-BYpcshKV.mjs → current-ABh6R3vp.mjs} +1 -1
  14. package/dist/{customer-COMf1yZb.mjs → customer-CZ-nG9ku.mjs} +1 -1
  15. package/dist/date-BcQMKhIT.mjs +21 -0
  16. package/dist/deal-analysis-Dqz34gLw.mjs +10 -0
  17. package/dist/{device-flow-DC1kqcmR.mjs → device-flow-j10PFOQL.mjs} +42 -31
  18. package/dist/diff-8I1_L-nU.mjs +21 -0
  19. package/dist/{doc-NfMyo-fF.mjs → doc-CJT7BuhU.mjs} +3 -3
  20. package/dist/{doc-content-BKaZ016e.mjs → doc-content-_SCykNvs.mjs} +3 -3
  21. package/dist/{docs-CheVzIbW.mjs → docs-BHtwTAJ4.mjs} +3 -3
  22. package/dist/fields-BRE3oWMD.mjs +54 -0
  23. package/dist/{focus-AWSxlbBZ.mjs → focus-C4egr05X.mjs} +1 -1
  24. package/dist/follow-LwYQd9Bv.mjs +14 -0
  25. package/dist/{format-HWx3JWdS.mjs → format-DfVypHID.mjs} +1 -1
  26. package/dist/get-CbovJWSq.mjs +66 -0
  27. package/dist/{kb-DkSAvuBG.mjs → kb-CyPqbezN.mjs} +4 -4
  28. package/dist/last-7-days-VKMMIzDz.mjs +5 -0
  29. package/dist/{list-BbU4R0_z.mjs → list-2qqSxkDM.mjs} +3 -3
  30. package/dist/{list-CMFp28Dm.mjs → list-CT4t_FJs.mjs} +4 -4
  31. package/dist/{list-Czym-Sla.mjs → list-Ca5uJXDH.mjs} +3 -3
  32. package/dist/{list-bBAaEvT7.mjs → list-CiNgcIXS.mjs} +4 -4
  33. package/dist/{list-BxWqQllQ2.mjs → list-DWv6toPT.mjs} +4 -4
  34. package/dist/list-DXOlqJog.mjs +76 -0
  35. package/dist/{list-D7Fmqk0G.mjs → list-FQpZk3vH.mjs} +4 -4
  36. package/dist/{list-QIEQgIb3.mjs → list-OYeOGI0g.mjs} +4 -4
  37. package/dist/list-XIIj_ryX.mjs +43 -0
  38. package/dist/{login-DYAlK1aL.mjs → login-Bp2W2Hnj.mjs} +9 -2
  39. package/dist/{logout-S3GMy_ns.mjs → logout-BnoEQxKZ.mjs} +2 -2
  40. package/dist/now-Ce3ViNOw.mjs +9 -0
  41. package/dist/plan-C35h8U-w.mjs +10 -0
  42. package/dist/portrait-BEDGkOx1.mjs +14 -0
  43. package/dist/portrait-tags-B9hPFDIF.mjs +10 -0
  44. package/dist/{project-CiltZzqF.mjs → project-urShHaAN.mjs} +3 -3
  45. package/dist/{qa-DDzTuZ8K.mjs → qa-CaV_tDBc.mjs} +3 -3
  46. package/dist/{quantum-CgAcmQAL.mjs → quantum-Ds7rlag3.mjs} +5 -5
  47. package/dist/range-CSJiXTp3.mjs +18 -0
  48. package/dist/{resistance-YwKC91E0.mjs → resistance-DMesV4lG.mjs} +1 -1
  49. package/dist/{sales-report-XQ_Oy9ht.mjs → sales-report-BIfyfucO.mjs} +3 -3
  50. package/dist/{search-CxOFpH18.mjs → search-B0wA0YCI.mjs} +4 -4
  51. package/dist/shared-BEkL4JRB.mjs +11 -0
  52. package/dist/shared-Bbxvn4ZI.mjs +92 -0
  53. package/dist/shared-CYALikq5.mjs +277 -0
  54. package/dist/status-CrpCtf5U.mjs +65 -0
  55. package/dist/subtract-B4XTXD_X.mjs +21 -0
  56. package/dist/{summary-CfbHddby.mjs → summary-BIx7F4AE.mjs} +4 -4
  57. package/dist/summary-BkxVcv8a.mjs +65 -0
  58. package/dist/{text-R3KjyXSK.mjs → text-CqmsXzad.mjs} +3 -3
  59. package/dist/this-month-BRdfmc1s.mjs +5 -0
  60. package/dist/this-week-2GoqEaXU.mjs +5 -0
  61. package/dist/today-BhQnSMJH.mjs +5 -0
  62. package/dist/today-CdlU96lq.mjs +9 -0
  63. package/dist/today-so-far-D2g98rKv.mjs +5 -0
  64. package/dist/{token-usage-BDnEMHvB.mjs → token-usage-y46b3_7C.mjs} +3 -3
  65. package/dist/tomorrow-BgSEBV69.mjs +9 -0
  66. package/dist/{use-DgCwov4y.mjs → use-rAR4OVC7.mjs} +1 -1
  67. package/dist/{visit-Beb2o8zF.mjs → visit-CmEtfs7n.mjs} +2 -2
  68. package/dist/visit-evaluate-LdAg9iP5.mjs +9 -0
  69. package/dist/weekday-CgEg7n7U.mjs +14 -0
  70. package/dist/{whoami-H8AdUnQY.mjs → whoami-oRc8gILN.mjs} +1 -1
  71. package/dist/yesterday-CHAh1DlJ.mjs +5 -0
  72. package/dist/yesterday-DW-YiRTt.mjs +9 -0
  73. package/package.json +3 -2
  74. package/skills/wangxiaobao-audio-analyze/SKILL.md +42 -0
  75. package/skills/wangxiaobao-beautx/SKILL.md +42 -0
  76. package/skills/wangxiaobao-customer-portrait/SKILL.md +45 -0
  77. package/skills/wangxiaobao-customer-query/SKILL.md +1 -1
  78. package/skills/wangxiaobao-follow-query/SKILL.md +45 -0
  79. package/skills/wangxiaobao-knowledge-base/SKILL.md +1 -1
  80. package/skills/wangxiaobao-quantum-stats/SKILL.md +3 -1
  81. package/skills/wangxiaobao-quantum-stats/references/quantum-metrics.md +3 -2
  82. package/skills/wangxiaobao-shared/SKILL.md +5 -1
  83. /package/dist/{util-pyTg7qwY.mjs → util-BuoFIeLS.mjs} +0 -0
package/README.md CHANGED
@@ -56,10 +56,23 @@ xiaobao-cli audio list --from "2026-05-01 00:00:00" --to "2026-05-02 00:00:00" -
56
56
  | `kb doc <doc-id>` | 新增 · 知识库文档详情 |
57
57
  | `kb doc-content <doc-id> [--offset] [--limit]` | 新增 · 知识库文档正文分页 |
58
58
  | `quantum <metric> [--view] [--visit-type] …` | 新增 · 量子看板 / KPI 统计(20 指标) |
59
+ | `follow list` / `follow summary` | 新增 · 旺跟进明细分页 / 电话微信指标汇总 |
60
+ | `portrait list` / `portrait get <字段>` | 新增 · 画像字段清单 / 单字段饼图分布 |
61
+ | `config fields` | 新增 · 客户字段配置字典(解读 dynamic_tags) |
62
+ | `audio analyze <query> [--customer-id]` | 新增 · 录音批量分析(LLM) |
63
+ | `beautx plan\|deal-analysis\|portrait-tags\|visit-evaluate` | 新增 · 医美四查询 |
64
+ | `date now\|today\|range this-week …` | 新增 · 本地日期工具(不走网络) |
59
65
  | `admin sales-report --from --to [--by project\|zone]` | 新增 · 公司经营数据 出库/回款(super-admin,独立白名单) |
60
66
  | `admin token-usage --from --to [--model] …` | 新增 · LLM token 用量(super-admin,独立白名单) |
61
67
  | `api <METHOD> <path>` | `xiaobao_api` |
62
68
 
69
+ ## WorkBuddy Connector
70
+
71
+ `workbuddy/` 是按《WorkBuddy Connector 对接规范》方案二(CLI + Skill)准备的连接器配置
72
+ (`connector-meta.json` / `cli.json` / `icon.svg`);`npm run workbuddy:pack` 会连同 `skills/`
73
+ 打成 `dist-workbuddy/wangxiaobao-connector.zip` 供提交审核。认证走 `auth login`(device flow)
74
+ + `auth status`(exit 0 = 已登录,可完成待授权的 device code 换 token)+ `auth logout`。
75
+
63
76
  ## 通用 flags
64
77
 
65
78
  - `--format toon|json|table` —— 默认 `toon`(省 token,适合 LLM 上下文);`json` 严格 JSON、agent/人类友好;`table` 暂未实现(回退 JSON)
@@ -0,0 +1,21 @@
1
+ import { n as parsePositiveDays, r as addDays, t as defineDateCommand } from "./shared-CYALikq5.mjs";
2
+ //#region src/commands/date/add.ts
3
+ var add_default = defineDateCommand({
4
+ name: "add",
5
+ description: "日期往后推 N 天",
6
+ args: {
7
+ date: {
8
+ type: "positional",
9
+ required: true,
10
+ description: "基准日期 YYYY-MM-DD"
11
+ },
12
+ days: {
13
+ type: "positional",
14
+ required: true,
15
+ description: "往后推的天数(非负整数)"
16
+ }
17
+ },
18
+ run: ({ args }) => addDays(args.date, parsePositiveDays(args.days, "days"), args.timezone)
19
+ });
20
+ //#endregion
21
+ export { add_default as default };
@@ -6,8 +6,8 @@ var admin_default = defineCommand({
6
6
  description: "super-admin 经营报表:公司经营数据(出库/回款)/ LLM token 用量(独立白名单)"
7
7
  },
8
8
  subCommands: {
9
- "sales-report": () => import("./sales-report-XQ_Oy9ht.mjs").then((m) => m.default),
10
- "token-usage": () => import("./token-usage-BDnEMHvB.mjs").then((m) => m.default)
9
+ "sales-report": () => import("./sales-report-BIfyfucO.mjs").then((m) => m.default),
10
+ "token-usage": () => import("./token-usage-y46b3_7C.mjs").then((m) => m.default)
11
11
  }
12
12
  });
13
13
  //#endregion
@@ -0,0 +1,72 @@
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
+ import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
4
+ import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
+ import { t as csvToArray } from "./util-BuoFIeLS.mjs";
7
+ import { defineCommand } from "citty";
8
+ //#region src/commands/audio/analyze.ts
9
+ /**
10
+ * `xiaobao-cli audio analyze` — 录音批量分析(LLM)。
11
+ *
12
+ * 对指定客户/顾问范围的录音做 LLM 分析(共性抗性、话术问题等开放问题)。
13
+ * 与 `audio list/text`(元数据/逐字稿查询)不同,这是耗时的生成式分析。
14
+ * 调 POST /ai-open/audio/analyze。
15
+ */
16
+ var analyze_default = defineCommand({
17
+ meta: {
18
+ name: "analyze",
19
+ description: "录音批量分析(LLM,耗时较长;元数据查询用 audio list)"
20
+ },
21
+ args: {
22
+ query: {
23
+ type: "positional",
24
+ required: true,
25
+ description: "分析问题/指令"
26
+ },
27
+ type: {
28
+ type: "string",
29
+ description: "分析类型:general_analysis(默认)| timeline_analysis"
30
+ },
31
+ "customer-id": {
32
+ type: "string",
33
+ description: "单个客户 wang_id"
34
+ },
35
+ "customer-ids": {
36
+ type: "string",
37
+ description: "CSV: 客户 wang_id 列表"
38
+ },
39
+ "advisor-ids": {
40
+ type: "string",
41
+ description: "CSV: 顾问 userId 列表"
42
+ },
43
+ "api-base": { type: "string" },
44
+ "auth-base": { type: "string" },
45
+ format: {
46
+ type: "string",
47
+ default: "toon"
48
+ }
49
+ },
50
+ async run({ args }) {
51
+ try {
52
+ writeResult(await xbApiFetch(resolveConfig({
53
+ apiBase: args["api-base"],
54
+ authBase: args["auth-base"]
55
+ }), "POST", "/ai-open/audio/analyze", {
56
+ headers: tenantProjectHeaders(await requireActiveProject()),
57
+ body: {
58
+ query: String(args.query),
59
+ analysisType: args.type,
60
+ customerId: args["customer-id"],
61
+ customerIds: csvToArray(args["customer-ids"]),
62
+ advisorIds: csvToArray(args["advisor-ids"])
63
+ }
64
+ }), args.format);
65
+ } catch (err) {
66
+ writeError(err, args.format);
67
+ process.exit(1);
68
+ }
69
+ }
70
+ });
71
+ //#endregion
72
+ export { analyze_default as default };
@@ -1,8 +1,8 @@
1
- import { a as resolveConfig } from "./device-flow-DC1kqcmR.mjs";
2
- import { t as xbApiFetch } from "./api-client-ifJHc7hu.mjs";
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
3
  import { t as loadActiveProject } from "./project-store-CudTRvbA.mjs";
4
4
  import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
6
  import { defineCommand } from "citty";
7
7
  //#region src/commands/api.ts
8
8
  /**
@@ -1,4 +1,4 @@
1
- import { r as refreshToken } from "./device-flow-DC1kqcmR.mjs";
1
+ import { i as refreshToken } from "./device-flow-j10PFOQL.mjs";
2
2
  import { a as isAccessTokenValid, l as writeToken, s as readToken } from "./token-store-BB7n-fwJ.mjs";
3
3
  //#region src/core/api-client.ts
4
4
  /**
@@ -6,8 +6,9 @@ var audio_default = defineCommand({
6
6
  description: "录音元数据分页 / 单条文本查询"
7
7
  },
8
8
  subCommands: {
9
- list: () => import("./list-CMFp28Dm.mjs").then((m) => m.default),
10
- text: () => import("./text-R3KjyXSK.mjs").then((m) => m.default)
9
+ list: () => import("./list-CT4t_FJs.mjs").then((m) => m.default),
10
+ text: () => import("./text-CqmsXzad.mjs").then((m) => m.default),
11
+ analyze: () => import("./analyze-mjHjOnz1.mjs").then((m) => m.default)
11
12
  }
12
13
  });
13
14
  //#endregion
@@ -6,9 +6,10 @@ var auth_default = defineCommand({
6
6
  description: "OAuth 登录 / 身份查询 / 登出(device flow)"
7
7
  },
8
8
  subCommands: {
9
- login: () => import("./login-DYAlK1aL.mjs").then((m) => m.default),
10
- whoami: () => import("./whoami-H8AdUnQY.mjs").then((m) => m.default),
11
- logout: () => import("./logout-S3GMy_ns.mjs").then((m) => m.default)
9
+ login: () => import("./login-Bp2W2Hnj.mjs").then((m) => m.default),
10
+ whoami: () => import("./whoami-oRc8gILN.mjs").then((m) => m.default),
11
+ status: () => import("./status-CrpCtf5U.mjs").then((m) => m.default),
12
+ logout: () => import("./logout-BnoEQxKZ.mjs").then((m) => m.default)
12
13
  }
13
14
  });
14
15
  //#endregion
@@ -0,0 +1,16 @@
1
+ import { defineCommand } from "citty";
2
+ //#region src/commands/beautx/index.ts
3
+ var beautx_default = defineCommand({
4
+ meta: {
5
+ name: "beautx",
6
+ description: "医美:变美计划(plan) / 成交分析(deal-analysis) / 画像标签(portrait-tags) / 接诊评价(visit-evaluate)"
7
+ },
8
+ subCommands: {
9
+ plan: () => import("./plan-C35h8U-w.mjs").then((m) => m.default),
10
+ "deal-analysis": () => import("./deal-analysis-Dqz34gLw.mjs").then((m) => m.default),
11
+ "portrait-tags": () => import("./portrait-tags-B9hPFDIF.mjs").then((m) => m.default),
12
+ "visit-evaluate": () => import("./visit-evaluate-LdAg9iP5.mjs").then((m) => m.default)
13
+ }
14
+ });
15
+ //#endregion
16
+ export { beautx_default as default };
package/dist/cli.mjs CHANGED
@@ -19,19 +19,24 @@ runMain(defineCommand({
19
19
  description: "旺小宝 CLI — host-agnostic 业务数据 / 问数 / 来访总结 / 知识库 能力 (openclaw-xiaobao plugin 的 CLI 等价物)"
20
20
  },
21
21
  subCommands: {
22
- auth: () => import("./auth-CdWYrfte.mjs").then((m) => m.default),
23
- project: () => import("./project-CiltZzqF.mjs").then((m) => m.default),
24
- consultant: () => import("./consultant-CO9zaJ7I.mjs").then((m) => m.default),
25
- audio: () => import("./audio-CeNKUqeU.mjs").then((m) => m.default),
26
- customer: () => import("./customer-COMf1yZb.mjs").then((m) => m.default),
27
- visit: () => import("./visit-Beb2o8zF.mjs").then((m) => m.default),
28
- focus: () => import("./focus-AWSxlbBZ.mjs").then((m) => m.default),
29
- resistance: () => import("./resistance-YwKC91E0.mjs").then((m) => m.default),
30
- qa: () => import("./qa-DDzTuZ8K.mjs").then((m) => m.default),
31
- kb: () => import("./kb-DkSAvuBG.mjs").then((m) => m.default),
32
- quantum: () => import("./quantum-CgAcmQAL.mjs").then((m) => m.default),
33
- admin: () => import("./admin-BzMFazEa.mjs").then((m) => m.default),
34
- api: () => import("./api-ChuNquZJ.mjs").then((m) => m.default)
22
+ auth: () => import("./auth-sQwZSTNA.mjs").then((m) => m.default),
23
+ project: () => import("./project-urShHaAN.mjs").then((m) => m.default),
24
+ consultant: () => import("./consultant-elv5arLG.mjs").then((m) => m.default),
25
+ audio: () => import("./audio-CDt1rpEL.mjs").then((m) => m.default),
26
+ customer: () => import("./customer-CZ-nG9ku.mjs").then((m) => m.default),
27
+ visit: () => import("./visit-CmEtfs7n.mjs").then((m) => m.default),
28
+ focus: () => import("./focus-C4egr05X.mjs").then((m) => m.default),
29
+ resistance: () => import("./resistance-DMesV4lG.mjs").then((m) => m.default),
30
+ qa: () => import("./qa-CaV_tDBc.mjs").then((m) => m.default),
31
+ kb: () => import("./kb-CyPqbezN.mjs").then((m) => m.default),
32
+ quantum: () => import("./quantum-Ds7rlag3.mjs").then((m) => m.default),
33
+ follow: () => import("./follow-LwYQd9Bv.mjs").then((m) => m.default),
34
+ portrait: () => import("./portrait-BEDGkOx1.mjs").then((m) => m.default),
35
+ config: () => import("./config-GuXMTecJ.mjs").then((m) => m.default),
36
+ beautx: () => import("./beautx-DytYVFvT.mjs").then((m) => m.default),
37
+ date: () => import("./date-BcQMKhIT.mjs").then((m) => m.default),
38
+ admin: () => import("./admin-BOL_otwc.mjs").then((m) => m.default),
39
+ api: () => import("./api-BaX_r5S5.mjs").then((m) => m.default)
35
40
  }
36
41
  }));
37
42
  //#endregion
@@ -0,0 +1,11 @@
1
+ import { defineCommand } from "citty";
2
+ //#region src/commands/config/index.ts
3
+ var config_default = defineCommand({
4
+ meta: {
5
+ name: "config",
6
+ description: "项目配置:客户字段配置(fields,解读 dynamic_tags 标签含义)"
7
+ },
8
+ subCommands: { fields: () => import("./fields-BRE3oWMD.mjs").then((m) => m.default) }
9
+ });
10
+ //#endregion
11
+ export { config_default as default };
@@ -5,7 +5,7 @@ var consultant_default = defineCommand({
5
5
  name: "consultant",
6
6
  description: "查询有权限的置业顾问列表"
7
7
  },
8
- subCommands: { list: () => import("./list-BbU4R0_z.mjs").then((m) => m.default) }
8
+ subCommands: { list: () => import("./list-2qqSxkDM.mjs").then((m) => m.default) }
9
9
  });
10
10
  //#endregion
11
11
  export { consultant_default as default };
@@ -1,5 +1,5 @@
1
1
  import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
2
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
2
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/commands/project/current.ts
5
5
  /**
@@ -5,7 +5,7 @@ var customer_default = defineCommand({
5
5
  name: "customer",
6
6
  description: "客户画像分页查询"
7
7
  },
8
- subCommands: { list: () => import("./list-D7Fmqk0G.mjs").then((m) => m.default) }
8
+ subCommands: { list: () => import("./list-FQpZk3vH.mjs").then((m) => m.default) }
9
9
  });
10
10
  //#endregion
11
11
  export { customer_default as default };
@@ -0,0 +1,21 @@
1
+ import { defineCommand } from "citty";
2
+ //#region src/commands/date/index.ts
3
+ var date_default = defineCommand({
4
+ meta: {
5
+ name: "date",
6
+ description: "本地日期/时间(不走 MCP):now、today、weekday、range 等"
7
+ },
8
+ subCommands: {
9
+ now: () => import("./now-Ce3ViNOw.mjs").then((m) => m.default),
10
+ today: () => import("./today-CdlU96lq.mjs").then((m) => m.default),
11
+ yesterday: () => import("./yesterday-DW-YiRTt.mjs").then((m) => m.default),
12
+ tomorrow: () => import("./tomorrow-BgSEBV69.mjs").then((m) => m.default),
13
+ weekday: () => import("./weekday-CgEg7n7U.mjs").then((m) => m.default),
14
+ add: () => import("./add-CCuWFy1O.mjs").then((m) => m.default),
15
+ subtract: () => import("./subtract-B4XTXD_X.mjs").then((m) => m.default),
16
+ diff: () => import("./diff-8I1_L-nU.mjs").then((m) => m.default),
17
+ range: () => import("./range-CSJiXTp3.mjs").then((m) => m.default)
18
+ }
19
+ });
20
+ //#endregion
21
+ export { date_default as default };
@@ -0,0 +1,10 @@
1
+ import { t as defineBeautxCommand } from "./shared-Bbxvn4ZI.mjs";
2
+ //#region src/commands/beautx/deal-analysis.ts
3
+ var deal_analysis_default = defineBeautxCommand({
4
+ name: "deal-analysis",
5
+ description: "医美成交分析分页(成交状态/未成交点/分析原因与结果)",
6
+ path: "/ai-open/beautx/deal-analyses",
7
+ supportsLatestOnly: true
8
+ });
9
+ //#endregion
10
+ export { deal_analysis_default as default };
@@ -88,6 +88,43 @@ async function initiateDeviceAuthorization(config) {
88
88
  };
89
89
  return data;
90
90
  }
91
+ /**
92
+ * RFC 8628 §3.4 — ONE token-endpoint attempt. `'pending'` / `'slow_down'`
93
+ * mean "not yet"; anything else terminal is thrown. Shared by the blocking
94
+ * poll loop and by `auth status` (which must return within seconds).
95
+ */
96
+ async function exchangeDeviceCode(config, deviceCode) {
97
+ const url = `${config.authBase}/oauth2/token`;
98
+ const body = new URLSearchParams({
99
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
100
+ device_code: deviceCode
101
+ });
102
+ const resp = await fetch(url, {
103
+ method: "POST",
104
+ headers: authHeaders(config),
105
+ body: body.toString()
106
+ });
107
+ const parsed = await resp.json();
108
+ if (resp.ok) return parsed;
109
+ const err = parsed.error;
110
+ if (err === "authorization_pending") return "pending";
111
+ if (err === "slow_down") return "slow_down";
112
+ if (err === "access_denied") throw {
113
+ code: "ACCESS_DENIED",
114
+ message: "User declined authorization",
115
+ body: parsed
116
+ };
117
+ if (err === "expired_token") throw {
118
+ code: "EXPIRED_TOKEN",
119
+ message: "Device code expired before user approved",
120
+ body: parsed
121
+ };
122
+ throw {
123
+ code: "TOKEN_POLL_FAILED",
124
+ status: resp.status,
125
+ body: parsed
126
+ };
127
+ }
91
128
  /** RFC 8628 §3.4 — poll the token endpoint until success / denial / expiry. */
92
129
  async function pollForToken(config, deviceCode, intervalSeconds, expiresInSeconds) {
93
130
  const serverDeadline = Date.now() + expiresInSeconds * 1e3;
@@ -95,39 +132,13 @@ async function pollForToken(config, deviceCode, intervalSeconds, expiresInSecond
95
132
  let pollIntervalMs = Math.max(1, intervalSeconds) * 1e3;
96
133
  while (Date.now() < Math.min(serverDeadline, hardDeadline)) {
97
134
  await sleep(pollIntervalMs);
98
- const url = `${config.authBase}/oauth2/token`;
99
- const body = new URLSearchParams({
100
- grant_type: "urn:ietf:params:oauth:grant-type:device_code",
101
- device_code: deviceCode
102
- });
103
- const resp = await fetch(url, {
104
- method: "POST",
105
- headers: authHeaders(config),
106
- body: body.toString()
107
- });
108
- const parsed = await resp.json();
109
- if (resp.ok) return parsed;
110
- const err = parsed.error;
111
- if (err === "authorization_pending") continue;
112
- if (err === "slow_down") {
135
+ const result = await exchangeDeviceCode(config, deviceCode);
136
+ if (result === "pending") continue;
137
+ if (result === "slow_down") {
113
138
  pollIntervalMs += 5e3;
114
139
  continue;
115
140
  }
116
- if (err === "access_denied") throw {
117
- code: "ACCESS_DENIED",
118
- message: "User declined authorization",
119
- body: parsed
120
- };
121
- if (err === "expired_token") throw {
122
- code: "EXPIRED_TOKEN",
123
- message: "Device code expired before user approved",
124
- body: parsed
125
- };
126
- throw {
127
- code: "TOKEN_POLL_FAILED",
128
- status: resp.status,
129
- body: parsed
130
- };
141
+ return result;
131
142
  }
132
143
  throw {
133
144
  code: "TIMEOUT",
@@ -163,4 +174,4 @@ function sleep(ms) {
163
174
  return new Promise((r) => setTimeout(r, ms));
164
175
  }
165
176
  //#endregion
166
- export { resolveConfig as a, revokeRefreshToken as i, pollForToken as n, refreshToken as r, initiateDeviceAuthorization as t };
177
+ export { revokeRefreshToken as a, refreshToken as i, initiateDeviceAuthorization as n, resolveConfig as o, pollForToken as r, exchangeDeviceCode as t };
@@ -0,0 +1,21 @@
1
+ import { i as dateDiff, t as defineDateCommand } from "./shared-CYALikq5.mjs";
2
+ //#region src/commands/date/diff.ts
3
+ var diff_default = defineDateCommand({
4
+ name: "diff",
5
+ description: "计算两日期相差天数(end - start)",
6
+ args: {
7
+ start: {
8
+ type: "string",
9
+ description: "开始日期 YYYY-MM-DD",
10
+ required: true
11
+ },
12
+ end: {
13
+ type: "string",
14
+ description: "结束日期 YYYY-MM-DD",
15
+ required: true
16
+ }
17
+ },
18
+ run: ({ args }) => dateDiff(args.start, args.end)
19
+ });
20
+ //#endregion
21
+ export { diff_default as default };
@@ -1,8 +1,8 @@
1
- import { a as resolveConfig } from "./device-flow-DC1kqcmR.mjs";
2
- import { t as xbApiFetch } from "./api-client-ifJHc7hu.mjs";
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
3
  import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
4
4
  import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
6
  import { defineCommand } from "citty";
7
7
  //#region src/commands/kb/doc.ts
8
8
  /**
@@ -1,8 +1,8 @@
1
- import { a as resolveConfig } from "./device-flow-DC1kqcmR.mjs";
2
- import { t as xbApiFetch } from "./api-client-ifJHc7hu.mjs";
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
3
  import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
4
4
  import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
6
  import { defineCommand } from "citty";
7
7
  //#region src/commands/kb/doc-content.ts
8
8
  /**
@@ -1,8 +1,8 @@
1
- import { a as resolveConfig } from "./device-flow-DC1kqcmR.mjs";
2
- import { t as xbApiFetch } from "./api-client-ifJHc7hu.mjs";
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
3
  import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
4
4
  import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
6
  import { defineCommand } from "citty";
7
7
  //#region src/commands/kb/docs.ts
8
8
  /**
@@ -0,0 +1,54 @@
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
+ import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
4
+ import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
+ import { defineCommand } from "citty";
7
+ //#region src/commands/config/fields.ts
8
+ /**
9
+ * `xiaobao-cli config fields` — 客户字段配置分页。
10
+ *
11
+ * 返回本项目客户字段(名称/格式/说明/分类/AI 映射名),供解读
12
+ * customer list 里 dynamic_tags 各标签的含义。调 POST /ai-open/customers/fields。
13
+ */
14
+ var fields_default = defineCommand({
15
+ meta: {
16
+ name: "fields",
17
+ description: "客户字段配置分页(解读 dynamic_tags 标签含义)"
18
+ },
19
+ args: {
20
+ page: {
21
+ type: "string",
22
+ default: "1"
23
+ },
24
+ size: {
25
+ type: "string",
26
+ default: "50"
27
+ },
28
+ "api-base": { type: "string" },
29
+ "auth-base": { type: "string" },
30
+ format: {
31
+ type: "string",
32
+ default: "toon"
33
+ }
34
+ },
35
+ async run({ args }) {
36
+ try {
37
+ writeResult(await xbApiFetch(resolveConfig({
38
+ apiBase: args["api-base"],
39
+ authBase: args["auth-base"]
40
+ }), "POST", "/ai-open/customers/fields", {
41
+ headers: tenantProjectHeaders(await requireActiveProject()),
42
+ body: {
43
+ page: Number(args.page),
44
+ size: Number(args.size)
45
+ }
46
+ }), args.format);
47
+ } catch (err) {
48
+ writeError(err, args.format);
49
+ process.exit(1);
50
+ }
51
+ }
52
+ });
53
+ //#endregion
54
+ export { fields_default as default };
@@ -5,7 +5,7 @@ var focus_default = defineCommand({
5
5
  name: "focus",
6
6
  description: "客户关注点标签分页查询"
7
7
  },
8
- subCommands: { list: () => import("./list-QIEQgIb3.mjs").then((m) => m.default) }
8
+ subCommands: { list: () => import("./list-OYeOGI0g.mjs").then((m) => m.default) }
9
9
  });
10
10
  //#endregion
11
11
  export { focus_default as default };
@@ -0,0 +1,14 @@
1
+ import { defineCommand } from "citty";
2
+ //#region src/commands/follow/index.ts
3
+ var follow_default = defineCommand({
4
+ meta: {
5
+ name: "follow",
6
+ description: "旺跟进:明细分页(list) / 电话微信指标汇总(summary)(聚合统计卡片用 quantum follow)"
7
+ },
8
+ subCommands: {
9
+ list: () => import("./list-DXOlqJog.mjs").then((m) => m.default),
10
+ summary: () => import("./summary-BkxVcv8a.mjs").then((m) => m.default)
11
+ }
12
+ });
13
+ //#endregion
14
+ export { follow_default as default };
@@ -1,4 +1,4 @@
1
- //#region ../../../node_modules/.pnpm/@toon-format+toon@2.2.0/node_modules/@toon-format/toon/dist/index.mjs
1
+ //#region node_modules/.pnpm/@toon-format+toon@2.2.0/node_modules/@toon-format/toon/dist/index.mjs
2
2
  const NULL_LITERAL = "null";
3
3
  const DEFAULT_DELIMITER = {
4
4
  comma: ",",
@@ -0,0 +1,66 @@
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
+ import { n as requireActiveProject } from "./project-store-CudTRvbA.mjs";
4
+ import { t as tenantProjectHeaders } from "./headers-Dy5gROBB.mjs";
5
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
6
+ import { r as toLocalDateTime, t as csvToArray } from "./util-BuoFIeLS.mjs";
7
+ import { defineCommand } from "citty";
8
+ //#region src/commands/portrait/get.ts
9
+ /**
10
+ * `xiaobao-cli portrait get <field>` — 单个画像字段的饼图分布。
11
+ *
12
+ * 回答"全项目客户的<意向级别/预算/…>分布比例"类问题(count + items[].name/count/rate)。
13
+ * field 用 `portrait list` 返回的中文字段名。调 POST /ai-open/portraits/get。
14
+ */
15
+ var get_default = defineCommand({
16
+ meta: {
17
+ name: "get",
18
+ description: "画像饼图数据(按单个字段中文名查询分布)"
19
+ },
20
+ args: {
21
+ field: {
22
+ type: "positional",
23
+ required: true,
24
+ description: "画像字段中文名(portrait list 的 fieldName)"
25
+ },
26
+ from: {
27
+ type: "string",
28
+ description: "开始时间(含)"
29
+ },
30
+ to: {
31
+ type: "string",
32
+ description: "结束时间(不含)"
33
+ },
34
+ "user-ids": {
35
+ type: "string",
36
+ description: "CSV: 数据范围 userIds;不传按当前授权范围"
37
+ },
38
+ "api-base": { type: "string" },
39
+ "auth-base": { type: "string" },
40
+ format: {
41
+ type: "string",
42
+ default: "toon"
43
+ }
44
+ },
45
+ async run({ args }) {
46
+ try {
47
+ writeResult(await xbApiFetch(resolveConfig({
48
+ apiBase: args["api-base"],
49
+ authBase: args["auth-base"]
50
+ }), "POST", "/ai-open/portraits/get", {
51
+ headers: tenantProjectHeaders(await requireActiveProject()),
52
+ body: {
53
+ field: String(args.field),
54
+ fromDate: toLocalDateTime(args.from),
55
+ toDate: toLocalDateTime(args.to),
56
+ userIds: csvToArray(args["user-ids"])?.map(Number)
57
+ }
58
+ }), args.format);
59
+ } catch (err) {
60
+ writeError(err, args.format);
61
+ process.exit(1);
62
+ }
63
+ }
64
+ });
65
+ //#endregion
66
+ export { get_default as default };
@@ -6,10 +6,10 @@ var kb_default = defineCommand({
6
6
  description: "项目知识库:语义检索 / 文档列表 / 文档详情 / 文档正文分页"
7
7
  },
8
8
  subCommands: {
9
- search: () => import("./search-CxOFpH18.mjs").then((m) => m.default),
10
- docs: () => import("./docs-CheVzIbW.mjs").then((m) => m.default),
11
- doc: () => import("./doc-NfMyo-fF.mjs").then((m) => m.default),
12
- "doc-content": () => import("./doc-content-BKaZ016e.mjs").then((m) => m.default)
9
+ search: () => import("./search-B0wA0YCI.mjs").then((m) => m.default),
10
+ docs: () => import("./docs-BHtwTAJ4.mjs").then((m) => m.default),
11
+ doc: () => import("./doc-CJT7BuhU.mjs").then((m) => m.default),
12
+ "doc-content": () => import("./doc-content-_SCykNvs.mjs").then((m) => m.default)
13
13
  }
14
14
  });
15
15
  //#endregion
@@ -0,0 +1,5 @@
1
+ import { t as defineRangePresetCommand } from "./shared-BEkL4JRB.mjs";
2
+ //#region src/commands/date/range/last-7-days.ts
3
+ var last_7_days_default = defineRangePresetCommand("last-7-days", "最近 7 天(含今天):from=6 天前 00:00,to=明天 00:00");
4
+ //#endregion
5
+ export { last_7_days_default as default };