@wecom/wecom-openclaw-plugin 2026.7.2-beta.1 → 2026.8.17-beta.1

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 (183) hide show
  1. package/README.md +33 -4
  2. package/dist/index.js +14 -21
  3. package/dist/src/cli/argv.d.ts +36 -0
  4. package/dist/src/cli/argv.js +155 -0
  5. package/dist/src/cli/const.d.ts +94 -0
  6. package/dist/src/cli/const.js +107 -0
  7. package/dist/src/cli/credentials.d.ts +54 -0
  8. package/dist/src/cli/credentials.js +342 -0
  9. package/dist/src/cli/index.d.ts +5 -0
  10. package/dist/src/cli/index.js +5 -0
  11. package/dist/src/cli/legacy-tool-warning.d.ts +12 -0
  12. package/dist/src/cli/legacy-tool-warning.js +20 -0
  13. package/dist/src/cli/locate.d.ts +32 -0
  14. package/dist/src/cli/locate.js +196 -0
  15. package/dist/src/cli/process-launcher.d.ts +1 -0
  16. package/dist/src/cli/process-launcher.js +1 -0
  17. package/dist/src/cli/process-output.d.ts +14 -0
  18. package/dist/src/cli/process-output.js +43 -0
  19. package/dist/src/cli/tool.d.ts +46 -0
  20. package/dist/src/cli/tool.js +363 -0
  21. package/dist/src/const.d.ts +0 -8
  22. package/dist/src/const.js +0 -14
  23. package/dist/src/monitor.js +1 -12
  24. package/dist/src/state-manager.d.ts +0 -19
  25. package/dist/src/state-manager.js +1 -34
  26. package/dist/src/utils.d.ts +27 -0
  27. package/openclaw.plugin.json +1 -1
  28. package/package.json +3 -3
  29. package/skills/wecom-send-media/SKILL.md +2 -0
  30. package/skills/wecom-send-template-card/SKILL.md +1 -1
  31. package/skills/wecomcli-calendar/SKILL.md +302 -0
  32. package/skills/wecomcli-calendar/references/calendar-agenda.md +228 -0
  33. package/skills/wecomcli-calendar/references/calendar-cancel.md +110 -0
  34. package/skills/wecomcli-calendar/references/calendar-create.md +240 -0
  35. package/skills/wecomcli-calendar/references/calendar-freebusy.md +209 -0
  36. package/skills/wecomcli-calendar/references/calendar-meeting-room.md +172 -0
  37. package/skills/wecomcli-calendar/references/calendar-search.md +208 -0
  38. package/skills/wecomcli-calendar/references/calendar-update.md +274 -0
  39. package/skills/wecomcli-contact/SKILL.md +59 -0
  40. package/skills/wecomcli-disk/SKILL.md +401 -0
  41. package/skills/wecomcli-doc/SKILL.md +140 -0
  42. package/skills/wecomcli-doc/references/doc-contents-append.md +22 -0
  43. package/skills/wecomcli-doc/references/doc-contents-overwrite.md +29 -0
  44. package/skills/wecomcli-doc/references/doc-create.md +161 -0
  45. package/skills/wecomcli-doc/scripts/build_docx.py +1375 -0
  46. package/skills/wecomcli-doc-manage/SKILL.md +135 -0
  47. package/skills/wecomcli-doc-manage/references/doc-members-update.md +26 -0
  48. package/skills/wecomcli-doc-manage/references/doc-names-update.md +22 -0
  49. package/skills/wecomcli-doc-manage/references/doc-rules-update.md +24 -0
  50. package/skills/wecomcli-email/SKILL.md +216 -0
  51. package/skills/wecomcli-email/references/forward-mail.md +131 -0
  52. package/skills/wecomcli-email/references/get-mail.md +168 -0
  53. package/skills/wecomcli-email/references/reply-mail.md +140 -0
  54. package/skills/wecomcli-email/references/search-mail.md +113 -0
  55. package/skills/wecomcli-email/references/security.md +53 -0
  56. package/skills/wecomcli-email/references/send-mail.md +186 -0
  57. package/skills/wecomcli-email/references/send-schedule.md +83 -0
  58. package/skills/wecomcli-media/SKILL.md +100 -0
  59. package/skills/wecomcli-meeting/SKILL.md +374 -0
  60. package/skills/wecomcli-meeting/references/meeting-cancel.md +115 -0
  61. package/skills/wecomcli-meeting/references/meeting-create.md +169 -0
  62. package/skills/wecomcli-meeting/references/meeting-list.md +228 -0
  63. package/skills/wecomcli-meeting/references/meeting-original-get.md +100 -0
  64. package/skills/wecomcli-meeting/references/meeting-search.md +175 -0
  65. package/skills/wecomcli-meeting/references/meeting-update.md +219 -0
  66. package/skills/wecomcli-message/SKILL.md +213 -0
  67. package/skills/wecomcli-preflight/SKILL.md +147 -0
  68. package/skills/wecomcli-sheet/SKILL.md +177 -0
  69. package/skills/wecomcli-sheet/references/sheet-contents-update.md +49 -0
  70. package/skills/wecomcli-sheet/references/sheet-ranges-get.md +47 -0
  71. package/skills/wecomcli-sheet/references/sheet-rows-append.md +47 -0
  72. package/skills/wecomcli-sheet/references/sheet-subsheets-add.md +28 -0
  73. package/skills/wecomcli-sheet/references/sheet-subsheets-delete.md +22 -0
  74. package/skills/wecomcli-smartpage/SKILL.md +172 -0
  75. package/skills/wecomcli-smartpage/references/data-driven-pages.md +50 -0
  76. package/skills/wecomcli-smartpage/references/formula/arraylist.md +369 -0
  77. package/skills/wecomcli-smartpage/references/formula/datetime.md +283 -0
  78. package/skills/wecomcli-smartpage/references/formula/logic.md +247 -0
  79. package/skills/wecomcli-smartpage/references/formula/math.md +362 -0
  80. package/skills/wecomcli-smartpage/references/formula/operators.md +246 -0
  81. package/skills/wecomcli-smartpage/references/formula/pageblock.md +76 -0
  82. package/skills/wecomcli-smartpage/references/formula/templates.md +410 -0
  83. package/skills/wecomcli-smartpage/references/formula/text.md +377 -0
  84. package/skills/wecomcli-smartpage/references/formula/user.md +22 -0
  85. package/skills/wecomcli-smartpage/references/formula-reference.md +192 -0
  86. package/skills/wecomcli-smartpage/references/mdx-syntax.md +739 -0
  87. package/skills/wecomcli-smartpage/references/smartpage-edit.md +519 -0
  88. package/skills/wecomcli-smartsheet/SKILL.md +153 -0
  89. package/skills/wecomcli-smartsheet/assets/templates/README.md +53 -0
  90. package/skills/wecomcli-smartsheet/assets/templates/ai_efficiency.md +709 -0
  91. package/skills/wecomcli-smartsheet/assets/templates/connect_to_app.md +380 -0
  92. package/skills/wecomcli-smartsheet/assets/templates/financial_accounting.md +369 -0
  93. package/skills/wecomcli-smartsheet/assets/templates/hr_and_administration.md +475 -0
  94. package/skills/wecomcli-smartsheet/assets/templates/ledger_records.md +156 -0
  95. package/skills/wecomcli-smartsheet/assets/templates/manufacturing.md +395 -0
  96. package/skills/wecomcli-smartsheet/assets/templates/marketing.md +186 -0
  97. package/skills/wecomcli-smartsheet/assets/templates/office_essentials.md +299 -0
  98. package/skills/wecomcli-smartsheet/assets/templates/personal_efficiency.md +70 -0
  99. package/skills/wecomcli-smartsheet/assets/templates/procurement_logistics.md +325 -0
  100. package/skills/wecomcli-smartsheet/assets/templates/project_management.md +564 -0
  101. package/skills/wecomcli-smartsheet/assets/templates/rd_process_customer.md +222 -0
  102. package/skills/wecomcli-smartsheet/assets/templates/rd_process_ops.md +105 -0
  103. package/skills/wecomcli-smartsheet/assets/templates/rd_process_project.md +109 -0
  104. package/skills/wecomcli-smartsheet/assets/templates/rd_process_research.md +92 -0
  105. package/skills/wecomcli-smartsheet/assets/templates/sales_and_operations.md +446 -0
  106. package/skills/wecomcli-smartsheet/assets/templates/store_management.md +431 -0
  107. package/skills/wecomcli-smartsheet/assets/templates/team_tasks.md +274 -0
  108. package/skills/wecomcli-smartsheet/assets/templates/wechat_customer.md +384 -0
  109. package/skills/wecomcli-smartsheet/assets/templates/work_report.md +100 -0
  110. package/skills/wecomcli-smartsheet/references/common.md +145 -0
  111. package/skills/wecomcli-smartsheet/references/smart-sheet-chart-types.md +95 -0
  112. package/skills/wecomcli-smartsheet/references/smart-sheet-edit.md +611 -0
  113. package/skills/wecomcli-smartsheet/references/smart-sheet-field-types.md +438 -0
  114. package/skills/wecomcli-smartsheet/references/smart-sheet-formula.md +845 -0
  115. package/skills/wecomcli-smartsheet/references/smart-sheet-read.md +411 -0
  116. package/skills/wecomcli-smartsheet/references/smart-sheet-record-values.md +203 -0
  117. package/skills/wecomcli-smartsheet/references/smart-sheet-view-types.md +356 -0
  118. package/skills/{wecom-smartsheet/references/webhook-examples.md → wecomcli-smartsheet/references/smart-sheet-webhook-examples.md} +23 -32
  119. package/skills/wecomcli-smartsheet/references/smart-sheet-webhook.md +169 -0
  120. package/skills/wecomcli-todo/SKILL.md +75 -0
  121. package/skills/wecomcli-todo/references/todo-create.md +139 -0
  122. package/skills/wecomcli-todo/references/todo-delete.md +65 -0
  123. package/skills/wecomcli-todo/references/todo-finish.md +74 -0
  124. package/skills/wecomcli-todo/references/todo-get.md +68 -0
  125. package/skills/wecomcli-todo/references/todo-list.md +135 -0
  126. package/skills/wecomcli-todo/references/todo-update.md +114 -0
  127. package/dist/src/mcp/index.d.ts +0 -6
  128. package/dist/src/mcp/index.js +0 -10
  129. package/dist/src/mcp/interceptors/biz-error.d.ts +0 -11
  130. package/dist/src/mcp/interceptors/biz-error.js +0 -69
  131. package/dist/src/mcp/interceptors/doc-auth-error.d.ts +0 -10
  132. package/dist/src/mcp/interceptors/doc-auth-error.js +0 -171
  133. package/dist/src/mcp/interceptors/index.d.ts +0 -35
  134. package/dist/src/mcp/interceptors/index.js +0 -72
  135. package/dist/src/mcp/interceptors/msg-media.d.ts +0 -11
  136. package/dist/src/mcp/interceptors/msg-media.js +0 -133
  137. package/dist/src/mcp/interceptors/smartpage-create.d.ts +0 -30
  138. package/dist/src/mcp/interceptors/smartpage-create.js +0 -132
  139. package/dist/src/mcp/interceptors/smartpage-export.d.ts +0 -17
  140. package/dist/src/mcp/interceptors/smartpage-export.js +0 -87
  141. package/dist/src/mcp/interceptors/smartsheet-upload.d.ts +0 -22
  142. package/dist/src/mcp/interceptors/smartsheet-upload.js +0 -263
  143. package/dist/src/mcp/interceptors/types.d.ts +0 -64
  144. package/dist/src/mcp/interceptors/types.js +0 -7
  145. package/dist/src/mcp/schema.d.ts +0 -11
  146. package/dist/src/mcp/schema.js +0 -99
  147. package/dist/src/mcp/tool.d.ts +0 -63
  148. package/dist/src/mcp/tool.js +0 -224
  149. package/dist/src/mcp/transport.d.ts +0 -94
  150. package/dist/src/mcp/transport.js +0 -549
  151. package/skills/wecom-contact/SKILL.md +0 -162
  152. package/skills/wecom-doc/SKILL.md +0 -127
  153. package/skills/wecom-meeting/SKILL.md +0 -441
  154. package/skills/wecom-meeting/references/example-full.md +0 -30
  155. package/skills/wecom-meeting/references/example-reminder.md +0 -46
  156. package/skills/wecom-meeting/references/example-security.md +0 -22
  157. package/skills/wecom-meeting/references/response-get-meeting-info.md +0 -148
  158. package/skills/wecom-msg/SKILL.md +0 -157
  159. package/skills/wecom-msg/references/api-get-messages.md +0 -93
  160. package/skills/wecom-msg/references/api-get-msg-chat-list.md +0 -58
  161. package/skills/wecom-msg/references/api-get-msg-media.md +0 -44
  162. package/skills/wecom-msg/references/api-send-message.md +0 -39
  163. package/skills/wecom-preflight/SKILL.md +0 -141
  164. package/skills/wecom-schedule/SKILL.md +0 -161
  165. package/skills/wecom-schedule/references/api-check-availability.md +0 -56
  166. package/skills/wecom-schedule/references/api-create-schedule.md +0 -38
  167. package/skills/wecom-schedule/references/api-get-schedule-detail.md +0 -81
  168. package/skills/wecom-schedule/references/api-update-schedule.md +0 -32
  169. package/skills/wecom-schedule/references/ref-reminders.md +0 -24
  170. package/skills/wecom-sheet/SKILL.md +0 -131
  171. package/skills/wecom-sheet/references/sheet-add-sub.md +0 -54
  172. package/skills/wecom-sheet/references/sheet-append-data.md +0 -64
  173. package/skills/wecom-sheet/references/sheet-delete-sub.md +0 -38
  174. package/skills/wecom-sheet/references/sheet-update-range-data.md +0 -95
  175. package/skills/wecom-smartpage/SKILL.md +0 -119
  176. package/skills/wecom-smartpage/references/smartpage-create.md +0 -130
  177. package/skills/wecom-smartpage/references/smartpage-export.md +0 -168
  178. package/skills/wecom-smartsheet/SKILL.md +0 -241
  179. package/skills/wecom-smartsheet/references/smartsheet-cell-value-formats.md +0 -163
  180. package/skills/wecom-smartsheet/references/smartsheet-field-types.md +0 -44
  181. package/skills/wecom-smartsheet/references/smartsheet-get-records.md +0 -187
  182. package/skills/wecom-smartsheet/references/webhook-fallback.md +0 -183
  183. package/skills/wecom-todo/SKILL.md +0 -272
