@workclaw/openclaw-workclaw 1.0.17 → 1.0.19

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 (147) hide show
  1. package/README.md +364 -325
  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 +263 -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 +28 -0
  20. package/dist/src/channel.d.ts +11 -0
  21. package/dist/src/channel.js +198 -0
  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/dist/src/gateway/agent-handlers.js +433 -0
  28. package/dist/src/gateway/config-writer.d.ts +71 -0
  29. package/dist/src/gateway/config-writer.js +312 -0
  30. package/dist/src/gateway/message-context.d.ts +76 -0
  31. package/dist/src/gateway/message-context.js +499 -0
  32. package/dist/src/gateway/message-dispatcher.d.ts +19 -0
  33. package/dist/src/gateway/message-dispatcher.js +512 -0
  34. package/dist/src/gateway/reconnect.d.ts +27 -0
  35. package/dist/src/gateway/reconnect.js +206 -0
  36. package/dist/src/gateway/skills-handler.d.ts +29 -0
  37. package/dist/src/gateway/skills-handler.js +576 -0
  38. package/dist/src/gateway/skills-list-handler.d.ts +27 -0
  39. package/dist/src/gateway/skills-list-handler.js +233 -0
  40. package/dist/src/gateway/tools-list-handler.d.ts +30 -0
  41. package/dist/src/gateway/tools-list-handler.js +101 -0
  42. package/dist/src/gateway/workclaw-gateway.d.ts +14 -0
  43. package/dist/src/gateway/workclaw-gateway.js +223 -0
  44. package/dist/src/media/upload.d.ts +13 -0
  45. package/dist/src/media/upload.js +125 -0
  46. package/dist/src/outbound/index.d.ts +36 -0
  47. package/dist/src/outbound/index.js +123 -0
  48. package/dist/src/outbound/workclaw-sender.d.ts +36 -0
  49. package/dist/src/outbound/workclaw-sender.js +95 -0
  50. package/dist/src/runtime.d.ts +116 -0
  51. package/dist/src/runtime.js +374 -0
  52. package/dist/src/secret-contract-api.d.ts +4 -0
  53. package/dist/src/secret-contract-api.js +4 -0
  54. package/dist/src/send.d.ts +1 -0
  55. package/dist/src/send.js +1 -0
  56. package/dist/src/setup-api.d.ts +3 -0
  57. package/dist/src/setup-api.js +3 -0
  58. package/dist/src/setup-core.d.ts +3 -0
  59. package/dist/src/setup-core.js +13 -0
  60. package/dist/src/setup-surface.d.ts +7 -0
  61. package/dist/src/setup-surface.js +363 -0
  62. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts +93 -0
  63. package/dist/src/tools/openclaw-workclaw-cron/api/index.js +209 -0
  64. package/dist/src/tools/openclaw-workclaw-cron/index.d.ts +10 -0
  65. package/{src/tools/openclaw-workclaw-cron/index.ts → dist/src/tools/openclaw-workclaw-cron/index.js} +33 -39
  66. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.d.ts +16 -0
  67. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.js +152 -0
  68. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.d.ts +18 -0
  69. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.js +162 -0
  70. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.d.ts +14 -0
  71. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.js +80 -0
  72. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.d.ts +14 -0
  73. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.js +107 -0
  74. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.d.ts +14 -0
  75. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.js +80 -0
  76. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.d.ts +14 -0
  77. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.js +107 -0
  78. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.d.ts +17 -0
  79. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.js +127 -0
  80. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.d.ts +14 -0
  81. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.js +87 -0
  82. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.d.ts +14 -0
  83. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.js +107 -0
  84. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.d.ts +17 -0
  85. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.js +164 -0
  86. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.d.ts +18 -0
  87. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.js +135 -0
  88. package/dist/src/tools/openclaw-workclaw-cron/types/index.d.ts +52 -0
  89. package/dist/src/tools/openclaw-workclaw-cron/types/index.js +4 -0
  90. package/dist/src/tools/openclaw-workclaw-cron/utils/index.d.ts +40 -0
  91. package/dist/src/tools/openclaw-workclaw-cron/utils/index.js +122 -0
  92. package/dist/src/tools/openclaw-workclaw-system/index.d.ts +10 -0
  93. package/{src/tools/openclaw-workclaw-system/index.ts → dist/src/tools/openclaw-workclaw-system/index.js} +15 -17
  94. package/dist/src/tools/openclaw-workclaw-system/src/get/index.d.ts +8 -0
  95. package/dist/src/tools/openclaw-workclaw-system/src/get/index.js +64 -0
  96. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts +8 -0
  97. package/dist/src/tools/openclaw-workclaw-system/src/token/index.js +78 -0
  98. package/dist/src/types.d.ts +39 -0
  99. package/dist/src/types.js +1 -0
  100. package/dist/src/utils/content.d.ts +15 -0
  101. package/dist/src/utils/content.js +38 -0
  102. package/openclaw.plugin.json +1 -0
  103. package/package.json +62 -42
  104. package/skills/openclaw-workclaw-cron/SKILL.md +45 -28
  105. package/index.ts +0 -302
  106. package/src/accounts.ts +0 -287
  107. package/src/api/accounts-api.ts +0 -157
  108. package/src/api/prompts-api.ts +0 -123
  109. package/src/api/session-api.ts +0 -247
  110. package/src/api/skills-api.ts +0 -74
  111. package/src/api/workspace.ts +0 -43
  112. package/src/channel.ts +0 -227
  113. package/src/config-schema.ts +0 -110
  114. package/src/connection/workclaw-client.ts +0 -656
  115. package/src/gateway/agent-handlers.ts +0 -557
  116. package/src/gateway/config-writer.ts +0 -311
  117. package/src/gateway/message-context.ts +0 -422
  118. package/src/gateway/message-dispatcher.ts +0 -601
  119. package/src/gateway/reconnect.ts +0 -149
  120. package/src/gateway/skills-handler.ts +0 -805
  121. package/src/gateway/skills-list-handler.ts +0 -332
  122. package/src/gateway/tools-list-handler.ts +0 -162
  123. package/src/gateway/workclaw-gateway.ts +0 -525
  124. package/src/media/upload.ts +0 -168
  125. package/src/outbound/index.ts +0 -183
  126. package/src/outbound/workclaw-sender.ts +0 -157
  127. package/src/runtime.ts +0 -400
  128. package/src/send.ts +0 -1
  129. package/src/tools/openclaw-workclaw-cron/api/index.ts +0 -326
  130. package/src/tools/openclaw-workclaw-cron/src/add/params.ts +0 -176
  131. package/src/tools/openclaw-workclaw-cron/src/add/sync.ts +0 -188
  132. package/src/tools/openclaw-workclaw-cron/src/disable/params.ts +0 -100
  133. package/src/tools/openclaw-workclaw-cron/src/disable/sync.ts +0 -127
  134. package/src/tools/openclaw-workclaw-cron/src/enable/params.ts +0 -100
  135. package/src/tools/openclaw-workclaw-cron/src/enable/sync.ts +0 -127
  136. package/src/tools/openclaw-workclaw-cron/src/notify/sync.ts +0 -148
  137. package/src/tools/openclaw-workclaw-cron/src/remove/params.ts +0 -109
  138. package/src/tools/openclaw-workclaw-cron/src/remove/sync.ts +0 -127
  139. package/src/tools/openclaw-workclaw-cron/src/update/params.ts +0 -197
  140. package/src/tools/openclaw-workclaw-cron/src/update/sync.ts +0 -161
  141. package/src/tools/openclaw-workclaw-cron/types/index.ts +0 -55
  142. package/src/tools/openclaw-workclaw-cron/utils/index.ts +0 -141
  143. package/src/tools/openclaw-workclaw-system/src/get/index.ts +0 -77
  144. package/src/tools/openclaw-workclaw-system/src/token/index.ts +0 -93
  145. package/src/types.ts +0 -60
  146. package/src/utils/content.ts +0 -40
  147. package/tsconfig.json +0 -11
