@workclaw/openclaw-workclaw 1.0.18 → 1.0.20

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 (145) hide show
  1. package/README.md +30 -11
  2. package/dist/api.d.ts +3 -0
  3. package/dist/api.js +3 -0
  4. package/dist/index.d.ts +11 -0
  5. package/dist/index.js +264 -0
  6. package/dist/setup-entry.d.ts +2 -0
  7. package/dist/setup-entry.js +12 -0
  8. package/dist/src/accounts.d.ts +66 -0
  9. package/dist/src/accounts.js +279 -0
  10. package/dist/src/api/accounts-api.d.ts +2 -0
  11. package/dist/src/api/accounts-api.js +130 -0
  12. package/dist/src/api/prompts-api.d.ts +2 -0
  13. package/dist/src/api/prompts-api.js +103 -0
  14. package/dist/src/api/session-api.d.ts +2 -0
  15. package/dist/src/api/session-api.js +207 -0
  16. package/dist/src/api/skills-api.d.ts +2 -0
  17. package/dist/src/api/skills-api.js +64 -0
  18. package/dist/src/api/workspace.d.ts +3 -0
  19. package/dist/src/api/workspace.js +30 -0
  20. package/dist/src/channel.d.ts +11 -0
  21. package/{src/channel.ts → dist/src/channel.js} +199 -225
  22. package/dist/src/config-schema.d.ts +93 -0
  23. package/dist/src/config-schema.js +56 -0
  24. package/dist/src/connection/workclaw-client.d.ts +147 -0
  25. package/dist/src/connection/workclaw-client.js +351 -0
  26. package/dist/src/gateway/agent-handlers.d.ts +12 -0
  27. package/{src/gateway/agent-handlers.ts → dist/src/gateway/agent-handlers.js} +372 -462
  28. package/dist/src/gateway/config-writer.d.ts +71 -0
  29. package/dist/src/gateway/config-writer.js +302 -0
  30. package/dist/src/gateway/cron-tasks-handler.d.ts +19 -0
  31. package/dist/src/gateway/cron-tasks-handler.js +188 -0
  32. package/dist/src/gateway/message-context.d.ts +80 -0
  33. package/{src/gateway/message-context.ts → dist/src/gateway/message-context.js} +509 -594
  34. package/dist/src/gateway/message-dispatcher.d.ts +18 -0
  35. package/dist/src/gateway/message-dispatcher.js +572 -0
  36. package/dist/src/gateway/reconnect.d.ts +27 -0
  37. package/{src/gateway/reconnect.ts → dist/src/gateway/reconnect.js} +210 -253
  38. package/dist/src/gateway/skills-handler.d.ts +29 -0
  39. package/dist/src/gateway/skills-handler.js +615 -0
  40. package/dist/src/gateway/skills-list-handler.d.ts +27 -0
  41. package/dist/src/gateway/skills-list-handler.js +233 -0
  42. package/dist/src/gateway/tools-list-handler.d.ts +30 -0
  43. package/dist/src/gateway/tools-list-handler.js +101 -0
  44. package/dist/src/gateway/workclaw-gateway.d.ts +14 -0
  45. package/dist/src/gateway/workclaw-gateway.js +237 -0
  46. package/dist/src/media/upload.d.ts +13 -0
  47. package/dist/src/media/upload.js +125 -0
  48. package/dist/src/outbound/index.d.ts +36 -0
  49. package/dist/src/outbound/index.js +123 -0
  50. package/dist/src/outbound/workclaw-sender.d.ts +36 -0
  51. package/{src/outbound/workclaw-sender.ts → dist/src/outbound/workclaw-sender.js} +95 -158
  52. package/dist/src/runtime.d.ts +116 -0
  53. package/dist/src/runtime.js +374 -0
  54. package/dist/src/secret-contract-api.d.ts +4 -0
  55. package/dist/src/secret-contract-api.js +4 -0
  56. package/{src/send.ts → dist/src/send.d.ts} +1 -1
  57. package/dist/src/send.js +1 -0
  58. package/dist/src/setup-api.d.ts +3 -0
  59. package/dist/src/setup-api.js +3 -0
  60. package/dist/src/setup-core.d.ts +3 -0
  61. package/dist/src/setup-core.js +13 -0
  62. package/dist/src/setup-surface.d.ts +7 -0
  63. package/dist/src/setup-surface.js +363 -0
  64. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts +93 -0
  65. package/dist/src/tools/openclaw-workclaw-cron/api/index.js +209 -0
  66. package/dist/src/tools/openclaw-workclaw-cron/index.d.ts +10 -0
  67. package/{src/tools/openclaw-workclaw-cron/index.ts → dist/src/tools/openclaw-workclaw-cron/index.js} +33 -39
  68. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.d.ts +16 -0
  69. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.js +152 -0
  70. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.d.ts +18 -0
  71. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.js +162 -0
  72. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.d.ts +14 -0
  73. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.js +80 -0
  74. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.d.ts +14 -0
  75. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.js +107 -0
  76. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.d.ts +14 -0
  77. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.js +80 -0
  78. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.d.ts +14 -0
  79. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.js +107 -0
  80. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.d.ts +17 -0
  81. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.js +127 -0
  82. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.d.ts +14 -0
  83. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.js +87 -0
  84. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.d.ts +14 -0
  85. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.js +107 -0
  86. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.d.ts +17 -0
  87. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.js +164 -0
  88. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.d.ts +18 -0
  89. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.js +135 -0
  90. package/dist/src/tools/openclaw-workclaw-cron/types/index.d.ts +52 -0
  91. package/dist/src/tools/openclaw-workclaw-cron/types/index.js +4 -0
  92. package/dist/src/tools/openclaw-workclaw-cron/utils/index.d.ts +40 -0
  93. package/dist/src/tools/openclaw-workclaw-cron/utils/index.js +122 -0
  94. package/dist/src/tools/openclaw-workclaw-system/index.d.ts +10 -0
  95. package/{src/tools/openclaw-workclaw-system/index.ts → dist/src/tools/openclaw-workclaw-system/index.js} +15 -17
  96. package/dist/src/tools/openclaw-workclaw-system/src/get/index.d.ts +8 -0
  97. package/dist/src/tools/openclaw-workclaw-system/src/get/index.js +64 -0
  98. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts +8 -0
  99. package/dist/src/tools/openclaw-workclaw-system/src/token/index.js +78 -0
  100. package/{src/types.ts → dist/src/types.d.ts} +39 -58
  101. package/dist/src/types.js +1 -0
  102. package/dist/src/utils/content.d.ts +15 -0
  103. package/{src/utils/content.ts → dist/src/utils/content.js} +38 -35
  104. package/package.json +13 -9
  105. package/index.ts +0 -302
  106. package/setup-entry.ts +0 -6
  107. package/src/accounts.ts +0 -312
  108. package/src/api/accounts-api.ts +0 -156
  109. package/src/api/prompts-api.ts +0 -116
  110. package/src/api/session-api.ts +0 -238
  111. package/src/api/skills-api.ts +0 -72
  112. package/src/api/workspace.ts +0 -41
  113. package/src/config-schema.ts +0 -110
  114. package/src/connection/workclaw-client.ts +0 -643
  115. package/src/gateway/config-writer.ts +0 -296
  116. package/src/gateway/message-dispatcher.ts +0 -641
  117. package/src/gateway/skills-handler.ts +0 -741
  118. package/src/gateway/skills-list-handler.ts +0 -332
  119. package/src/gateway/tools-list-handler.ts +0 -160
  120. package/src/gateway/workclaw-gateway.ts +0 -367
  121. package/src/media/upload.ts +0 -157
  122. package/src/outbound/index.ts +0 -185
  123. package/src/runtime.ts +0 -497
  124. package/src/tools/openclaw-workclaw-cron/api/index.ts +0 -326
  125. package/src/tools/openclaw-workclaw-cron/src/add/params.ts +0 -177
  126. package/src/tools/openclaw-workclaw-cron/src/add/sync.ts +0 -188
  127. package/src/tools/openclaw-workclaw-cron/src/disable/params.ts +0 -100
  128. package/src/tools/openclaw-workclaw-cron/src/disable/sync.ts +0 -127
  129. package/src/tools/openclaw-workclaw-cron/src/enable/params.ts +0 -100
  130. package/src/tools/openclaw-workclaw-cron/src/enable/sync.ts +0 -127
  131. package/src/tools/openclaw-workclaw-cron/src/notify/sync.ts +0 -148
  132. package/src/tools/openclaw-workclaw-cron/src/remove/params.ts +0 -109
  133. package/src/tools/openclaw-workclaw-cron/src/remove/sync.ts +0 -127
  134. package/src/tools/openclaw-workclaw-cron/src/update/params.ts +0 -195
  135. package/src/tools/openclaw-workclaw-cron/src/update/sync.ts +0 -161
  136. package/src/tools/openclaw-workclaw-cron/types/index.ts +0 -55
  137. package/src/tools/openclaw-workclaw-cron/utils/index.ts +0 -141
  138. package/src/tools/openclaw-workclaw-system/src/get/index.ts +0 -77
  139. package/src/tools/openclaw-workclaw-system/src/token/index.ts +0 -93
  140. package/tests/accounts.test.ts +0 -285
  141. package/tests/message-context.test.ts +0 -313
  142. package/tests/reconnect.test.ts +0 -257
  143. package/tests/workclaw-client.test.ts +0 -112
  144. package/tsconfig.json +0 -14
  145. package/vitest.config.ts +0 -8