package/README.md CHANGED
@@ -17,9 +17,9 @@
17
17
 
18
18
  # 🤖 WeCom OpenClaw Plugin
19
19
 
20
- **WeCom channel plugin for [OpenClaw](https://github.com/openclaw)** — by the Tencent WeCom team.
20
+ **WeCom channel and business capability plugin for [OpenClaw](https://github.com/openclaw)** — by the Tencent WeCom team.
21
21
 
22
- > A channel plugin powered by WeCom. Supports **Bot mode** (WebSocket long-polling or HTTP webhook with JSON callbacks) and **Agent mode** (HTTP webhook with XML encrypted callbacks). Direct messages, group chats, streaming replies, and proactive messaging.
22
+ > A channel and business capability plugin powered by WeCom. Supports **Bot mode** (WebSocket long-polling or HTTP webhook with JSON callbacks), **Agent mode** (HTTP webhook with XML encrypted callbacks), direct messages, group chats, streaming replies, proactive messaging, and built-in `wecom-cli` business operations.
23
23
 
24
24
  ---
25
25
 
@@ -41,8 +41,7 @@
41
41
  - 🔒 Built-in access control: DM Policy (pairing / open / allowlist / disabled) and Group Policy (open / allowlist / disabled)
42
42
  - 🔑 Command authorization: per-account command permission control with access group support
43
43
  - 👥 Multi-account support: run multiple WeCom accounts with independent bot/agent configs
44
- - 🧩 MCP tool integration (`wecom_mcp`) with interceptor pipeline (biz-error, media, smartpage-create, smartpage-export)
45
- - 🎯 **15 built-in Skills**: contact lookup, doc management, todo, meeting, schedule, messaging, smartsheet, template cards, and more
44
+ - 🧰 Built-in business Skills powered by the plugin-provided `wecom-cli` tool
46
45
  - 🔀 Dynamic Agent routing: auto-create isolated agents per user/group
47
46
  - 📁 Local file sending with configurable media path allowlist (`mediaLocalRoots`)
48
47
  - 📊 Smart media size limits with auto-downgrade (image 10MB → file, video 10MB → file, voice 2MB/AMR-only → file, max 20MB)
@@ -51,6 +50,25 @@
51
50
  - 🛡️ Anti-kick protection: suppresses auto-restart on server-side disconnection to prevent mutual kicking loops
52
51
  - 🧙 Interactive CLI setup wizard
53
52
 
53
+ ### Enterprise Business Capabilities
54
+
55
+ The plugin includes the `wecom-cli` tool and corresponding Skills, covering the following WeCom business domains:
56
+
57
+ | Domain | Capabilities |
58
+ |---|---|
59
+ | 💬 Messaging | Proactively send messages to direct or group chats that recently interacted with the bot; supports Markdown, image, file, voice, and video messages |
60
+ | 📧 Email | Send, reply to, and forward email; search messages and retrieve full email details |
61
+ | 📄 Documents | Create, import, read, append to, and overwrite online documents |
62
+ | 🗂️ Document Management | Search across multiple document types; rename online documents, spreadsheets, smart sheets, and smart documents; manage members, permissions, and join rules |
63
+ | 📊 Spreadsheets | Create online spreadsheets, import CSV/Excel files, read and update content, append rows, and manage sheets |
64
+ | 🧮 Smart Sheets | Create smart sheets; manage sheets, fields, records, views, charts, and row/column styles |
65
+ | 📰 Smart Documents | Create smart documents, retrieve and edit page content, and access embedded data table information |
66
+ | ✅ Todo | Create, read, update, and delete todo items; assign participants and mark items as complete |
67
+ | 📅 Calendar | Create, read, update, and delete events; manage participants, query attendee availability, and search or reserve meeting rooms |
68
+ | 🎥 Meetings | Schedule, cancel, and update meetings; manage attendees, query meeting lists and details, and retrieve minutes and transcripts |
69
+ | 💾 WeDrive | Search files, retrieve file metadata, and upload or download files |
70
+ | 👤 Contacts | Search members by name, pinyin, or alias and retrieve member details for meetings, calendar events, and other multi-user workflows |
71
+
54
72
  ---
55
73
 
56
74
  ## 🚀 Getting Started
@@ -102,6 +120,17 @@ openclaw config set channels.wecom.enabled true
102
120
  openclaw gateway restart
103
121
  ```
104
122
 
123
+ ### Enable Business Tools
124
+
125
+ The enterprise business capabilities above are exposed through the plugin-provided `wecom-cli` tool. Unless `tools.profile` is set to `full`, allow the plugin and restart the Gateway:
126
+
127
+ ```shell
128
+ openclaw config set tools.alsoAllow '["wecom-openclaw-plugin"]'
129
+ openclaw gateway restart
130
+ ```
131
+
132
+ > Allowing the plugin ID enables all tools currently or subsequently registered by this plugin. If `tools.alsoAllow` already contains other entries, merge `wecom-openclaw-plugin` into the existing array instead of replacing it.
133
+
105
134
  ### Mode Overview
106
135
 
107
136
  The plugin supports two connection modes that can be used independently or together:
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { emptyPluginConfigSchema } from "./src/openclaw-compat.js";
2
2
  import { wecomPlugin } from "./src/channel.js";
3
- import { createWeComMcpTool } from "./src/mcp/index.js";
4
- import { getSessionChatInfo } from "./src/state-manager.js";
3
+ import { createWeComCliTool, CLI_TOOL_NAME } from "./src/cli/index.js";
4
+ import { LEGACY_TOOL_WARNING, shouldWarnLegacyToolAllow, } from "./src/cli/legacy-tool-warning.js";
5
5
  import { setWeComRuntime } from "./src/runtime.js";
6
6
  import { CHANNEL_ID, WEBHOOK_PATHS } from "./src/const.js";
7
7
  import { createWecomAgentWebhookHandler } from "./src/agent/webhook.js";
@@ -13,25 +13,16 @@ const plugin = {
13
13
  configSchema: emptyPluginConfigSchema(),
14
14
  register(api) {
15
15
  setWeComRuntime(api.runtime);
16
+ if (shouldWarnLegacyToolAllow(api.config.tools)) {
17
+ api.logger.warn(LEGACY_TOOL_WARNING);
18
+ }
16
19
  api.registerChannel({ plugin: wecomPlugin });
17
- // 注册 wecom_mcp:通过 HTTP 直接调用企业微信 MCP Server
20
+ // 注册 wecom-cli:包装 @wecom/cli 二进制,按会话所属bot 注入独立配置目录
18
21
  api.registerTool((ctx) => {
19
- const trustedRequesterUserId = ctx.messageChannel === CHANNEL_ID ? ctx.requesterSenderId?.trim() ?? undefined : undefined;
20
- // 按 sessionKey 精确取回「原始大小写」的 chatId / chatType。
21
- // 数据由 monitor.ts 在消息入站时通过 setSessionChatInfo 写入,
22
- // 避免 parseSessionKeyChat 反解导致 chatId 被 OpenClaw core 小写化
23
- // (小写后的 chatId 调用企业微信 aibot_send_biz_msg 会报 invalid chatid)。
24
- const sessionChat = getSessionChatInfo(ctx.sessionKey);
25
- console.log(`[mcp] registerTool ctx: sessionKey="${ctx.sessionKey}", messageChannel="${ctx.messageChannel}", ` +
26
- `requesterSenderId="${ctx.requesterSenderId}", agentAccountId="${ctx.agentAccountId}", ` +
27
- `sessionChat=${JSON.stringify(sessionChat)}`);
28
- return createWeComMcpTool({
29
- requesterUserId: trustedRequesterUserId,
30
- accountId: ctx.agentAccountId,
31
- chatId: sessionChat?.chatId,
32
- chatType: sessionChat?.chatType,
33
- });
34
- }, { name: "wecom_mcp" });
22
+ console.log(`[wecom-cli:tool] registerTool ctx: sessionKey="${ctx.sessionKey}", ` +
23
+ `messageChannel="${ctx.messageChannel}", agentAccountId="${ctx.agentAccountId}"`);
24
+ return createWeComCliTool({ accountId: ctx.agentAccountId });
25
+ }, { name: CLI_TOOL_NAME });
35
26
  const agentWebhookHandler = createWecomAgentWebhookHandler(api.runtime);
36
27
  // 注册 Agent 模式 HTTP 路由(prefix match 覆盖带 accountId 的子路径)
37
28
  api.registerHttpRoute({
@@ -57,7 +48,7 @@ const plugin = {
57
48
  match: "prefix",
58
49
  });
59
50
  }
60
- // 注入媒体发送指令和文件大小限制提示词(仅对企业微信 channel 生效)
51
+ // 注入企业微信专用工具约束、媒体发送指令和文件大小限制提示词(仅对企业微信 channel 生效)
61
52
  api.on("before_prompt_build", (_event, ctx) => {
62
53
  // 只在企业微信 channel 的会话中注入,避免影响其他 channel 插件
63
54
  if (ctx?.channelId !== CHANNEL_ID) {
@@ -65,8 +56,10 @@ const plugin = {
65
56
  }
66
57
  return {
67
58
  appendSystemContext: [
59
+ "重要:企业微信通讯录、文档、会议、日程、待办、智能表格等能力必须调用专用 `wecom-cli` tool。禁止通过 exec、bash、shell、npx 或全局命令运行 wecom-cli;专用 tool 内部自行寻址并启动二进制是正常实现,不属于此禁止范围。",
60
+ "重要:即使 `wecom-cli` tool 调用失败、不可见、权限不足或提示授权,也不得降级到 exec 或手动执行 auth init;应向用户返回工具权限或 `channels.wecom` 配置问题。调用 tool 时,`args` 只传 wecom-cli 后面的参数,不传命令前缀、WECOM_CLI_* 环境变量或配置目录。",
68
61
  "重要:涉及发送图片/视频/语音/文件给用户时,请务必使用 `MEDIA:` 指令。详见 wecom-send-media 这个 skill(技能)。",
69
- "重要:当需要向用户发送结构化卡片消息(如通知、投票、按钮选择等)时,请在回复中直接输出 JSON 代码块(```json ... ```),其中 card_type 字段标明卡片类型。详见 wecom-send-template-card 技能。"
62
+ "重要:当需要向用户发送结构化卡片消息(如通知、投票、按钮选择等)时,请在回复中直接输出 JSON 代码块(```json ... ```),其中 card_type 字段标明卡片类型。详见 wecom-send-template-card 技能。",
70
63
  ].join("\n"),
71
64
  };
72
65
  });
@@ -0,0 +1,36 @@
1
+ /**
2
+ * argv 解析与安全校验
3
+ *
4
+ * tool 入参刻意对齐 cli 命令行本身(`args` = `wecom-cli ` 之后的全部内容),
5
+ * 这样 skills 里的命令表、参数说明、返回字段表都不需要改写。
6
+ *
7
+ * 但"对齐命令行"不等于"走shell"——spawn 一律 `shell: false`,
8
+ * 这里只做极简词法切分:认单引号 / 双引号 / 反斜杠,遇到任何 shell
9
+ * 元字符直接拒绝(出现元字符说明模型在拼 shell,而不是在传参数)。
10
+ */
11
+ export declare class CliArgvError extends Error {
12
+ }
13
+ /**
14
+ * 极简 POSIX-ish 词法切分。
15
+ *
16
+ * 支持:
17
+ * 'single quoted' → 内部原样,不做任何转义
18
+ * "double quoted" → 支持 \" \\ 转义
19
+ * bare\ token → 反斜杠转义空格
20
+ * 不支持(且拒绝):裸的管道、重定向、命令组合。
21
+ *
22
+ * shell 组合符的检查是**引号感知**的:只有引号外的裸字符才会被拒绝。
23
+ * 这样 `--json '{"a":1}'` 和 `--json {"a":1}` 都能通过,
24
+ * 而 `... | jq .` 里裸的管道符会被拦住。
25
+ */
26
+ export declare function tokenize(input: string): string[];
27
+ /**
28
+ * 安全校验。
29
+ *
30
+ * 关键点:`WECOM_CLI_CONFIG_DIR` 由服务端按当前会话的 bot 注入,
31
+ * 模型既看不到也改不了。这里额外拦住模型试图自行覆盖配置目录/端点的行为——
32
+ * 一旦被覆盖,就可能拿 A 企业的凭据调 B 企业的接口。
33
+ */
34
+ export declare function assertSafeArgv(argv: string[]): void;
35
+ /** 归一化 tool 入参为 argv 数组,并完成安全校验 */
36
+ export declare function normalizeArgs(args: unknown): string[];
@@ -0,0 +1,155 @@
1
+ /**
2
+ * argv 解析与安全校验
3
+ *
4
+ * tool 入参刻意对齐 cli 命令行本身(`args` = `wecom-cli ` 之后的全部内容),
5
+ * 这样 skills 里的命令表、参数说明、返回字段表都不需要改写。
6
+ *
7
+ * 但"对齐命令行"不等于"走shell"——spawn 一律 `shell: false`,
8
+ * 这里只做极简词法切分:认单引号 / 双引号 / 反斜杠,遇到任何 shell
9
+ * 元字符直接拒绝(出现元字符说明模型在拼 shell,而不是在传参数)。
10
+ */
11
+ import { CLI_FORBIDDEN_AUTH_ACTIONS, CLI_FORBIDDEN_SUBCOMMANDS, CLI_SHELL_METACHARS, CLI_SUBCOMMAND_RE, } from "./const.js";
12
+ export class CliArgvError extends Error {
13
+ }
14
+ /**
15
+ * 极简 POSIX-ish 词法切分。
16
+ *
17
+ * 支持:
18
+ * 'single quoted' → 内部原样,不做任何转义
19
+ * "double quoted" → 支持 \" \\ 转义
20
+ * bare\ token → 反斜杠转义空格
21
+ * 不支持(且拒绝):裸的管道、重定向、命令组合。
22
+ *
23
+ * shell 组合符的检查是**引号感知**的:只有引号外的裸字符才会被拒绝。
24
+ * 这样 `--json '{"a":1}'` 和 `--json {"a":1}` 都能通过,
25
+ * 而 `... | jq .` 里裸的管道符会被拦住。
26
+ */
27
+ export function tokenize(input) {
28
+ const out = [];
29
+ let cur = "";
30
+ let has = false;
31
+ let i = 0;
32
+ while (i < input.length) {
33
+ const ch = input[i];
34
+ if (ch === " " || ch === "\t") {
35
+ if (has) {
36
+ out.push(cur);
37
+ cur = "";
38
+ has = false;
39
+ }
40
+ i += 1;
41
+ continue;
42
+ }
43
+ if (ch === "'") {
44
+ has = true;
45
+ i += 1;
46
+ const end = input.indexOf("'", i);
47
+ if (end < 0)
48
+ throw new CliArgvError("args 中单引号未闭合");
49
+ cur += input.slice(i, end);
50
+ i = end + 1;
51
+ continue;
52
+ }
53
+ if (ch === '"') {
54
+ has = true;
55
+ i += 1;
56
+ while (i < input.length && input[i] !== '"') {
57
+ if (input[i] === "\\" && i + 1 < input.length) {
58
+ const next = input[i + 1];
59
+ cur += next === '"' || next === "\\" ? next : `\\${next}`;
60
+ i += 2;
61
+ }
62
+ else {
63
+ cur += input[i];
64
+ i += 1;
65
+ }
66
+ }
67
+ if (i >= input.length)
68
+ throw new CliArgvError("args 中双引号未闭合");
69
+ i += 1;
70
+ continue;
71
+ }
72
+ if (ch === "\\" && i + 1 < input.length) {
73
+ has = true;
74
+ cur += input[i + 1];
75
+ i += 2;
76
+ continue;
77
+ }
78
+ // 裸字符(不在任何引号内):此处才做shell 组合符检查
79
+ if (CLI_SHELL_METACHARS.test(ch)) {
80
+ throw new CliArgvError(`args 中包含未被引号包裹的 shell 组合符 ${JSON.stringify(ch)}。` +
81
+ "本 tool 直接执行 wecom-cli,不经过 shell,因此不支持管道、重定向与命令组合。" +
82
+ "若该字符是参数值的一部分,请用引号包裹,或改用数组形式的 args。");
83
+ }
84
+ // 裸的命令替换 `$(`:单独的 `$` 是合法值字符(如金额),但 `$(` 只可能是拼shell
85
+ if (ch === "$" && input[i + 1] === "(") {
86
+ throw new CliArgvError("args 中包含未被引号包裹的命令替换 `$(`。本 tool 不经过 shell 执行," +
87
+ "请直接给出参数值;若该内容是参数值的一部分,请用引号包裹或改用数组形式的 args。");
88
+ }
89
+ has = true;
90
+ cur += ch;
91
+ i += 1;
92
+ }
93
+ if (has)
94
+ out.push(cur);
95
+ return out;
96
+ }
97
+ /**
98
+ * 安全校验。
99
+ *
100
+ * 关键点:`WECOM_CLI_CONFIG_DIR` 由服务端按当前会话的 bot 注入,
101
+ * 模型既看不到也改不了。这里额外拦住模型试图自行覆盖配置目录/端点的行为——
102
+ * 一旦被覆盖,就可能拿 A 企业的凭据调 B 企业的接口。
103
+ */
104
+ export function assertSafeArgv(argv) {
105
+ if (argv.length === 0) {
106
+ throw new CliArgvError("args 不能为空,至少需要指定品类,如 `contact users search --json '{}'`");
107
+ }
108
+ const head = argv[0];
109
+ if (!CLI_SUBCOMMAND_RE.test(head)) {
110
+ throw new CliArgvError(`第一个参数 ${JSON.stringify(head)} 不是合法的子命令名。` +
111
+ `应为品类名(如 contact / doc / meeting / todo / calendar)或 auth / cache。`);
112
+ }
113
+ if (CLI_FORBIDDEN_SUBCOMMANDS.has(head)) {
114
+ throw new CliArgvError(`子命令 \`${head}\` 已被禁用:它是交互式流程且会改写全局凭据存储。` +
115
+ `企业微信凭据请在 openclaw 配置 \`channels.wecom\` 中维护。`);
116
+ }
117
+ // `auth init` 的 argv[0] 是 auth 而非 init,不在上面的顶层禁用集内,需单独拦
118
+ if (head === "auth" && argv[1] && CLI_FORBIDDEN_AUTH_ACTIONS.has(argv[1])) {
119
+ throw new CliArgvError(`\`auth ${argv[1]}\` 已被禁用:企业微信凭据由插件按当前会话的机器人自动管理,` +
120
+ `不需要(也不允许)手动授权。若提示凭据不可用,请检查 openclaw 配置 ` +
121
+ `\`channels.wecom\` 中的 botId / secret。`);
122
+ }
123
+ for (const tok of argv) {
124
+ if (/^WECOM_CLI_[A-Z_]*=/.test(tok)) {
125
+ throw new CliArgvError(`args 中不允许出现环境变量赋值 ${JSON.stringify(tok)};运行环境由插件按当前会话的机器人注入。`);
126
+ }
127
+ if (/^--config-dir(=|$)/.test(tok) || /^--home(=|$)/.test(tok)) {
128
+ throw new CliArgvError(`args 中不允许覆盖配置目录(${JSON.stringify(tok)});配置目录由插件按当前会话的机器人决定。`);
129
+ }
130
+ }
131
+ }
132
+ /** 归一化 tool 入参为 argv 数组,并完成安全校验 */
133
+ export function normalizeArgs(args) {
134
+ let argv;
135
+ if (Array.isArray(args)) {
136
+ argv = args.map((a) => {
137
+ if (typeof a === "string")
138
+ return a;
139
+ if (typeof a === "number" || typeof a === "boolean")
140
+ return String(a);
141
+ throw new CliArgvError(`args 数组元素必须是字符串,收到 ${typeof a}`);
142
+ });
143
+ }
144
+ else if (typeof args === "string") {
145
+ argv = tokenize(args);
146
+ }
147
+ else {
148
+ throw new CliArgvError(`args 必须是字符串或字符串数组,收到 ${typeof args}`);
149
+ }
150
+ // 容错:模型可能把 "wecom-cli" 本身也带上
151
+ if (argv[0] === "wecom-cli" || argv[0] === "wecom")
152
+ argv = argv.slice(1);
153
+ assertSafeArgv(argv);
154
+ return argv;
155
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * wecom-cli tool 常量
3
+ */
4
+ /** tool 名(与 openclaw.plugin.json 的 contracts.tools 必须完全一致) */
5
+ export declare const CLI_TOOL_NAME = "wecom-cli";
6
+ /**
7
+ * 日志前缀。
8
+ *
9
+ * 必须与 agent 通过 exec 直接执行 `wecom-cli` 的情形可区分——
10
+ * 两者在日志里都叫 wecom-cli,排查"串号"问题时需要靠这个前缀分辨。
11
+ */
12
+ export declare const CLI_LOG = "[wecom-cli:tool]";
13
+ /** 单次业务命令 spawn 超时(实测热缓存调用仅 300~500ms) */
14
+ export declare const CLI_TIMEOUT_MS = 45000;
15
+ /**
16
+ * `auth init` 的 spawn 超时,比业务命令短。
17
+ *
18
+ * 授权只有一次 HTTP 鉴权,30s 足够覆盖慢网。
19
+ * 更重要的是它是**唯一**能兜住"cli 写 keyring 时挂住"的手段:
20
+ * cli 的 save_key 对 keyring 失败只 warn,但 macOS Keychain 可能弹窗等待授权,
21
+ * 而 gateway 是后台进程 → 弹窗没人点 → 进程永久挂住。
22
+ */
23
+ export declare const CLI_AUTH_TIMEOUT_MS = 30000;
24
+ /** 超时后 SIGTERM 到 SIGKILL 的宽限期 */
25
+ export declare const CLI_KILL_GRACE_MS = 3000;
26
+ /** SIGKILL 后等待 close 事件的上限,超过后主动结束插件侧等待 */
27
+ export declare const CLI_KILL_FORCE_WAIT_MS = 3000;
28
+ /** 返回给模型的输出上限。openclaw 无通用截断机制,必须由插件自己兜住 */
29
+ export declare const CLI_MAX_OUTPUT_BYTES: number;
30
+ /** 同一配置目录的重签冷却,避免 secret 失效时反复撞 45009 频率超限 */
31
+ export declare const CLI_RESIGN_COOLDOWN_MS: number;
32
+ /**
33
+ * 禁止的顶层子命令。
34
+ *
35
+ * `init` 无非交互入口,会拉起cliclack /扫码流程。
36
+ */
37
+ export declare const CLI_FORBIDDEN_SUBCOMMANDS: Set<string>;
38
+ /**
39
+ * 禁止的 `auth` 子动作(`argv[0] === "auth"` 时检查 `argv[1]`)。
40
+ *
41
+ * 为什么单独拦:授权命令是 `auth init`,`argv[0]` 是 `auth` 而非 `init`,
42
+ * 不在上面的顶层禁用集内。而凭据现在完全由插件管理
43
+ * (`credentials.ts` 会按当前会话机器人 spawn `auth init --bot-id/--secret`),
44
+ * 模型自行触发只有两种结果:
45
+ * - 不带凭据 → stderr 非 TTY 下走扫码分支 → 挂到超时
46
+ * - 带凭据 → 它拿不到 secret,只能瞎猜;即便猜对也绕过了 openclaw 配置
47
+ * `auth show` / `auth status` 之类只读动作不受影响。
48
+ */
49
+ export declare const CLI_FORBIDDEN_AUTH_ACTIONS: Set<string>;
50
+ /**
51
+ * argv[0] 合法格式。
52
+ *
53
+ * 这里刻意不用"品类白名单"——品类由服务端 discovery 动态下发,
54
+ * 白名单会在cli 新增品类时过期,违背"cli 加品类、插件零改动"的目标。
55
+ */
56
+ export declare const CLI_SUBCOMMAND_RE: RegExp;
57
+ /**
58
+ * shell 组合符:仅对**未被引号包裹的裸字符**生效。
59
+ *
60
+ * 这不是安全边界——spawn 一律 `shell: false`,argv 直接交给进程,
61
+ * 不存在 shell 解释。它只是一个启发式:识别"模型在拼 shell"并给出可操作的
62
+ * 报错,而不是把管道符当参数传下去、让 cli 报一个费解的错。
63
+ *
64
+ * 因此**刻意不包含** `{}` `()` `$`:
65
+ * - `{` `}` 是 JSON 参数的必备字符(`--json '{"a":1}'`)
66
+ * - `(` `)` 会出现在成员名里(如 `张三(jackzhang22)`)
67
+ * - `$` 会出现在普通文本值里(如金额)
68
+ * 误杀合法参数的代价远大于放过一个怪参数——后者只会得到一个正常的 cli 报错。
69
+ */
70
+ export declare const CLI_SHELL_METACHARS: RegExp;
71
+ /**
72
+ * 允许从插件配置透传给 cli 的环境变量白名单。
73
+ *
74
+ * 仅供联调指向测试环境。注意这三个变量在 cli 侧受 `custom-endpoint`
75
+ * feature 门控(默认关闭),正式包上不生效。
76
+ *
77
+ * 模型提供的任何 env 一律拒绝——这里只接受插件配置来源。
78
+ */
79
+ export declare const CLI_ENV_PASSTHROUGH: readonly ["WECOM_CLI_BASE_URL", "WECOM_CLI_AUTH_ENDPOINT", "WECOM_CLI_ADDITIONAL_HEADERS"];
80
+ /** cli 侧错误码 */
81
+ export declare const CLI_ERR: {
82
+ /** AuthRequiredError:无 token 或凭据不可解密 */
83
+ readonly AUTH_REQUIRED: 893999;
84
+ /** cli token 已过期(cli 会尝试自动刷新) */
85
+ readonly TOKEN_EXPIRED: 853004;
86
+ /** cli token 无效 */
87
+ readonly TOKEN_INVALID: 853005;
88
+ /** bot_id / secret 无效或签名校验失败 */
89
+ readonly BAD_CREDENTIAL: 853000;
90
+ /** 换取 token 频率超限 */
91
+ readonly RATE_LIMITED: 45009;
92
+ };
93
+ /** 需要触发"强制重签 + 重试一次"的错误码 */
94
+ export declare const CLI_RESIGN_CODES: Set<number>;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * wecom-cli tool 常量
3
+ */
4
+ /** tool 名(与 openclaw.plugin.json 的 contracts.tools 必须完全一致) */
5
+ export const CLI_TOOL_NAME = "wecom-cli";
6
+ /**
7
+ * 日志前缀。
8
+ *
9
+ * 必须与 agent 通过 exec 直接执行 `wecom-cli` 的情形可区分——
10
+ * 两者在日志里都叫 wecom-cli,排查"串号"问题时需要靠这个前缀分辨。
11
+ */
12
+ export const CLI_LOG = "[wecom-cli:tool]";
13
+ /** 单次业务命令 spawn 超时(实测热缓存调用仅 300~500ms) */
14
+ export const CLI_TIMEOUT_MS = 45_000;
15
+ /**
16
+ * `auth init` 的 spawn 超时,比业务命令短。
17
+ *
18
+ * 授权只有一次 HTTP 鉴权,30s 足够覆盖慢网。
19
+ * 更重要的是它是**唯一**能兜住"cli 写 keyring 时挂住"的手段:
20
+ * cli 的 save_key 对 keyring 失败只 warn,但 macOS Keychain 可能弹窗等待授权,
21
+ * 而 gateway 是后台进程 → 弹窗没人点 → 进程永久挂住。
22
+ */
23
+ export const CLI_AUTH_TIMEOUT_MS = 30_000;
24
+ /** 超时后 SIGTERM 到 SIGKILL 的宽限期 */
25
+ export const CLI_KILL_GRACE_MS = 3_000;
26
+ /** SIGKILL 后等待 close 事件的上限,超过后主动结束插件侧等待 */
27
+ export const CLI_KILL_FORCE_WAIT_MS = 3_000;
28
+ /** 返回给模型的输出上限。openclaw 无通用截断机制,必须由插件自己兜住 */
29
+ export const CLI_MAX_OUTPUT_BYTES = 64 * 1024;
30
+ /** 同一配置目录的重签冷却,避免 secret 失效时反复撞 45009 频率超限 */
31
+ export const CLI_RESIGN_COOLDOWN_MS = 5 * 60 * 1000;
32
+ /**
33
+ * 禁止的顶层子命令。
34
+ *
35
+ * `init` 无非交互入口,会拉起cliclack /扫码流程。
36
+ */
37
+ export const CLI_FORBIDDEN_SUBCOMMANDS = new Set(["init"]);
38
+ /**
39
+ * 禁止的 `auth` 子动作(`argv[0] === "auth"` 时检查 `argv[1]`)。
40
+ *
41
+ * 为什么单独拦:授权命令是 `auth init`,`argv[0]` 是 `auth` 而非 `init`,
42
+ * 不在上面的顶层禁用集内。而凭据现在完全由插件管理
43
+ * (`credentials.ts` 会按当前会话机器人 spawn `auth init --bot-id/--secret`),
44
+ * 模型自行触发只有两种结果:
45
+ * - 不带凭据 → stderr 非 TTY 下走扫码分支 → 挂到超时
46
+ * - 带凭据 → 它拿不到 secret,只能瞎猜;即便猜对也绕过了 openclaw 配置
47
+ * `auth show` / `auth status` 之类只读动作不受影响。
48
+ */
49
+ export const CLI_FORBIDDEN_AUTH_ACTIONS = new Set(["init", "login", "logout", "bind", "unbind"]);
50
+ /**
51
+ * argv[0] 合法格式。
52
+ *
53
+ * 这里刻意不用"品类白名单"——品类由服务端 discovery 动态下发,
54
+ * 白名单会在cli 新增品类时过期,违背"cli 加品类、插件零改动"的目标。
55
+ */
56
+ export const CLI_SUBCOMMAND_RE = /^[a-z][a-z0-9_-]*$/;
57
+ /**
58
+ * shell 组合符:仅对**未被引号包裹的裸字符**生效。
59
+ *
60
+ * 这不是安全边界——spawn 一律 `shell: false`,argv 直接交给进程,
61
+ * 不存在 shell 解释。它只是一个启发式:识别"模型在拼 shell"并给出可操作的
62
+ * 报错,而不是把管道符当参数传下去、让 cli 报一个费解的错。
63
+ *
64
+ * 因此**刻意不包含** `{}` `()` `$`:
65
+ * - `{` `}` 是 JSON 参数的必备字符(`--json '{"a":1}'`)
66
+ * - `(` `)` 会出现在成员名里(如 `张三(jackzhang22)`)
67
+ * - `$` 会出现在普通文本值里(如金额)
68
+ * 误杀合法参数的代价远大于放过一个怪参数——后者只会得到一个正常的 cli 报错。
69
+ */
70
+ export const CLI_SHELL_METACHARS = /[;|&`<>\n\r]/;
71
+ /**
72
+ * 允许从插件配置透传给 cli 的环境变量白名单。
73
+ *
74
+ * 仅供联调指向测试环境。注意这三个变量在 cli 侧受 `custom-endpoint`
75
+ * feature 门控(默认关闭),正式包上不生效。
76
+ *
77
+ * 模型提供的任何 env 一律拒绝——这里只接受插件配置来源。
78
+ */
79
+ export const CLI_ENV_PASSTHROUGH = [
80
+ "WECOM_CLI_BASE_URL",
81
+ "WECOM_CLI_AUTH_ENDPOINT",
82
+ "WECOM_CLI_ADDITIONAL_HEADERS",
83
+ ];
84
+ /** cli 侧错误码 */
85
+ export const CLI_ERR = {
86
+ /** AuthRequiredError:无 token 或凭据不可解密 */
87
+ AUTH_REQUIRED: 893999,
88
+ /** cli token 已过期(cli 会尝试自动刷新) */
89
+ TOKEN_EXPIRED: 853004,
90
+ /** cli token 无效 */
91
+ TOKEN_INVALID: 853005,
92
+ /** bot_id / secret 无效或签名校验失败 */
93
+ BAD_CREDENTIAL: 853000,
94
+ /** 换取 token 频率超限 */
95
+ RATE_LIMITED: 45009,
96
+ };
97
+ /** 需要触发"强制重签 + 重试一次"的错误码 */
98
+ export const CLI_RESIGN_CODES = new Set([
99
+ CLI_ERR.AUTH_REQUIRED,
100
+ CLI_ERR.TOKEN_EXPIRED,
101
+ CLI_ERR.TOKEN_INVALID,
102
+ // 业务命令报 853000 = 磁盘凭据里的 secret 已失效(服务端禁用/轮换),
103
+ // 而 openclaw 配置里可能已是新 secret → 重签一次即可自愈。
104
+ // ⚠️ 注意不对称:`auth init` **自身**报 853000 表示"配置里的 secret 就是错的",
105
+ // 那种情况绝不重试(见 credentials.ts),否则只是多打一次鉴权、离45009 更近。
106
+ CLI_ERR.BAD_CREDENTIAL,
107
+ ]);
@@ -0,0 +1,54 @@
1
+ /**
2
+ * 登录态同步(ensureSynced)
3
+ *
4
+ * 职责:确保当前会话的 bot 在自己的配置目录里有可用登录态,返回该目录。
5
+ *
6
+ * **授权动作整体委托 cli**:spawn `wecom-cli auth init --bot-id <ID> --secret <SECRET>`
7
+ * (cli >= 0.1.9-build.149,stderr 非 TTY 时走直连授权分支)。
8
+ * 插件不再复刻凭据协议——签名算法、AES-GCM格式、`.encryption_key`、原子写
9
+ * 全部由 cli 负责。那些代码曾是整套方案最脆的部分:cli 改一处格式,
10
+ * 插件就静默解密失败,且表现为"未授权",完全不指向真实原因。
11
+ *
12
+ * 本文件只保留 cli 里不存在的 **openclaw 侧策略**:
13
+ * 1. 目录隔离:每个 (botId, secret) 组合一个目录 → 多 bot 隔离 + secret 轮换即时生效
14
+ * 2. 短路:`auth init` 无幂等,每次调用都会打一次鉴权接口(45009 频率限制)
15
+ * 3. 并发去重 + 全局串行
16
+ * 4. 重签冷却熔断
17
+ */
18
+ export declare class CliAuthError extends Error {
19
+ readonly errcode?: number | undefined;
20
+ constructor(message: string, errcode?: number | undefined);
21
+ }
22
+ export type CliEnvOverrides = Partial<Record<"WECOM_CLI_BASE_URL" | "WECOM_CLI_AUTH_ENDPOINT" | "WECOM_CLI_ADDITIONAL_HEADERS", string>>;
23
+ /**
24
+ * 配置目录 = `<state>/wecom-cli/<safeBotId>-<sha8(botId:secret)>`。
25
+ *
26
+ * 为什么把 secret 指纹编进目录名,而不是另外维护一份 meta 文件:
27
+ * 删掉自实现的crypto 后插件不再解密 `credentials.enc`,也就永远读不到里面的
28
+ * secret,"磁盘上这份凭据是不是用当前配置签出来的"这个问题就无法回答。
29
+ * 把指纹放进目录名后,secret 一变目录就变 → 天然没有凭据 → 自动重新授权,
30
+ * 且走的是普通路径(不碰 force 熔断),所以**改配置立即生效**。
31
+ *
32
+ * 分隔符 `:` 是必需的:否则 `ab`+`c` 与 `a`+`bc` 会得到同一指纹。
33
+ *
34
+ * 已知取舍:`safeBotId` 的字符归一化可能碰撞(`a.b` 与 `a_b` 同名),
35
+ * 清理兄弟目录时可能误删另一个 bot 的目录。代价仅是"那个 bot 下次调用
36
+ * 重新授权一次",不是数据丢失、更不是串号,因此接受。
37
+ */
38
+ export declare function cliConfigDirFor(botId: string, secret: string): string;
39
+ /**
40
+ * 确保指定 bot 的登录态已就绪,返回其配置目录。
41
+ *
42
+ * @param force 强制重新授权(业务命令报凭据类错误时的兜底),受冷却熔断约束。
43
+ * 注意 cli 没有 `--force` 参数,也不需要:`auth init` 本身无幂等,
44
+ * 每次调用都会重新签发,所以"force"只是跳过插件自己的短路。
45
+ */
46
+ export declare function ensureSynced(params: {
47
+ binPath: string;
48
+ botId: string;
49
+ secret: string;
50
+ env?: CliEnvOverrides;
51
+ force?: boolean;
52
+ }): Promise<string>;
53
+ /** 仅用于测试 */
54
+ export declare function resetCredentialState(): void;