package/src/channel.ts DELETED
@@ -1,227 +0,0 @@
1
- import type {
2
- ChannelGatewayContext,
3
- ChannelPlugin,
4
- OpenClawConfig,
5
- } from 'openclaw/plugin-sdk'
6
- import type { OpenclawWorkclawConfig, ResolvedOpenclawWorkclawAccount } from './types.js'
7
- import { appendFileSync } from 'node:fs'
8
- import { homedir } from 'node:os'
9
- import { join } from 'node:path'
10
- import {
11
- isOpenclawWorkclawAccountConfigured,
12
- listOpenclawWorkclawAccountIds,
13
- resolveOpenclawWorkclawAccount,
14
- } from './accounts.js'
15
- import { OpenclawWorkclawConfigSchema } from './config-schema.js'
16
- import { startOpenclawWorkclawGateway, stopOpenclawWorkclawGateway } from './gateway/workclaw-gateway.js'
17
- import { sendMessageOpenclawWorkclaw } from './outbound/index.js'
18
- import { getOpenclawWorkclawRuntime } from './runtime.js'
19
-
20
- const DEFAULT_ACCOUNT_ID = 'default'
21
-
22
- function buildChannelConfigSchema(schema: unknown): any {
23
- return schema
24
- }
25
-
26
- function formatPairingApproveHint(_channelId: string): string {
27
- return '请回复验证码完成配对'
28
- }
29
-
30
- const meta = {
31
- id: 'openclaw-workclaw',
32
- label: '智小途',
33
- selectionLabel: '智小途',
34
- docsPath: '/channels/openclaw-workclaw',
35
- docsLabel: '智小途',
36
- blurb: '智小途 OpenClaw通道',
37
- aliases: [],
38
- order: 90,
39
- }
40
-
41
- /**
42
- * 写入文件日志到磁盘
43
- * @param message 日志消息
44
- */
45
- function writeFileLog(message: string): void {
46
- const timestamp = new Date().toISOString()
47
- const logLine = `[${timestamp}] ${message}\n`
48
- const logDir = join(homedir(), '.openclaw', 'logs')
49
- const logFile = join(logDir, 'sendtext-outbound.log')
50
-
51
- try {
52
- appendFileSync(logFile, logLine)
53
- }
54
- catch (err) {
55
- console.error(`[writeFileLog] Failed to write log: ${err}`)
56
- }
57
- }
58
-
59
- export const openclawWorkclawDock = {
60
- id: 'openclaw-workclaw',
61
- capabilities: {
62
- chatTypes: ['direct', 'group'],
63
- media: true,
64
- blockStreaming: true,
65
- },
66
- }
67
-
68
- export const openclawWorkclawPlugin: ChannelPlugin<ResolvedOpenclawWorkclawAccount> = {
69
- id: 'openclaw-workclaw',
70
- meta,
71
- capabilities: {
72
- chatTypes: ['direct', 'group'],
73
- media: true,
74
- reactions: false,
75
- threads: false,
76
- polls: false,
77
- nativeCommands: false,
78
- blockStreaming: true,
79
- },
80
- reload: { configPrefixes: ['channels.openclaw-workclaw'] },
81
- configSchema: buildChannelConfigSchema(OpenclawWorkclawConfigSchema),
82
- config: {
83
- listAccountIds: cfg => listOpenclawWorkclawAccountIds(cfg as OpenClawConfig),
84
- resolveAccount: (cfg, accountId) =>
85
- resolveOpenclawWorkclawAccount({ cfg: cfg as OpenClawConfig, accountId }),
86
- isConfigured: account => isOpenclawWorkclawAccountConfigured(account.config),
87
- describeAccount: account => ({
88
- accountId: account.accountId,
89
- name: account.name,
90
- enabled: account.enabled,
91
- configured: isOpenclawWorkclawAccountConfigured(account.config),
92
- }),
93
- },
94
- security: {
95
- resolveDmPolicy: ({ cfg, accountId, account }) => {
96
- const resolvedAccountId = accountId ?? account.accountId ?? DEFAULT_ACCOUNT_ID
97
- const channelConfig = cfg.channels?.['openclaw-workclaw'] as OpenclawWorkclawConfig | undefined
98
- const useAccountPath = Boolean(channelConfig?.accounts?.[resolvedAccountId])
99
- const basePath = useAccountPath
100
- ? `channels.openclaw-workclaw.accounts.${resolvedAccountId}.`
101
- : 'channels.openclaw-workclaw.'
102
- return {
103
- policy: account.config.dmPolicy ?? 'pairing',
104
- allowFrom: account.config.allowFrom ?? [],
105
- policyPath: `${basePath}dmPolicy`,
106
- allowFromPath: `${basePath}allowFrom`,
107
- approveHint: formatPairingApproveHint('openclaw-workclaw'),
108
- normalizeEntry: raw => raw.replace(/^openclaw-workclaw:/i, ''),
109
- }
110
- },
111
- },
112
- status: {
113
- buildAccountSnapshot: async ({ account }) => {
114
- const { getOpenclawWorkclawWsConnection } = await import('./runtime.js')
115
- const ws = getOpenclawWorkclawWsConnection(account.accountId)
116
- const isConnected = ws && ws.readyState === 1 // WebSocket.OPEN = 1
117
-
118
- return {
119
- accountId: account.accountId,
120
- name: account.name,
121
- enabled: account.enabled,
122
- configured: account.configured,
123
- connected: isConnected,
124
- running: account.enabled && account.configured,
125
- mode: account.config.connectionMode || 'workclaw',
126
- }
127
- },
128
- },
129
- outbound: {
130
- deliveryMode: 'direct',
131
- chunker: (text: string, _limit: number) => [text],
132
- textChunkLimit: 4096,
133
- sendText: async ({ to, text, accountId, cfg, replyToId }) => {
134
- writeFileLog(`outbound sendText called: replyToId=${replyToId}, to=${to}, text=${text.substring(0, 100)}`)
135
- const result = await sendMessageOpenclawWorkclaw({
136
- accountId: accountId ?? undefined,
137
- cfg: cfg as OpenClawConfig,
138
- to,
139
- text,
140
- })
141
- return {
142
- channel: 'openclaw-workclaw',
143
- ok: true,
144
- messageId: result.messageId,
145
- }
146
- },
147
- sendMedia: async ({ to, text, mediaUrl, accountId, cfg }) => {
148
- if (!mediaUrl && !text.trim()) {
149
- throw new Error('mediaUrl is required for outbound media')
150
- }
151
- const runtime = getOpenclawWorkclawRuntime() as any
152
- const log = runtime.log ?? console.warn
153
- if (typeof log === 'function') {
154
- log(`outbound sendMedia called for ${to} with text ${text} and mediaUrl ${mediaUrl}`)
155
- }
156
- else if (log?.info) {
157
- log.info(`outbound sendMedia called for ${to} with text ${text} and mediaUrl ${mediaUrl}`)
158
- }
159
- const messageText = text.trim() ? text : mediaUrl ?? ''
160
- const result = await sendMessageOpenclawWorkclaw({
161
- accountId: accountId ?? undefined,
162
- cfg: cfg as OpenClawConfig,
163
- to,
164
- text: messageText,
165
- mediaUrl: mediaUrl ?? undefined,
166
- })
167
- return {
168
- channel: 'openclaw-workclaw',
169
- ok: true,
170
- messageId: result.messageId,
171
- }
172
- },
173
- },
174
- gateway: {
175
- startAccount: async (ctx: ChannelGatewayContext<ResolvedOpenclawWorkclawAccount>) => {
176
- const { setStatus, getStatus, account, accountId, cfg, log } = ctx
177
- log?.info?.(`startAccount called for ${accountId}`)
178
-
179
- await startOpenclawWorkclawGateway({
180
- accountId,
181
- account,
182
- cfg,
183
- log,
184
- })
185
-
186
- setStatus({
187
- ...getStatus(),
188
- running: true,
189
- lastStartAt: Date.now(),
190
- lastError: null,
191
- })
192
- log?.info?.(`startAccount completed for ${accountId}, keeping pending until abort`)
193
-
194
- // 保持 pending 状态直到 abortSignal 触发(防止 OpenClaw 3.8 认为启动立即退出)
195
- await new Promise<void>((resolve) => {
196
- if (ctx.abortSignal.aborted) {
197
- resolve()
198
- return
199
- }
200
- ctx.abortSignal.addEventListener('abort', () => resolve(), { once: true })
201
- })
202
-
203
- // abort 触发后,清理资源
204
- log?.info?.(`startAccount abort signal received for ${accountId}`)
205
- const wsStrategy = (account.config as any)?.wsConnectionStrategy || 'per-account'
206
- stopOpenclawWorkclawGateway(accountId, wsStrategy)
207
- setStatus({
208
- ...getStatus(),
209
- running: false,
210
- lastStopAt: Date.now(),
211
- })
212
- },
213
- stopAccount: async (ctx: ChannelGatewayContext<ResolvedOpenclawWorkclawAccount>) => {
214
- const { setStatus, getStatus, accountId, account } = ctx
215
-
216
- // Stop WorkClaw gateway
217
- const wsStrategy = (account.config as any)?.wsConnectionStrategy || 'per-account'
218
- stopOpenclawWorkclawGateway(accountId, wsStrategy)
219
-
220
- setStatus({
221
- ...getStatus(),
222
- running: false,
223
- lastStopAt: Date.now(),
224
- })
225
- },
226
- },
227
- }
@@ -1,110 +0,0 @@
1
- import { z } from 'zod'
2
-
3
- export { z }
4
-
5
- const DmPolicySchema = z.enum(['open', 'pairing', 'allowlist'])
6
- const OpenclawWorkclawConnectionModeSchema = z.enum(['websocket'])
7
- const WsConnectionStrategySchema = z.enum(['per-account', 'per-appKey'])
8
-
9
- const DmConfigSchema = z
10
- .object({
11
- enabled: z.boolean().optional(),
12
- systemPrompt: z.string().optional(),
13
- })
14
- .strict()
15
- .optional()
16
-
17
- // Message render mode: auto (default) = detect markdown, raw = plain text, card = always card
18
- const RenderModeSchema = z.enum(['auto', 'raw', 'card']).optional()
19
- const ChannelHeartbeatVisibilitySchema = z
20
- .object({
21
- visibility: z.enum(['visible', 'hidden']).optional(),
22
- intervalMs: z.number().int().positive().optional(),
23
- })
24
- .strict()
25
- .optional()
26
-
27
- /**
28
- * Per-account config schema
29
- * Only fields that make sense to configure per-account.
30
- */
31
- export const openclawWorkclawAccountConfigSchema = z
32
- .object({
33
- enabled: z.boolean().optional(),
34
- name: z.string().optional(),
35
- agentId: z.union([z.string(), z.number()]).optional(),
36
- userId: z.union([z.string(), z.number()]).optional(),
37
- openConversationId: z.string().optional(),
38
- replyEndpoint: z.string().optional(),
39
- pushEndpoint: z.string().optional(),
40
- dmPolicy: DmPolicySchema.optional(),
41
- allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
42
- requireMention: z.boolean().optional(),
43
- historyLimit: z.number().int().min(0).optional(),
44
- dmHistoryLimit: z.number().int().min(0).optional(),
45
- dms: z.record(z.string(), DmConfigSchema).optional(),
46
- textChunkLimit: z.number().int().positive().optional(),
47
- chunkMode: z.enum(['length', 'newline']).optional(),
48
- mediaMaxMb: z.number().positive().optional(),
49
- heartbeat: ChannelHeartbeatVisibilitySchema,
50
- renderMode: RenderModeSchema,
51
- })
52
- .strict()
53
-
54
- /**
55
- * Top-level plugin config schema
56
- */
57
- export const OpenclawWorkclawConfigSchema = z
58
- .object({
59
- enabled: z.boolean().optional(),
60
- connectionMode: OpenclawWorkclawConnectionModeSchema.optional().default('websocket'),
61
- wsConnectionStrategy: WsConnectionStrategySchema.optional().default('per-account'),
62
- baseUrl: z.string().url().optional(),
63
- websocketUrl: z.string().url().optional(),
64
- appKey: z.string().optional(),
65
- appSecret: z.string().optional(),
66
- agentId: z.union([z.string(), z.number()]).optional(),
67
- localIp: z.string().optional(),
68
- userId: z.union([z.string(), z.number()]).optional(),
69
- replyEndpoint: z.string().optional(),
70
- pushEndpoint: z.string().optional(),
71
- requestTimeout: z.number().int().positive().optional(),
72
- allowInsecureTls: z.boolean().optional(),
73
- allowRawJsonPayload: z.boolean().optional(),
74
- capabilities: z.array(z.string()).optional(),
75
- uploadUrl: z.string().url().optional(),
76
- uploadFieldName: z.string().optional(),
77
- uploadHeaders: z.record(z.string(), z.string()).optional(),
78
- uploadFormFields: z
79
- .record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
80
- .optional(),
81
- uploadResponseUrlPath: z.string().optional(),
82
- dmPolicy: DmPolicySchema.optional().default('pairing'),
83
- allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
84
- historyLimit: z.number().int().min(0).optional(),
85
- dmHistoryLimit: z.number().int().min(0).optional(),
86
- dms: z.record(z.string(), DmConfigSchema).optional(),
87
- textChunkLimit: z.number().int().positive().optional(),
88
- chunkMode: z.enum(['length', 'newline']).optional(),
89
- mediaMaxMb: z.number().positive().optional(),
90
- heartbeat: ChannelHeartbeatVisibilitySchema,
91
- renderMode: RenderModeSchema,
92
- accounts: z.record(z.string(), openclawWorkclawAccountConfigSchema.optional()).optional(),
93
- })
94
- .strict()
95
- .superRefine((value, ctx) => {
96
- if (value.dmPolicy === 'open') {
97
- const allowFrom = value.allowFrom ?? []
98
- const hasWildcard = allowFrom.some(entry => String(entry).trim() === '*')
99
- if (!hasWildcard) {
100
- ctx.addIssue({
101
- code: z.ZodIssueCode.custom,
102
- path: ['allowFrom'],
103
- message:
104
- 'channels.openclaw-workclaw.dmPolicy="open" requires channels.openclaw-workclaw.allowFrom to include "*"',
105
- })
106
- }
107
- }
108
- })
109
-
110
- export const openclawWorkclawConfigSchema = OpenclawWorkclawConfigSchema