package/README.md CHANGED
@@ -80,7 +80,7 @@ openclaw-workclaw/
80
80
  ## ✨ 功能特性
81
81
 
82
82
  - **WebSocket 实时通信**:支持通过 WebSocket 与智小途平台保持长连接
83
- - **多账号支持**:支持 per-account 和 per-appKey 两种连接策略
83
+ - **多账号支持**:多个账号共享一个 WebSocket 连接
84
84
  - **消息收发**:支持文本消息、图片消息、语音消息的发送与接收
85
85
  - **定时任务**:内置定时任务管理工具,支持创建、修改、删除、启用/禁用定时任务
86
86
  - **流式响应**:支持流式消息输出
@@ -97,7 +97,6 @@ openclaw-workclaw/
97
97
  |--------|------|------|------|
98
98
  | enabled | boolean | 否 | 是否启用通道,默认 true |
99
99
  | connectionMode | string | 否 | 连接模式,支持 `websocket`,默认 `websocket` |
100
- | wsConnectionStrategy | string | 否 | WebSocket 连接策略,默认 `per-account` |
101
100
  | baseUrl | string | 是 | API 基础地址 |
102
101
  | websocketUrl | string | 否 | WebSocket 地址,默认根据 baseUrl 自动生成 |
103
102
  | appKey | string | 是 | 应用 Key |
