@puyinkai/xiaobao-cli 0.4.0 → 0.5.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 (41) hide show
  1. package/README.md +7 -0
  2. package/dist/{admin-BzMFazEa.mjs → admin-BOL_otwc.mjs} +2 -2
  3. package/dist/{api-ChuNquZJ.mjs → api-BaX_r5S5.mjs} +3 -3
  4. package/dist/{api-client-ifJHc7hu.mjs → api-client-D3sCv6L3.mjs} +1 -1
  5. package/dist/{audio-CeNKUqeU.mjs → audio-DzcmDYVu.mjs} +2 -2
  6. package/dist/{auth-CdWYrfte.mjs → auth-DvvYyJBK.mjs} +4 -3
  7. package/dist/cli.mjs +13 -13
  8. package/dist/{consultant-CO9zaJ7I.mjs → consultant-Ccnjnhzz.mjs} +1 -1
  9. package/dist/{current-BYpcshKV.mjs → current-CaUOiS5G.mjs} +1 -1
  10. package/dist/{customer-COMf1yZb.mjs → customer-D_LctjqX.mjs} +1 -1
  11. package/dist/{device-flow-DC1kqcmR.mjs → device-flow-j10PFOQL.mjs} +42 -31
  12. package/dist/{doc-NfMyo-fF.mjs → doc-CC08fj8m.mjs} +3 -3
  13. package/dist/{doc-content-BKaZ016e.mjs → doc-content-DktnDECM.mjs} +3 -3
  14. package/dist/{docs-CheVzIbW.mjs → docs-DtQy3Zoc.mjs} +3 -3
  15. package/dist/{focus-AWSxlbBZ.mjs → focus-BPPyRCBb.mjs} +1 -1
  16. package/dist/{format-HWx3JWdS.mjs → format-DfVypHID.mjs} +1 -1
  17. package/dist/{kb-DkSAvuBG.mjs → kb-DpBUFdFV.mjs} +4 -4
  18. package/dist/{list-CMFp28Dm.mjs → list-CTSX1XuK.mjs} +3 -3
  19. package/dist/{list-BxWqQllQ2.mjs → list-Ca5Fvq_e.mjs} +3 -3
  20. package/dist/{list-Czym-Sla.mjs → list-DPyzRkq4.mjs} +3 -3
  21. package/dist/{list-QIEQgIb3.mjs → list-D_8QLOZ1.mjs} +3 -3
  22. package/dist/{list-bBAaEvT7.mjs → list-DciEIXpx.mjs} +3 -3
  23. package/dist/{list-BbU4R0_z.mjs → list-Ikc5mo6a.mjs} +3 -3
  24. package/dist/{list-D7Fmqk0G.mjs → list-xbJZbyGQ.mjs} +3 -3
  25. package/dist/{login-DYAlK1aL.mjs → login-COK74GKN.mjs} +9 -2
  26. package/dist/{logout-S3GMy_ns.mjs → logout-BQnDwD5-.mjs} +2 -2
  27. package/dist/{project-CiltZzqF.mjs → project-CYA9qd8k.mjs} +3 -3
  28. package/dist/{qa-DDzTuZ8K.mjs → qa-CDYWW-19.mjs} +3 -3
  29. package/dist/{quantum-CgAcmQAL.mjs → quantum-Dyhp2Clf.mjs} +3 -3
  30. package/dist/{resistance-YwKC91E0.mjs → resistance-BhlYgeUx.mjs} +1 -1
  31. package/dist/{sales-report-XQ_Oy9ht.mjs → sales-report-BIfyfucO.mjs} +3 -3
  32. package/dist/{search-CxOFpH18.mjs → search-ChFFOKV4.mjs} +3 -3
  33. package/dist/status-DR0tFzju.mjs +65 -0
  34. package/dist/{summary-CfbHddby.mjs → summary-C3poiB2C.mjs} +3 -3
  35. package/dist/{text-R3KjyXSK.mjs → text-K7uP8bat.mjs} +3 -3
  36. package/dist/{token-usage-BDnEMHvB.mjs → token-usage-y46b3_7C.mjs} +3 -3
  37. package/dist/{use-DgCwov4y.mjs → use-DwoZynR9.mjs} +1 -1
  38. package/dist/{visit-Beb2o8zF.mjs → visit-qf8Lwf_s.mjs} +2 -2
  39. package/dist/{whoami-H8AdUnQY.mjs → whoami-CtuWBu20.mjs} +1 -1
  40. package/package.json +3 -2
  41. package/skills/wangxiaobao-knowledge-base/SKILL.md +1 -1
