@xmoxmo/bncr 0.0.3 → 0.0.5
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.
- package/README.md +92 -336
- package/index.ts +2 -2
- package/openclaw.plugin.json +33 -2
- package/package.json +7 -2
- package/scripts/selfcheck.mjs +38 -0
- package/src/channel.ts +287 -772
- package/src/core/accounts.ts +50 -0
- package/src/core/config-schema.ts +42 -0
- package/src/core/permissions.ts +29 -0
- package/src/core/policy.ts +27 -0
- package/src/core/probe.ts +45 -0
- package/src/core/status.ts +145 -0
- package/src/core/targets.ts +243 -0
- package/src/core/types.ts +59 -0
- package/src/messaging/inbound/commands.ts +136 -0
- package/src/messaging/inbound/dispatch.ts +178 -0
- package/src/messaging/inbound/gate.ts +66 -0
- package/src/messaging/inbound/parse.ts +97 -0
- package/src/messaging/outbound/actions.ts +42 -0
- package/src/messaging/outbound/media.ts +53 -0
- package/src/messaging/outbound/send.ts +67 -0
package/README.md
CHANGED
|
@@ -1,394 +1,150 @@
|
|
|
1
|
-
# bncr
|
|
1
|
+
# bncr
|
|
2
2
|
|
|
3
|
-
OpenClaw 的 Bncr
|
|
3
|
+
OpenClaw 的 Bncr 频道插件(`channelId=bncr`)。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
作用很简单:把 **Bncr / 无界客户端** 接到 **OpenClaw 网关**,用于消息双向通信与媒体/文件传输。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## 1. 概览
|
|
10
|
-
|
|
11
|
-
- **OpenClaw Channel ID**:`bncr`
|
|
12
|
-
- **Bridge Version**:`2`
|
|
13
|
-
- **出站事件名**:`bncr.push`
|
|
14
|
-
- **出站模式**:`push-only`(不依赖 pull 轮询)
|
|
15
|
-
- **活动心跳方法**:`bncr.activity`
|
|
16
|
-
- **诊断方法**:`bncr.diagnostics`
|
|
17
|
-
- **文件互传方法(V1)**:
|
|
18
|
-
- `bncr.file.init`
|
|
19
|
-
- `bncr.file.chunk`
|
|
20
|
-
- `bncr.file.complete`
|
|
21
|
-
- `bncr.file.abort`
|
|
22
|
-
- `bncr.file.ack`
|
|
7
|
+
> 当前定位说明:bncr **不是 agent**。它保留既有 **WS 接入链路** 作为 transport / 通信承载,
|
|
8
|
+
> 在 OpenClaw 内部则按 **正式频道插件(channel plugin)** 建模。
|
|
23
9
|
|
|
24
10
|
---
|
|
25
11
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
当前是 **push-only**:
|
|
29
|
-
|
|
30
|
-
- Bncr 在线:OpenClaw 通过 WS `event=bncr.push` 直接下发回复。
|
|
31
|
-
- Bncr 离线:消息进入 outbox;重连后自动冲队列。
|
|
32
|
-
- `bncr.activity` 仅用于在线保活,不承载拉取。
|
|
33
|
-
- `bncr.ack` 保留兼容,当前主链路不强依赖。
|
|
12
|
+
## 1. 这是什么
|
|
34
13
|
|
|
35
|
-
|
|
36
|
-
|
|
14
|
+
- 一个 OpenClaw 的正式频道插件
|
|
15
|
+
- 负责把 Bncr / 无界客户端接入 OpenClaw
|
|
16
|
+
- 负责消息、媒体、文件与基础状态链路
|
|
37
17
|
|
|
38
18
|
---
|
|
39
19
|
|
|
40
|
-
##
|
|
20
|
+
## 2. 安装方式
|
|
41
21
|
|
|
42
|
-
|
|
22
|
+
### OpenClaw 侧
|
|
43
23
|
|
|
44
|
-
```
|
|
45
|
-
|
|
24
|
+
```bash
|
|
25
|
+
openclaw plugins install @xmoxmo/bncr
|
|
26
|
+
openclaw plugins enable bncr
|
|
27
|
+
openclaw gateway restart
|
|
46
28
|
```
|
|
47
29
|
|
|
48
|
-
|
|
30
|
+
### Bncr / 无界侧
|
|
49
31
|
|
|
50
|
-
|
|
51
|
-
- 推荐使用小写 hex(插件兼容大小写输入)。
|
|
52
|
-
- 兼容输入会在内部归一到 `agent:main:bncr:direct:<hexScope>`。
|
|
32
|
+
安装:
|
|
53
33
|
|
|
54
|
-
|
|
34
|
+
- `openclawclient.js`
|
|
55
35
|
|
|
56
|
-
|
|
57
|
-
scope = qq:0:888888
|
|
58
|
-
hexScope = 71713a303a383838383838
|
|
59
|
-
sessionKey = agent:main:bncr:direct:71713a303a383838383838
|
|
60
|
-
```
|
|
36
|
+
然后完成客户端配置并连上 OpenClaw 网关即可。
|
|
61
37
|
|
|
62
38
|
---
|
|
63
39
|
|
|
64
|
-
##
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
40
|
+
## 3. 当前能力
|
|
41
|
+
|
|
42
|
+
- 文本
|
|
43
|
+
- 图片
|
|
44
|
+
- 视频
|
|
45
|
+
- 语音
|
|
46
|
+
- 音频
|
|
47
|
+
- 文件
|
|
48
|
+
- 下行推送
|
|
49
|
+
- ACK
|
|
50
|
+
- 离线消息排队
|
|
51
|
+
- 重连后继续发送
|
|
52
|
+
- 状态诊断
|
|
53
|
+
- 文件互传
|
|
78
54
|
|
|
79
55
|
---
|
|
80
56
|
|
|
81
|
-
##
|
|
82
|
-
|
|
83
|
-
### Step A:建立 WS 并发送 `bncr.connect`
|
|
57
|
+
## 4. 架构定位
|
|
84
58
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```json
|
|
88
|
-
{
|
|
89
|
-
"type": "req",
|
|
90
|
-
"id": "c1",
|
|
91
|
-
"method": "bncr.connect",
|
|
92
|
-
"params": {
|
|
93
|
-
"accountId": "Primary",
|
|
94
|
-
"clientId": "bncr-client-1"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|
|
59
|
+
bncr 当前采用两层模型:
|
|
98
60
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
{
|
|
103
|
-
"type": "res",
|
|
104
|
-
"id": "c1",
|
|
105
|
-
"ok": true,
|
|
106
|
-
"result": {
|
|
107
|
-
"channel": "bncr",
|
|
108
|
-
"accountId": "Primary",
|
|
109
|
-
"bridgeVersion": 2,
|
|
110
|
-
"pushEvent": "bncr.push",
|
|
111
|
-
"online": true,
|
|
112
|
-
"isPrimary": true,
|
|
113
|
-
"activeConnections": 1,
|
|
114
|
-
"pending": 0,
|
|
115
|
-
"deadLetter": 0,
|
|
116
|
-
"diagnostics": {
|
|
117
|
-
"health": {
|
|
118
|
-
"connected": true,
|
|
119
|
-
"pending": 0,
|
|
120
|
-
"deadLetter": 0,
|
|
121
|
-
"activeConnections": 1
|
|
122
|
-
},
|
|
123
|
-
"regression": {
|
|
124
|
-
"ok": true
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
"now": 1772476800000
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
> `accountId` 示例是 `Primary`,请按你实际配置替换;不传默认使用 `Primary`。
|
|
133
|
-
|
|
134
|
-
### Step B:上行消息用 `bncr.inbound`
|
|
135
|
-
|
|
136
|
-
文本请求示例(`msg` 形态):
|
|
137
|
-
|
|
138
|
-
```json
|
|
139
|
-
{
|
|
140
|
-
"type": "req",
|
|
141
|
-
"id": "i1",
|
|
142
|
-
"method": "bncr.inbound",
|
|
143
|
-
"params": {
|
|
144
|
-
"accountId": "Primary",
|
|
145
|
-
"platform": "qq",
|
|
146
|
-
"groupId": "0",
|
|
147
|
-
"userId": "888888",
|
|
148
|
-
"sessionKey": "agent:main:bncr:direct:71713a303a383838383838",
|
|
149
|
-
"msgId": "msg-1001",
|
|
150
|
-
"type": "text",
|
|
151
|
-
"msg": "你好"
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
```
|
|
61
|
+
1. **WS 承载层**
|
|
62
|
+
- Bncr 客户端通过 WebSocket 接入 OpenClaw 网关
|
|
63
|
+
- 负责连接、推送、ACK、文件分块等 transport 能力
|
|
155
64
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
{
|
|
160
|
-
"type": "req",
|
|
161
|
-
"id": "i2",
|
|
162
|
-
"method": "bncr.inbound",
|
|
163
|
-
"params": {
|
|
164
|
-
"accountId": "Primary",
|
|
165
|
-
"platform": "qq",
|
|
166
|
-
"groupId": "0",
|
|
167
|
-
"userId": "888888",
|
|
168
|
-
"sessionKey": "agent:main:bncr:direct:71713a303a383838383838",
|
|
169
|
-
"msgId": "msg-1002",
|
|
170
|
-
"type": "image/png",
|
|
171
|
-
"msg": "",
|
|
172
|
-
"base64": "<BASE64_PAYLOAD>",
|
|
173
|
-
"mimeType": "image/png",
|
|
174
|
-
"fileName": "demo.png"
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
```
|
|
65
|
+
2. **OpenClaw 频道插件层**
|
|
66
|
+
- 在 OpenClaw 内部按正式 `channel plugin` 建模
|
|
67
|
+
- 负责入站解析、消息分发、出站适配、状态与治理
|
|
178
68
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
```json
|
|
182
|
-
{
|
|
183
|
-
"type": "res",
|
|
184
|
-
"id": "i1",
|
|
185
|
-
"ok": true,
|
|
186
|
-
"result": {
|
|
187
|
-
"accepted": true,
|
|
188
|
-
"accountId": "Primary",
|
|
189
|
-
"sessionKey": "agent:main:bncr:direct:71713a303a383838383838",
|
|
190
|
-
"msgId": "msg-1001",
|
|
191
|
-
"taskKey": null
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
```
|
|
69
|
+
当前代码结构:
|
|
195
70
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
```json
|
|
203
|
-
{
|
|
204
|
-
"type": "event",
|
|
205
|
-
"event": "bncr.push",
|
|
206
|
-
"payload": {
|
|
207
|
-
"type": "message.outbound",
|
|
208
|
-
"messageId": "3f8b1f9b-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
209
|
-
"idempotencyKey": "3f8b1f9b-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
210
|
-
"sessionKey": "agent:main:bncr:direct:71713a303a383838383838",
|
|
211
|
-
"message": {
|
|
212
|
-
"platform": "qq",
|
|
213
|
-
"groupId": "0",
|
|
214
|
-
"userId": "888888",
|
|
215
|
-
"type": "text",
|
|
216
|
-
"msg": "收到,已处理。",
|
|
217
|
-
"path": "",
|
|
218
|
-
"base64": "",
|
|
219
|
-
"fileName": ""
|
|
220
|
-
},
|
|
221
|
-
"ts": 1772476801234
|
|
222
|
-
}
|
|
223
|
-
}
|
|
71
|
+
```text
|
|
72
|
+
plugins/bncr/src/
|
|
73
|
+
channel.ts
|
|
74
|
+
core/
|
|
75
|
+
messaging/
|
|
224
76
|
```
|
|
225
77
|
|
|
226
78
|
---
|
|
227
79
|
|
|
228
|
-
##
|
|
229
|
-
|
|
230
|
-
### 6.1 Bncr -> OpenClaw(`bncr.inbound`)
|
|
231
|
-
|
|
232
|
-
常用字段:
|
|
233
|
-
|
|
234
|
-
- `accountId`:可选(默认 `Primary`)
|
|
235
|
-
- `platform`:必填
|
|
236
|
-
- `groupId`:可选,默认 `"0"`(私聊)
|
|
237
|
-
- `userId`:建议填写(私聊/群聊都建议带上)
|
|
238
|
-
- `sessionKey`:可选,建议传严格 sessionKey
|
|
239
|
-
- `msgId`:建议传(便于短窗口去重)
|
|
240
|
-
- `type`:`text/image/video/file/...`
|
|
241
|
-
- `msg`:文本
|
|
242
|
-
- `base64`:媒体 base64
|
|
243
|
-
- `path`:可选,文件直传完成后的落盘路径(与 `base64` 二选一)
|
|
244
|
-
- `mimeType` / `fileName`:媒体元数据(可选)
|
|
245
|
-
|
|
246
|
-
校验失败常见错误:
|
|
247
|
-
|
|
248
|
-
- `platform/groupId/userId required`
|
|
80
|
+
## 5. 配置项总览
|
|
249
81
|
|
|
250
|
-
|
|
82
|
+
当前主要配置字段:
|
|
251
83
|
|
|
252
|
-
`
|
|
84
|
+
- `enabled`
|
|
85
|
+
- `dmPolicy`
|
|
86
|
+
- `groupPolicy`
|
|
87
|
+
- `allowFrom`
|
|
88
|
+
- `groupAllowFrom`
|
|
89
|
+
- `outboundRequireAck`
|
|
90
|
+
- `requireMention`
|
|
91
|
+
- `accounts`
|
|
253
92
|
|
|
254
|
-
|
|
255
|
-
- `/task:foo`
|
|
256
|
-
- `/task foo 正文...`
|
|
93
|
+
补充:
|
|
257
94
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
关键字段:
|
|
263
|
-
|
|
264
|
-
- `type`(固定 `message.outbound`)
|
|
265
|
-
- `messageId`
|
|
266
|
-
- `idempotencyKey`(当前等于 `messageId`)
|
|
267
|
-
- `sessionKey`
|
|
268
|
-
- `message.platform/groupId/userId`
|
|
269
|
-
- `message.type/msg/path/base64/fileName/mimeType`
|
|
270
|
-
- `message.transferMode`(媒体场景可出现:`base64`/`chunk`)
|
|
271
|
-
- `ts`
|
|
272
|
-
|
|
273
|
-
说明:
|
|
274
|
-
|
|
275
|
-
- 主类型固定为 `type="message.outbound"`。
|
|
276
|
-
- 推荐客户端仅消费 `message.outbound` 主链路。
|
|
95
|
+
- `dmPolicy` / `groupPolicy` 支持:`open | allowlist | disabled`
|
|
96
|
+
- `outboundRequireAck` 控制文本外发是否等待 `bncr.ack` 再出队
|
|
97
|
+
- `requireMention` 当前仍是保留字段
|
|
277
98
|
|
|
278
99
|
---
|
|
279
100
|
|
|
280
|
-
##
|
|
281
|
-
|
|
282
|
-
发送前支持并兼容以下 6 种目标输入:
|
|
283
|
-
|
|
284
|
-
1. `agent:main:bncr:direct:<hex>`
|
|
285
|
-
2. `agent:main:bncr:group:<hex>`
|
|
286
|
-
3. `bncr:<hex>`
|
|
287
|
-
4. `bncr:g-<hex>`
|
|
288
|
-
5. `bncr:<platform>:<groupId>:<userId>`
|
|
289
|
-
6. `bncr:g-<platform>:<groupId>:<userId>`
|
|
101
|
+
## 6. 状态与诊断
|
|
290
102
|
|
|
291
|
-
|
|
103
|
+
常用检查:
|
|
292
104
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
- 必须在已知会话路由中反查到真实 session 才发送。
|
|
298
|
-
- 查不到会报:`target not found in known sessions`。
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## 8. 文件互传(V1)
|
|
303
|
-
|
|
304
|
-
### 8.1 OpenClaw -> Bncr(下行媒体)
|
|
305
|
-
|
|
306
|
-
当前默认 **强制分块**(chunk)传输:
|
|
307
|
-
|
|
308
|
-
- `bncr.file.init`
|
|
309
|
-
- `bncr.file.chunk`
|
|
310
|
-
- `bncr.file.complete`
|
|
311
|
-
- Bncr 客户端通过 `bncr.file.ack` 回 ACK
|
|
312
|
-
|
|
313
|
-
特性:
|
|
314
|
-
|
|
315
|
-
- 分块大小默认 256KB
|
|
316
|
-
- chunk ACK 超时/失败会重试
|
|
317
|
-
- 完成后 `message.outbound.message.path` 回填客户端可用路径
|
|
318
|
-
|
|
319
|
-
### 8.2 Bncr -> OpenClaw(上行文件)
|
|
320
|
-
|
|
321
|
-
Bncr 客户端可通过:
|
|
322
|
-
|
|
323
|
-
- `bncr.file.init`
|
|
324
|
-
- `bncr.file.chunk`
|
|
325
|
-
- `bncr.file.complete`
|
|
326
|
-
- `bncr.file.abort`
|
|
327
|
-
|
|
328
|
-
完成上传后,OpenClaw 会落盘并在后续 `bncr.inbound` 中通过 `path` 传递。
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
## 9. 可靠性
|
|
333
|
-
|
|
334
|
-
- 离线入队 + 重连自动冲队列。
|
|
335
|
-
- 指数退避:`1s,2s,4s,8s...`
|
|
336
|
-
- 最大重试次数:`10`
|
|
337
|
-
- 超限进入 dead-letter。
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
## 10. 状态判定与诊断
|
|
342
|
-
|
|
343
|
-
- 实际链路在线:`linked`
|
|
344
|
-
- 已配置但离线:`configured`
|
|
345
|
-
- 账户卡片离线展示口径会显示 `Status`
|
|
105
|
+
```bash
|
|
106
|
+
openclaw gateway status
|
|
107
|
+
openclaw health --json
|
|
108
|
+
```
|
|
346
109
|
|
|
347
|
-
|
|
110
|
+
重点看:
|
|
348
111
|
|
|
112
|
+
- `linked`
|
|
349
113
|
- `pending`
|
|
350
114
|
- `deadLetter`
|
|
351
|
-
-
|
|
352
|
-
- `lastSessionScope`(`bncr:platform:group:user`)
|
|
353
|
-
- `lastSessionAt`
|
|
354
|
-
- `lastActivityAt`
|
|
355
|
-
- `lastInboundAt`
|
|
356
|
-
- `lastOutboundAt`
|
|
357
|
-
- `diagnostics`
|
|
358
|
-
|
|
359
|
-
`diagnostics` 中包含:
|
|
360
|
-
|
|
361
|
-
- `health`:连接数、pending、dead-letter、事件计数、uptime
|
|
362
|
-
- `regression`:已知路由数、无效 sessionKey 残留、账号残留等
|
|
115
|
+
- diagnostics / probe / status 摘要
|
|
363
116
|
|
|
364
117
|
---
|
|
365
118
|
|
|
366
|
-
##
|
|
367
|
-
|
|
368
|
-
### Q1:为什么看不到回复?
|
|
119
|
+
## 7. 自检与测试
|
|
369
120
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
121
|
+
```bash
|
|
122
|
+
cd plugins/bncr
|
|
123
|
+
npm test
|
|
124
|
+
npm run selfcheck
|
|
125
|
+
npm pack
|
|
126
|
+
```
|
|
374
127
|
|
|
375
|
-
|
|
128
|
+
用途:
|
|
376
129
|
|
|
377
|
-
|
|
130
|
+
- `npm test`:跑回归测试
|
|
131
|
+
- `npm run selfcheck`:检查插件骨架是否完整
|
|
132
|
+
- `npm pack`:确认当前版本可正常打包
|
|
378
133
|
|
|
379
|
-
|
|
134
|
+
---
|
|
380
135
|
|
|
381
|
-
|
|
382
|
-
- 出站按 `idempotencyKey` 幂等处理。
|
|
383
|
-
- 客户端侧建议仅消费 `message.outbound`,并按需过滤 `NO_REPLY/HEARTBEAT_OK`。
|
|
136
|
+
## 8. 上线前检查
|
|
384
137
|
|
|
385
|
-
|
|
138
|
+
上线前建议至少确认:
|
|
386
139
|
|
|
387
|
-
-
|
|
388
|
-
-
|
|
140
|
+
- README 与当前实现一致
|
|
141
|
+
- 配置 schema 与实际字段一致
|
|
142
|
+
- 测试通过
|
|
143
|
+
- 自检通过
|
|
144
|
+
- 可以正常打包
|
|
145
|
+
- 本地版本号与 npm / 发布目标一致
|
|
146
|
+
- 运行态 `linked / pending / deadLetter` 正常
|
|
389
147
|
|
|
390
148
|
---
|
|
391
149
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
历史版本接入过的话,请以当前文档(push-only + 6 格式目标兼容 + 文件互传 V1 + 诊断字段)为准。
|
|
150
|
+
如果你接触过旧版本,请以当前 README 和当前代码为准。
|
package/index.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
2
|
import {
|
|
3
|
-
emptyPluginConfigSchema,
|
|
4
3
|
type GatewayRequestHandlerOptions,
|
|
5
4
|
} from "openclaw/plugin-sdk";
|
|
5
|
+
import { BncrConfigSchema } from "./src/core/config-schema.js";
|
|
6
6
|
import { createBncrBridge, createBncrChannelPlugin } from "./src/channel.js";
|
|
7
7
|
|
|
8
8
|
const plugin = {
|
|
9
9
|
id: "bncr",
|
|
10
10
|
name: "Bncr",
|
|
11
11
|
description: "Bncr channel plugin",
|
|
12
|
-
configSchema:
|
|
12
|
+
configSchema: BncrConfigSchema,
|
|
13
13
|
register(api: OpenClawPluginApi) {
|
|
14
14
|
const bridge = createBncrBridge(api);
|
|
15
15
|
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,38 @@
|
|
|
3
3
|
"channels": ["bncr"],
|
|
4
4
|
"configSchema": {
|
|
5
5
|
"type": "object",
|
|
6
|
-
"additionalProperties":
|
|
7
|
-
"properties": {
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"properties": {
|
|
8
|
+
"enabled": { "type": "boolean" },
|
|
9
|
+
"dmPolicy": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"enum": ["open", "allowlist", "disabled"]
|
|
12
|
+
},
|
|
13
|
+
"groupPolicy": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"enum": ["open", "allowlist", "disabled"]
|
|
16
|
+
},
|
|
17
|
+
"allowFrom": {
|
|
18
|
+
"type": "array",
|
|
19
|
+
"items": { "type": "string" }
|
|
20
|
+
},
|
|
21
|
+
"groupAllowFrom": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": { "type": "string" }
|
|
24
|
+
},
|
|
25
|
+
"requireMention": { "type": "boolean" },
|
|
26
|
+
"outboundRequireAck": { "type": "boolean" },
|
|
27
|
+
"accounts": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"additionalProperties": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": true,
|
|
32
|
+
"properties": {
|
|
33
|
+
"enabled": { "type": "boolean" },
|
|
34
|
+
"name": { "type": "string" }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
8
39
|
}
|
|
9
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmoxmo/bncr",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,8 +20,13 @@
|
|
|
20
20
|
"openclaw.plugin.json",
|
|
21
21
|
"README.md",
|
|
22
22
|
"LICENSE",
|
|
23
|
-
"src"
|
|
23
|
+
"src",
|
|
24
|
+
"scripts"
|
|
24
25
|
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"selfcheck": "node ./scripts/selfcheck.mjs",
|
|
28
|
+
"test": "node --import ./tests/register-ts-hooks.mjs --test ./tests/*.test.mjs"
|
|
29
|
+
},
|
|
25
30
|
"openclaw": {
|
|
26
31
|
"extensions": [
|
|
27
32
|
"./index.ts"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
const root = path.resolve(__dirname, '..');
|
|
8
|
+
|
|
9
|
+
const requiredFiles = [
|
|
10
|
+
'index.ts',
|
|
11
|
+
'openclaw.plugin.json',
|
|
12
|
+
'src/channel.ts',
|
|
13
|
+
'src/core/types.ts',
|
|
14
|
+
'src/core/accounts.ts',
|
|
15
|
+
'src/core/targets.ts',
|
|
16
|
+
'src/core/status.ts',
|
|
17
|
+
'src/core/probe.ts',
|
|
18
|
+
'src/core/config-schema.ts',
|
|
19
|
+
'src/core/policy.ts',
|
|
20
|
+
'src/core/permissions.ts',
|
|
21
|
+
'src/messaging/inbound/parse.ts',
|
|
22
|
+
'src/messaging/inbound/gate.ts',
|
|
23
|
+
'src/messaging/inbound/dispatch.ts',
|
|
24
|
+
'src/messaging/outbound/send.ts',
|
|
25
|
+
'src/messaging/outbound/media.ts',
|
|
26
|
+
'src/messaging/outbound/actions.ts',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const missing = requiredFiles.filter((rel) => !fs.existsSync(path.join(root, rel)));
|
|
30
|
+
const result = {
|
|
31
|
+
ok: missing.length === 0,
|
|
32
|
+
checkedRoot: root,
|
|
33
|
+
requiredCount: requiredFiles.length,
|
|
34
|
+
missing,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
console.log(JSON.stringify(result, null, 2));
|
|
38
|
+
if (missing.length > 0) process.exit(1);
|