@@ -108,7 +107,7 @@ openclaw-workclaw/
108
107
 
109
108
  | 配置项 | 类型 | 必填 | 说明 |
110
109
  |--------|------|------|------|
111
- | dmPolicy | string | 否 | 私信策略,默认 `pairing` |
110
+ | dmPolicy | string | 否 | 私信策略,默认 `open` |
112
111
  | allowFrom | array | 否 | 允许发送消息的用户 ID 列表 |
113
112
  | requireMention | boolean | 否 | 是否需要 @ 机器人 |
114
113
 
@@ -140,15 +139,10 @@ openclaw-workclaw/
140
139
  | 值 | 说明 |
141
140
  |----|------|
142
141
  | `open` | 开放策略,允许所有用户发送消息 |
143
- | `pairing` | 配对策略,需要用户先配对才能发送消息(默认) |
142
+ | `pairing` | 配对策略,需要用户先配对才能发送消息 |
144
143
  | `allowlist` | 白名单策略,只允许 allowFrom 列表中的用户发送消息 |
145
144
 
146
- ### wsConnectionStrategy 选项说明
147
-
148
- | 值 | 说明 |
149
- |----|------|
150
- | `per-account` | 每个账号独立建立 WebSocket 连接(默认) |
151
- | `per-appKey` | 多个账号共享一个 WebSocket 连接 |
145
+ > 当前安装向导会直接写入 `dmPolicy: "open"` 和 `allowFrom: ["*"]`,不会再让用户在向导中选择策略。
152
146
 
153
147
  ## 👥 多账号配置
154
148
 