package/README.md CHANGED
@@ -60,6 +60,13 @@ xiaobao-cli audio list --from "2026-05-01 00:00:00" --to "2026-05-02 00:00:00" -
60
60
  | `admin token-usage --from --to [--model] …` | 新增 · LLM token 用量(super-admin,独立白名单) |
61
61
  | `api <METHOD> <path>` | `xiaobao_api` |
62
62
 
63
+ ## WorkBuddy Connector
64
+
65
+ `workbuddy/` 是按《WorkBuddy Connector 对接规范》方案二(CLI + Skill)准备的连接器配置
66
+ (`connector-meta.json` / `cli.json` / `icon.svg`);`npm run workbuddy:pack` 会连同 `skills/`
67
+ 打成 `dist-workbuddy/wangxiaobao-connector.zip` 供提交审核。认证走 `auth login`(device flow)
68
+ + `auth status`(exit 0 = 已登录,可完成待授权的 device code 换 token)+ `auth logout`。
69
+
63
70
  ## 通用 flags
64
71
 
65
72
  - `--format toon|json|table` —— 默认 `toon`(省 token,适合 LLM 上下文);`json` 严格 JSON、agent/人类友好;`table` 暂未实现(回退 JSON)
@@ -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
@@ -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,8 @@ 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-CTSX1XuK.mjs").then((m) => m.default),
10
+ text: () => import("./text-K7uP8bat.mjs").then((m) => m.default)
11
11
  }
12
12
  });
13
13
  //#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-COK74GKN.mjs").then((m) => m.default),
10
+ whoami: () => import("./whoami-CtuWBu20.mjs").then((m) => m.default),
11
+ status: () => import("./status-DR0tFzju.mjs").then((m) => m.default),
12
+ logout: () => import("./logout-BQnDwD5-.mjs").then((m) => m.default)
12
13
  }
13
14
  });
14
15
  //#endregion
package/dist/cli.mjs CHANGED
@@ -19,19 +19,19 @@ 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-DvvYyJBK.mjs").then((m) => m.default),
23
+ project: () => import("./project-CYA9qd8k.mjs").then((m) => m.default),
24
+ consultant: () => import("./consultant-Ccnjnhzz.mjs").then((m) => m.default),
25
+ audio: () => import("./audio-DzcmDYVu.mjs").then((m) => m.default),
26
+ customer: () => import("./customer-D_LctjqX.mjs").then((m) => m.default),
27
+ visit: () => import("./visit-qf8Lwf_s.mjs").then((m) => m.default),
28
+ focus: () => import("./focus-BPPyRCBb.mjs").then((m) => m.default),
29
+ resistance: () => import("./resistance-BhlYgeUx.mjs").then((m) => m.default),
30
+ qa: () => import("./qa-CDYWW-19.mjs").then((m) => m.default),
31
+ kb: () => import("./kb-DpBUFdFV.mjs").then((m) => m.default),
32
+ quantum: () => import("./quantum-Dyhp2Clf.mjs").then((m) => m.default),
33
+ admin: () => import("./admin-BOL_otwc.mjs").then((m) => m.default),
34
+ api: () => import("./api-BaX_r5S5.mjs").then((m) => m.default)
35
35
  }
36
36
  }));
37
37
  //#endregion
@@ -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-Ikc5mo6a.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-xbJZbyGQ.mjs").then((m) => m.default) }
9
9
  });
10
10
  //#endregion
11
11
  export { customer_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 };