@@ -156,9 +150,11 @@ openclaw-workclaw/
156
150
  {
157
151
  "channels": {
158
152
  "openclaw-workclaw": {
159
- "baseUrl": "https://open.workbrain.cn",
153
+ "baseUrl": "https://workbrain.cn/backend-api",
160
154
  "appKey": "your-app-key",
161
155
  "appSecret": "your-app-secret",
156
+ "dmPolicy": "open",
157
+ "allowFrom": ["*"],
162
158
  "accounts": {
163
159
  "default": {
164
160
  "agentId": "agent-001",
@@ -174,6 +170,29 @@ openclaw-workclaw/
174
170
  }
175
171
  ```
176
172
 
173
+ ## 安装向导
174
+
175
+ 当前安装向导的输入项只有:
176
+
177
+ - `App Key`
178
+ - `App Secret`
179
+ - `手机号`
180
+
181
+ 向导会自动完成:
182
+
183
+ - 获取 `accessToken`
184
+ - 通过手机号查询 `agentId`
185
+ - 通过手机号查询 `userId`
186
+ - 写入 `dmPolicy: "open"`
187
+ - 写入 `allowFrom: ["*"]`
188
+
189
+ 安装向导支持通过以下方式覆盖接口地址:
190
+
191
+ - `channels.openclaw-workclaw.baseUrl`
192
+ - `WORKCLAW_BASE_URL`
193
+ - `WORKCLAW_AUTH_BASE_URL`
194
+ - `WORKCLAW_OPEN_API_BASE_URL`
195
+
177
196
  ## ⏰ 定时任务
178
197
 
179
198
  插件内置定时任务管理工具,支持以下操作:
package/dist/api.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { workclawPlugin } from "./src/channel.js";
2
+ export * from "./src/setup-core.js";
3
+ export * from "./src/setup-surface.js";
package/dist/api.js ADDED
@@ -0,0 +1,3 @@
1
+ export { workclawPlugin } from "./src/channel.js";
2
+ export * from "./src/setup-core.js";
3
+ export * from "./src/setup-surface.js";
@@ -0,0 +1,11 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
+ declare const _default: {
3
+ id: string;
4
+ name: string;
5
+ description: string;
6
+ configSchema: import("openclaw/plugin-sdk").ChannelConfigSchema;
7
+ register: (api: OpenClawPluginApi) => void;
8
+ channelPlugin: import("openclaw/plugin-sdk").ChannelPlugin<import("./src/types.js").ResolvedWorkclawAccount>;
9
+ setChannelRuntime?: (runtime: import("openclaw/plugin-sdk").PluginRuntime) => void;
10
+ };
11
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,264 @@
1
+ import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
2
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3
+ // @ts-ignore - types from openclaw 4.2, local dev uses 3.13
4
+ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
5
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { workclawPlugin } from "./src/channel.js";
9
+ import { setWorkclawRuntime, getWorkclawRuntime, getToolResultHint, getWorkclawLogger, } from "./src/runtime.js";
10
+ import { resolveWorkspaceDir, isDefaultWorkspace } from "./src/api/workspace.js";
11
+ import { createPromptsApiHandler } from "./src/api/prompts-api.js";
12
+ import { createAccountsApiHandler } from "./src/api/accounts-api.js";
13
+ import { createSessionApiHandler } from "./src/api/session-api.js";
14
+ import { createSkillsApiHandler } from "./src/api/skills-api.js";
15
+ import { registerAllOpenclawWorkclawCronTools } from "./src/tools/openclaw-workclaw-cron/index.js";
16
+ import { getToolContext, setToolCallIdToRunIdMapping, deleteToolContext, } from "./src/runtime.js";
17
+ import { sendMessageWorkclaw } from "./src/outbound/index.js";
18
+ // ============================================================================
19
+ // Tool output formatting helpers
20
+ // ============================================================================
21
+ function formatToolParams(toolName, params) {
22
+ if (!params || typeof params !== "object") {
23
+ return "";
24
+ }
25
+ const normalizedToolName = (toolName || "").toLowerCase().trim();
26
+ const p = params;
27
+ try {
28
+ if (normalizedToolName === "exec" || normalizedToolName === "bash" || normalizedToolName === "shell") {
29
+ const cmd = p.command || p.cmd;
30
+ if (cmd)
31
+ return `command: ${String(cmd).slice(0, 200)}`;
32
+ }
33
+ else if (normalizedToolName === "read" ||
34
+ normalizedToolName === "file_read" ||
35
+ normalizedToolName === "view") {
36
+ const p2 = p.path;
37
+ if (p2)
38
+ return `path: ${p2}`;
39
+ }
40
+ else if (normalizedToolName === "write" ||
41
+ normalizedToolName === "file_write" ||
42
+ normalizedToolName === "edit" ||
43
+ normalizedToolName === "patch") {
44
+ const p2 = p.path;
45
+ if (p2)
46
+ return `path: ${p2}`;
47
+ }
48
+ else if (normalizedToolName === "web_fetch" ||
49
+ normalizedToolName === "fetch" ||
50
+ normalizedToolName === "http_get" ||
51
+ normalizedToolName === "http_request" ||
52
+ normalizedToolName === "open_url" ||
53
+ normalizedToolName === "browser_open" ||
54
+ normalizedToolName === "open") {
55
+ const u = p.url;
56
+ if (u)
57
+ return `url: ${u}`;
58
+ }
59
+ else if (normalizedToolName === "search" ||
60
+ normalizedToolName === "web_search" ||
61
+ normalizedToolName === "google_search" ||
62
+ normalizedToolName === "browser_search" ||
63
+ normalizedToolName === "browser.search") {
64
+ const q = p.query || p.q || p.search;
65
+ if (q)
66
+ return `query: ${q}`;
67
+ }
68
+ else if (normalizedToolName === "image_generate" ||
69
+ normalizedToolName === "generate_image" ||
70
+ normalizedToolName === "dalle" ||
71
+ normalizedToolName === "text_to_image") {
72
+ const prompt = p.prompt;
73
+ if (prompt)
74
+ return `prompt: ${String(prompt).slice(0, 200)}`;
75
+ }
76
+ else if (normalizedToolName === "code_interpreter" ||
77
+ normalizedToolName === "python" ||
78
+ normalizedToolName === "jupyter") {
79
+ const code = p.code;
80
+ if (code)
81
+ return `code: ${String(code).slice(0, 200)}`;
82
+ }
83
+ else if (normalizedToolName === "mcp_deliver" || normalizedToolName === "deliver") {
84
+ const target = p.target || p.to;
85
+ if (target)
86
+ return `target: ${target}`;
87
+ }
88
+ else {
89
+ const entries = Object.entries(p);
90
+ if (entries.length > 0) {
91
+ return entries
92
+ .map(([k, v]) => {
93
+ const vStr = typeof v === "string" ? v : JSON.stringify(v);
94
+ return vStr.length > 100 ? `${k}: ${vStr.slice(0, 100)}...` : `${k}: ${vStr}`;
95
+ })
96
+ .join("\n");
97
+ }
98
+ }
99
+ }
100
+ catch {
101
+ return String(params);
102
+ }
103
+ return "";
104
+ }
105
+ function formatToolOutput(toolName, params, _result) {
106
+ return formatToolParams(toolName, params);
107
+ }
108
+ // ============================================================================
109
+ // Tool hooks
110
+ // ============================================================================
111
+ function registerToolHooks(api) {
112
+ api.on("agent_end", (event, ctx) => {
113
+ const { runId } = ctx || {};
114
+ if (runId) {
115
+ deleteToolContext(runId);
116
+ api.logger?.info?.(`[ToolHook] agent_end runId=${runId} cleaned up`);
117
+ }
118
+ return event;
119
+ });
120
+ api.on("before_tool_call", (event, _ctx) => {
121
+ api.logger?.info?.(`[ToolHook] before_tool_call event=${JSON.stringify(event)}`);
122
+ });
123
+ api.on("after_tool_call", (event, _ctx) => {
124
+ api.logger?.info?.(`[ToolHook] after_tool_call event=${JSON.stringify(event)}`);
125
+ const { runId, toolCallId, toolName, params, result } = event || {};
126
+ const toolCtx = runId ? getToolContext(runId) : undefined;
127
+ if (toolCtx && result) {
128
+ const content = formatToolOutput(toolName, params, result);
129
+ if (content) {
130
+ try {
131
+ const cfg = getWorkclawRuntime().config.loadConfig();
132
+ const formattedToolOutput = {
133
+ name: getToolResultHint(toolName),
134
+ toolName: toolName,
135
+ content: content,
136
+ state: "result",
137
+ };
138
+ sendMessageWorkclaw({
139
+ cfg,
140
+ to: toolCtx.target,
141
+ text: JSON.stringify(formattedToolOutput),
142
+ msgType: "26",
143
+ accountId: toolCtx.accountId,
144
+ openConversationId: toolCtx.openConversationId,
145
+ agentId: toolCtx.agentId,
146
+ replyToMessageId: toolCtx.replyToMessageId,
147
+ }).catch((err) => {
148
+ api.logger?.error?.(`[ToolHook] after_tool_call push failed: ${err}`);
149
+ });
150
+ api.logger?.info?.(`[ToolHook] after_tool_call pushed for toolName=${toolName}`);
151
+ }
152
+ catch (err) {
153
+ api.logger?.error?.(`[ToolHook] after_tool_call push failed: ${err}`);
154
+ }
155
+ }
156
+ }
157
+ if (runId && toolCallId) {
158
+ setToolCallIdToRunIdMapping(toolCallId, runId);
159
+ }
160
+ return event;
161
+ });
162
+ api.on("tool_result_persist", (event, _ctx) => {
163
+ return { message: event.message };
164
+ });
165
+ api.logger?.info?.(`[ToolHook] Tool execution hooks registered`);
166
+ }
167
+ // ============================================================================
168
+ // Templates
169
+ // ============================================================================
170
+ const templateNames = ["SOUL.md", "IDENTITY.md"];
171
+ /**
172
+ * 获取插件所在目录,兼容 Windows 下的 file:// URL 问题。
173
+ * 4.2 的插件加载器在 Windows 上可能传入不带协议前缀的路径。
174
+ */
175
+ function getPluginDir() {
176
+ try {
177
+ const url = import.meta.url;
178
+ if (!url.startsWith("file://")) {
179
+ // Windows 路径被直接传入(不带 file:// 前缀),直接取目录
180
+ return path.dirname(url);
181
+ }
182
+ return path.dirname(fileURLToPath(url));
183
+ }
184
+ catch {
185
+ return process.cwd();
186
+ }
187
+ }
188
+ async function writeFileIfMissing(filePath, content) {
189
+ try {
190
+ await writeFile(filePath, content, { encoding: "utf-8", flag: "wx" });
191
+ }
192
+ catch (error) {
193
+ if (error &&
194
+ typeof error === "object" &&
195
+ "code" in error &&
196
+ error.code === "EEXIST") {
197
+ return;
198
+ }
199
+ throw error;
200
+ }
201
+ }
202
+ async function releaseTemplates(api) {
203
+ const workspaceDir = resolveWorkspaceDir(api);
204
+ getWorkclawLogger().info(`workspaceDir: ${workspaceDir}`);
205
+ // 模板文件在根目录的 templates/ 中,而不是 dist/templates/
206
+ const currentDir = getPluginDir();
207
+ const templatesDir = path.join(currentDir.endsWith("dist") ? path.dirname(currentDir) : currentDir, "templates");
208
+ const shouldOverwrite = isDefaultWorkspace(api);
209
+ await mkdir(workspaceDir, { recursive: true });
210
+ await Promise.all(templateNames.map(async (name) => {
211
+ const sourcePath = path.join(templatesDir, name);
212
+ const targetPath = path.join(workspaceDir, name);
213
+ const content = await readFile(sourcePath, "utf-8");
214
+ if (shouldOverwrite) {
215
+ await writeFile(targetPath, content, { encoding: "utf-8" });
216
+ }
217
+ else {
218
+ await writeFileIfMissing(targetPath, content);
219
+ }
220
+ }));
221
+ api.logger.info(`openclaw-workclaw templates ready: ${workspaceDir}`);
222
+ }
223
+ // ============================================================================
224
+ // Plugin entry point
225
+ // ============================================================================
226
+ export default defineChannelPluginEntry({
227
+ id: "openclaw-workclaw",
228
+ name: "openclaw-workclaw",
229
+ description: "智小途 channel plugin",
230
+ configSchema: emptyPluginConfigSchema(),
231
+ plugin: workclawPlugin,
232
+ registerFull(api) {
233
+ setWorkclawRuntime(api.runtime);
234
+ registerAllOpenclawWorkclawCronTools(api);
235
+ registerToolHooks(api);
236
+ api.registerService({
237
+ id: "openclaw-workclaw-templates",
238
+ start: async () => {
239
+ await releaseTemplates(api);
240
+ },
241
+ });
242
+ api.registerHttpRoute({
243
+ path: "/openclaw-workclaw/workspace/prompts",
244
+ handler: createPromptsApiHandler(api),
245
+ auth: "plugin",
246
+ });
247
+ api.registerHttpRoute({
248
+ path: "/openclaw-workclaw/accounts",
249
+ handler: createAccountsApiHandler(api),
250
+ auth: "plugin",
251
+ });
252
+ api.registerHttpRoute({
253
+ path: "/openclaw-workclaw/skills",
254
+ handler: createSkillsApiHandler(api),
255
+ auth: "plugin",
256
+ });
257
+ api.registerHttpRoute({
258
+ path: "/openclaw-workclaw/sessions",
259
+ handler: createSessionApiHandler(api),
260
+ auth: "plugin",
261
+ match: "prefix",
262
+ });
263
+ },
264
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("openclaw/plugin-sdk/channel-entry-contract").BundledChannelSetupEntryContract<import("openclaw/plugin-sdk").ChannelPlugin>;
2
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
+ export default defineBundledChannelSetupEntry({
3
+ importMetaUrl: import.meta.url,
4
+ plugin: {
5
+ specifier: "./api.js",
6
+ exportName: "workclawPlugin",
7
+ },
8
+ secrets: {
9
+ specifier: "./src/secret-contract-api.js",
10
+ exportName: "channelSecrets",
11
+ },
12
+ });
@@ -0,0 +1,66 @@
1
+ import type { OpenClawConfig } from 'openclaw/plugin-sdk';
2
+ import type { ResolvedWorkclawAccount, WorkclawConfig } from './types.js';
3
+ /**
4
+ * Normalize account ID by trimming whitespace
5
+ */
6
+ export declare function normalizeAccountId(accountId: string | null | undefined): string;
7
+ /**
8
+ * Build the lookup cache from existing accounts in cfg.
9
+ * Called once at gateway startup.
10
+ */
11
+ export declare function buildAccountMap(cfg: OpenClawConfig): void;
12
+ /**
13
+ * Resolve accountId by userId + agentId.
14
+ * First checks cache, then falls back to iteration.
15
+ */
16
+ export declare function resolveAccountByUserIdAndAgentId(cfg: OpenClawConfig, userId: string, agentId: string): string | null;
17
+ /**
18
+ * Allocate a new workspace-N accountId and register it in the map.
19
+ */
20
+ export declare function allocateWorkerAccountId(_cfg: OpenClawConfig, userId: string, agentId: string): string;
21
+ /**
22
+ * Refresh the cache when an account's userId or agentId changes.
23
+ */
24
+ export declare function refreshAccountCache(cfg: OpenClawConfig): void;
25
+ /**
26
+ * List all account IDs.
27
+ * If no accounts are configured but plugin has workclaw config, returns [DEFAULT_ACCOUNT_ID].
28
+ */
29
+ export declare function listWorkclawAccountIds(cfg: OpenClawConfig): string[];
30
+ /**
31
+ * Resolve the default account ID.
32
+ */
33
+ export declare function resolveDefaultWorkclawAccountId(cfg: OpenClawConfig): string;
34
+ export declare function isWorkclawAccountConfigured(config: {
35
+ appKey?: string;
36
+ appSecret?: string;
37
+ agentId?: string | number;
38
+ }): boolean;
39
+ /**
40
+ * Resolve a complete account with merged config.
41
+ */
42
+ export declare function resolveWorkclawAccount(params: {
43
+ cfg: OpenClawConfig;
44
+ accountId?: string | null;
45
+ }): ResolvedWorkclawAccount;
46
+ /**
47
+ * List all enabled and configured accounts.
48
+ */
49
+ export declare function listEnabledWorkclawAccounts(cfg: OpenClawConfig): ResolvedWorkclawAccount[];
50
+ /**
51
+ * Resolve account and apply cached connection config if available.
52
+ * This ensures that appKey/appSecret etc. use the stable values captured at connection time,
53
+ * not potentially mutated values from cfg at resolution time.
54
+ */
55
+ export declare function resolveWorkclawAccountWithCache(params: {
56
+ cfg: OpenClawConfig;
57
+ accountId?: string | null;
58
+ }): ResolvedWorkclawAccount;
59
+ /**
60
+ * Inspect and probe workclaw credentials.
61
+ * Returns a function that can be called to test the connection.
62
+ */
63
+ export declare function inspectWorkclawCredentials(workclawCfg?: WorkclawConfig): (() => Promise<{
64
+ ok: boolean;
65
+ botName?: string;
66
+ }>) | null;