@@ -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
  /**
@@ -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-D_8QLOZ1.mjs").then((m) => m.default) }
9
9
  });
10
10
  //#endregion
11
11
  export { focus_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: ",",
@@ -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-ChFFOKV4.mjs").then((m) => m.default),
10
+ docs: () => import("./docs-DtQy3Zoc.mjs").then((m) => m.default),
11
+ doc: () => import("./doc-CC08fj8m.mjs").then((m) => m.default),
12
+ "doc-content": () => import("./doc-content-DktnDECM.mjs").then((m) => m.default)
13
13
  }
14
14
  });
15
15
  //#endregion
@@ -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 { n as mergeUserIds, r as toLocalDateTime, t as csvToArray } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/audio/list.ts
@@ -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 { r as toLocalDateTime } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/visit/list.ts
@@ -1,6 +1,6 @@
1
- import { a as resolveConfig } from "./device-flow-DC1kqcmR.mjs";
2
- import { t as xbApiFetch } from "./api-client-ifJHc7hu.mjs";
3
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
1
+ import { o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
+ import { t as xbApiFetch } from "./api-client-D3sCv6L3.mjs";
3
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  //#region src/commands/project/list.ts
6
6
  /**
@@ -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 { r as toLocalDateTime, t as csvToArray } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/focus/list.ts
@@ -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 { r as toLocalDateTime, t as csvToArray } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/resistance/list.ts
@@ -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/consultant/list.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 { r as toLocalDateTime } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/customer/list.ts
@@ -1,6 +1,6 @@
1
- import { a as resolveConfig, n as pollForToken, r as refreshToken, t as initiateDeviceAuthorization } from "./device-flow-DC1kqcmR.mjs";
1
+ import { i as refreshToken, n as initiateDeviceAuthorization, o as resolveConfig, r as pollForToken } from "./device-flow-j10PFOQL.mjs";
2
2
  import { a as isAccessTokenValid, c as writePendingAuth, l as writeToken, n as clearPendingAuth, o as readPendingAuth, r as clearToken, s as readToken, t as NoPendingAuthError } from "./token-store-BB7n-fwJ.mjs";
3
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
3
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  //#region src/commands/auth/login.ts
6
6
  /**
@@ -135,6 +135,13 @@ var login_default = defineCommand({
135
135
  }, fmt);
136
136
  return;
137
137
  }
138
+ await writePendingAuth({
139
+ device_code: init.device_code,
140
+ user_code: init.user_code,
141
+ verification_uri: verificationUri,
142
+ interval,
143
+ expires_at: Date.now() + init.expires_in * 1e3
144
+ });
138
145
  process.stderr.write(`
139
146
  请在浏览器中打开以下链接完成登录并授权访问你的旺小宝账号:
140
147
  \n 🔗 ${verificationUri}\n\n 设备验证码: ${init.user_code}\n 有效期约 ${expiresMinutes} 分钟\n\n等待你在浏览器中确认 ...
@@ -1,6 +1,6 @@
1
- import { a as resolveConfig, i as revokeRefreshToken } from "./device-flow-DC1kqcmR.mjs";
1
+ import { a as revokeRefreshToken, o as resolveConfig } from "./device-flow-j10PFOQL.mjs";
2
2
  import { n as clearPendingAuth, r as clearToken, s as readToken } from "./token-store-BB7n-fwJ.mjs";
3
- import { n as writeResult, t as writeError } from "./format-HWx3JWdS.mjs";
3
+ import { n as writeResult, t as writeError } from "./format-DfVypHID.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  //#region src/commands/auth/logout.ts
6
6
  /**
@@ -6,9 +6,9 @@ var project_default = defineCommand({
6
6
  description: "查询 / 切换激活项目"
7
7
  },
8
8
  subCommands: {
9
- list: () => import("./list-Czym-Sla.mjs").then((m) => m.default),
10
- use: () => import("./use-DgCwov4y.mjs").then((m) => m.default),
11
- current: () => import("./current-BYpcshKV.mjs").then((m) => m.default)
9
+ list: () => import("./list-DPyzRkq4.mjs").then((m) => m.default),
10
+ use: () => import("./use-DwoZynR9.mjs").then((m) => m.default),
11
+ current: () => import("./current-CaUOiS5G.mjs").then((m) => m.default)
12
12
  }
13
13
  });
14
14
  //#endregion
@@ -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/qa.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 { r as toLocalDateTime, t as csvToArray } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/quantum.ts
@@ -5,7 +5,7 @@ var resistance_default = defineCommand({
5
5
  name: "resistance",
6
6
  description: "客户抗性点标签分页查询"
7
7
  },
8
- subCommands: { list: () => import("./list-bBAaEvT7.mjs").then((m) => m.default) }
8
+ subCommands: { list: () => import("./list-DciEIXpx.mjs").then((m) => m.default) }
9
9
  });
10
10
  //#endregion
11
11
  export { resistance_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/admin/sales-report.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 { t as csvToArray } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/kb/search.ts
@@ -0,0 +1,65 @@
1
+ import { i as refreshToken, o as resolveConfig, t as exchangeDeviceCode } from "./device-flow-j10PFOQL.mjs";
2
+ import { a as isAccessTokenValid, i as decodeJwtPayload, l as writeToken, n as clearPendingAuth, o as readPendingAuth, r as clearToken, s as readToken } from "./token-store-BB7n-fwJ.mjs";
3
+ import { defineCommand } from "citty";
4
+ //#region src/commands/auth/status.ts
5
+ /**
6
+ * `xiaobao-cli auth status` — host-friendly auth check (WorkBuddy cli.json
7
+ * `status` command; also handy for scripts).
8
+ *
9
+ * Contract (WorkBuddy Connector spec §12.4): exit 0 + "Logged in as ..." on
10
+ * stdout when authenticated, non-zero otherwise; must return within seconds
11
+ * and be safe to poll every 3s.
12
+ *
13
+ * If a device authorization is pending (`auth login` was started and the host
14
+ * killed it after reading the URL), one token-endpoint attempt finishes the
15
+ * exchange here — this is what lets WorkBuddy's "kill auth, poll status"
16
+ * flow complete without the auth process staying alive.
17
+ */
18
+ function loggedIn(token) {
19
+ const c = decodeJwtPayload(token.id_token) ?? {};
20
+ const who = c.name ?? c.preferred_username ?? c.sub ?? "unknown";
21
+ process.stdout.write(`Logged in as ${String(who)}\n`);
22
+ process.exit(0);
23
+ }
24
+ function notLoggedIn(reason) {
25
+ process.stdout.write(`Not authenticated: ${reason}\n`);
26
+ process.exit(1);
27
+ }
28
+ var status_default = defineCommand({
29
+ meta: {
30
+ name: "status",
31
+ description: "认证状态检测(exit 0 = 已登录;可完成待授权的 device flow)"
32
+ },
33
+ args: { "auth-base": {
34
+ type: "string",
35
+ description: "覆盖 auth base URL"
36
+ } },
37
+ async run({ args }) {
38
+ const config = resolveConfig({ authBase: args["auth-base"] });
39
+ const cached = await readToken();
40
+ if (isAccessTokenValid(cached)) loggedIn(cached);
41
+ if (cached?.refresh_token) try {
42
+ loggedIn(await writeToken(await refreshToken(config, cached.refresh_token)));
43
+ } catch {
44
+ await clearToken();
45
+ }
46
+ const pending = await readPendingAuth();
47
+ if (!pending) notLoggedIn("run `xiaobao-cli auth login`");
48
+ if (pending.expires_at <= Date.now()) {
49
+ await clearPendingAuth();
50
+ notLoggedIn("device authorization expired, run `xiaobao-cli auth login` again");
51
+ }
52
+ try {
53
+ const result = await exchangeDeviceCode(config, pending.device_code);
54
+ if (result === "pending" || result === "slow_down") notLoggedIn("awaiting authorization in browser");
55
+ const saved = await writeToken(result);
56
+ await clearPendingAuth();
57
+ loggedIn(saved);
58
+ } catch (err) {
59
+ await clearPendingAuth();
60
+ notLoggedIn(`device authorization failed (${err?.code ?? "error"}), run \`xiaobao-cli auth login\` again`);
61
+ }
62
+ }
63
+ });
64
+ //#endregion
65
+ export { status_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 { r as toLocalDateTime } from "./util-pyTg7qwY.mjs";
7
7
  import { defineCommand } from "citty";
8
8
  //#region src/commands/visit/summary.ts
@@ -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/audio/text.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 { 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/admin/token-usage.ts
8
8
  /**
@@ -1,5 +1,5 @@
1
1
  import { r as saveActiveProject } 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/use.ts
5
5
  /**
@@ -6,8 +6,8 @@ var visit_default = defineCommand({
6
6
  description: "客户来访分页查询 / 来访接待总结"
7
7
  },
8
8
  subCommands: {
9
- list: () => import("./list-BxWqQllQ2.mjs").then((m) => m.default),
10
- summary: () => import("./summary-CfbHddby.mjs").then((m) => m.default)
9
+ list: () => import("./list-Ca5Fvq_e.mjs").then((m) => m.default),
10
+ summary: () => import("./summary-C3poiB2C.mjs").then((m) => m.default)
11
11
  }
12
12
  });
13
13
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { i as decodeJwtPayload, s as readToken } from "./token-store-BB7n-fwJ.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/auth/whoami.ts
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puyinkai/xiaobao-cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "旺小宝 CLI — host-agnostic 业务数据 / 问数 / 来访总结 / 知识库 能力 (openclaw-xiaobao plugin 的 CLI 等价物)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,8 @@
23
23
  "scripts": {
24
24
  "build": "tsdown",
25
25
  "typecheck": "tsc --noEmit",
26
- "dev": "node --import tsx src/cli.ts"
26
+ "dev": "node --import tsx src/cli.ts",
27
+ "workbuddy:pack": "rm -rf dist-workbuddy && mkdir -p dist-workbuddy/wangxiaobao && cp workbuddy/connector-meta.json workbuddy/cli.json workbuddy/icon.svg dist-workbuddy/wangxiaobao/ && cp -R skills dist-workbuddy/wangxiaobao/skills && cd dist-workbuddy && zip -qr wangxiaobao-connector.zip wangxiaobao && echo dist-workbuddy/wangxiaobao-connector.zip"
27
28
  },
28
29
  "dependencies": {
29
30
  "citty": "^0.1.6"
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: wangxiaobao-knowledge-base
3
3
  version: 0.1.0
4
- description: "旺小宝项目知识库:语义检索项目知识 chunk(kb search)、列文档(kb docs)、看文档详情(kb doc)、分页读文档正文(kb doc-content)。search/docs 按当前激活项目隔离;doc/doc-content 按 docId 直取。只读、无副作用。高频命令: xiaobao-cli kb search '<query>' [--k N]; xiaobao-cli kb docs [--title <kw>]; xiaobao-cli kb doc <doc-id>; xiaobao-cli kb doc-content <doc-id> [--offset N] [--limit N]。何时用:用户问项目资料/楼盘知识/销售政策/户型文档/物料/知识库里有没有讲过X/某文档具体写了啥/帮我查下资料。注:search 返回 chunk 不是全文,要逐段读全文用 doc-content 翻页(看 hasMore 续翻);k 默认 5 上限 20;要业务数据问数走 quick-qa,不是这里。"
4
+ description: "旺小宝项目知识库:语义检索项目知识 chunk(kb search)、列文档(kb docs)、看文档详情(kb doc)、分页读文档正文(kb doc-content)。search/docs 按当前激活项目隔离;doc/doc-content 按 docId 直取。只读、无副作用。高频命令: xiaobao-cli kb search '<query>' [--k N]; xiaobao-cli kb docs [--title <kw>]; xiaobao-cli kb doc <doc-id>; xiaobao-cli kb doc-content <doc-id> [--offset N] [--limit N]。何时用:用户问项目资料/楼盘知识/销售政策/户型文档/物料/知识库里有没有讲过X/某文档具体写了啥/帮我查下资料。注:search 返回 chunk 不是全文,要逐段读全文用 doc-content 翻页(看 hasMore 续翻);k 默认 5 上限 20"
5
5
  metadata:
6
6
  requires:
7
7
  bins: ["xiaobao-cli"]