@flomesh/ztm-chat 2026.2.15
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/LICENSE +21 -0
- package/README.md +865 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 flomesh-io
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
# ZTM Chat Channel Plugin for OpenClaw
|
|
2
|
+
|
|
3
|
+
[](https://github.com/flomesh-io/openclaw-channel-plugin-ztm/actions)
|
|
4
|
+
[](https://github.com/flomesh-io/openclaw-channel-plugin-ztm)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://github.com/flomesh-io/openclaw-channel-plugin-ztm/releases/latest)
|
|
8
|
+
|
|
9
|
+
This plugin integrates OpenClaw with ZTM (Zero Trust Mesh) Chat, enabling decentralized P2P messaging through the ZTM network.
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart TB
|
|
15
|
+
subgraph ZTM["ZTM Network"]
|
|
16
|
+
User["ZTM User"]
|
|
17
|
+
Agent["ZTM Agent"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
subgraph OpenClaw["OpenClaw Gateway"]
|
|
21
|
+
Plugin["ztm-chat Plugin"]
|
|
22
|
+
Dispatcher["Message Dispatcher"]
|
|
23
|
+
AgentLLM["AI Agent"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
subgraph Storage["Local Storage"]
|
|
27
|
+
State["Message State"]
|
|
28
|
+
Pairing["Pairing Store"]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
User -->|"DM/Group Message"| Agent
|
|
32
|
+
Agent -->|"Chat App API"| Plugin
|
|
33
|
+
Plugin -->|"Route"| Dispatcher
|
|
34
|
+
Dispatcher -->|"Check Policy"| AgentLLM
|
|
35
|
+
AgentLLM -->|"Response"| Plugin
|
|
36
|
+
Plugin -->|"Chat App API"| Agent
|
|
37
|
+
Agent -->|"Deliver"| User
|
|
38
|
+
|
|
39
|
+
Plugin --> State
|
|
40
|
+
Plugin --> Pairing
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Data Flow:**
|
|
44
|
+
1. User sends message to ZTM Agent
|
|
45
|
+
2. Plugin polls Chat App API for new messages
|
|
46
|
+
3. Dispatcher checks DM/Group policy
|
|
47
|
+
4. If allowed, route to AI Agent
|
|
48
|
+
5. AI Agent generates response
|
|
49
|
+
6. Plugin sends response via Chat App API
|
|
50
|
+
7. ZTM Agent delivers to user
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **Peer-to-Peer Messaging**: Send and receive messages with other ZTM users
|
|
55
|
+
- **Remote Connection**: Connect to ZTM Agent from anywhere via HTTP API
|
|
56
|
+
- **Secure**: Supports mTLS authentication with ZTM certificates
|
|
57
|
+
- **Decentralized**: Messages flow through the ZTM P2P network
|
|
58
|
+
- **Multi-Account**: Support for multiple ZTM bot accounts with isolated state
|
|
59
|
+
- **User Discovery**: Browse and discover other users in your ZTM mesh
|
|
60
|
+
- **Real-Time Updates**: Watch mechanism with polling fallback
|
|
61
|
+
- **Message Deduplication**: Prevents duplicate message processing
|
|
62
|
+
- **Structured Logging**: Context-aware logger with sensitive data filtering
|
|
63
|
+
- **Interactive Wizard**: CLI-guided configuration setup
|
|
64
|
+
- **Group Chat Support**: Multi-user group conversations with permission control
|
|
65
|
+
- **Fine-Grained Access Control**: Per-group policies, mention gating, and tool restrictions
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
### 1. Install ZTM CLI
|
|
70
|
+
|
|
71
|
+
Download ZTM from GitHub releases and install to `/usr/local/bin`:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Download (example: v1.0.4 for Linux x86_64)
|
|
75
|
+
curl -L "https://github.com/flomesh-io/ztm/releases/download/v1.0.4/ztm-aio-v1.0.4-generic_linux-x86_64.tar.gz" -o /tmp/ztm.tar.gz
|
|
76
|
+
|
|
77
|
+
# Extract
|
|
78
|
+
tar -xzf /tmp/ztm.tar.gz -C /tmp
|
|
79
|
+
|
|
80
|
+
# Install to /usr/local/bin (requires sudo)
|
|
81
|
+
sudo mv /tmp/bin/ztm /usr/local/bin/ztm
|
|
82
|
+
|
|
83
|
+
# Cleanup
|
|
84
|
+
rm /tmp/ztm.tar.gz
|
|
85
|
+
|
|
86
|
+
# Verify
|
|
87
|
+
ztm version
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Start ZTM Agent
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
ztm start agent
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The agent will start listening on `http://localhost:7777` by default.
|
|
97
|
+
|
|
98
|
+
### 3. Install Plugin
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
openclaw plugins install -l .
|
|
102
|
+
|
|
103
|
+
# Or install from npm (when published)
|
|
104
|
+
# npm install -g @ztm/openclaw-ztm-chat
|
|
105
|
+
# openclaw plugins install @ztm/openclaw-ztm-chat
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 4. Run Configuration Wizard
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
openclaw ztm-chat-wizard
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The wizard will guide you through:
|
|
115
|
+
1. **ZTM Agent URL** (default: `http://localhost:7777`)
|
|
116
|
+
2. **Permit Server URL** (default: `https://ztm-portal.flomesh.io:7779/permit`)
|
|
117
|
+
3. **Bot Username** (default: `openclaw-bot`)
|
|
118
|
+
4. **Security Settings**
|
|
119
|
+
- DM Policy: `pairing` (recommended), `allow`, or `deny`
|
|
120
|
+
- Allow From: Whitelist of usernames (or `*` for all)
|
|
121
|
+
5. **Group Chat Settings** (if enabled)
|
|
122
|
+
- Enable Groups: Yes/No
|
|
123
|
+
- Group Policy: `allowlist`, `open`, or `disabled`
|
|
124
|
+
- Require Mention: Yes/No (default: Yes)
|
|
125
|
+
6. **Summary & Save**
|
|
126
|
+
|
|
127
|
+
### 5. Restart OpenClaw
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
openclaw gateway restart
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Group Chat
|
|
134
|
+
|
|
135
|
+
### Overview
|
|
136
|
+
|
|
137
|
+
ZTM Chat supports group conversations with fine-grained permission control. When `enableGroups` is enabled, the bot can:
|
|
138
|
+
|
|
139
|
+
- Receive and process messages from group chats
|
|
140
|
+
- Reply to group messages with @mention support
|
|
141
|
+
- Apply per-group access policies
|
|
142
|
+
- Restrict available tools based on group membership
|
|
143
|
+
|
|
144
|
+
### How It Works
|
|
145
|
+
|
|
146
|
+
```mermaid
|
|
147
|
+
flowchart LR
|
|
148
|
+
subgraph Group["Group Chat"]
|
|
149
|
+
User1["Member 1"]
|
|
150
|
+
User2["Member 2"]
|
|
151
|
+
User3["Member 3"]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
subgraph ZTM["ZTM Agent"]
|
|
155
|
+
Agent[("Chat API")]
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
User1 -.->|"@mention"| Agent
|
|
159
|
+
User2 -.->|"@mention"| Agent
|
|
160
|
+
User3 -.->|"@mention"| Agent
|
|
161
|
+
|
|
162
|
+
Agent -->|"Poll messages"| Plugin
|
|
163
|
+
Plugin -->|"Check policy"| Plugin
|
|
164
|
+
Plugin -->|"AI Response"| Agent
|
|
165
|
+
Agent -->|"Deliver"| Group
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Enabling Group Chat
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Enable via wizard
|
|
172
|
+
openclaw ztm-chat-wizard
|
|
173
|
+
# Select "Enable Groups" when prompted
|
|
174
|
+
|
|
175
|
+
# Or manually in openclaw.yaml
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Group Policy Modes
|
|
179
|
+
|
|
180
|
+
| Policy | Behavior |
|
|
181
|
+
|--------|----------|
|
|
182
|
+
| `open` | Allow all group messages (with optional mention requirement) |
|
|
183
|
+
| `allowlist` | Only allow whitelisted senders |
|
|
184
|
+
| `disabled` | Block all group messages |
|
|
185
|
+
|
|
186
|
+
### Mention Gating
|
|
187
|
+
|
|
188
|
+
When `requireMention` is enabled (default), the bot will only process messages that @mention the bot username:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
# Bot username: my-bot
|
|
192
|
+
|
|
193
|
+
# These messages will be processed:
|
|
194
|
+
@my-bot can you help me?
|
|
195
|
+
Hey @my-bot what's up?
|
|
196
|
+
|
|
197
|
+
# These messages will be ignored:
|
|
198
|
+
hello everyone!
|
|
199
|
+
good morning
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Note:** `requireMention` applies to ALL users, including the group creator. This ensures even the group owner must explicitly mention the bot to trigger a response.
|
|
203
|
+
|
|
204
|
+
### Per-Group Configuration
|
|
205
|
+
|
|
206
|
+
You can configure different policies for different groups:
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
channels:
|
|
210
|
+
ztm-chat:
|
|
211
|
+
accounts:
|
|
212
|
+
my-bot:
|
|
213
|
+
enableGroups: true
|
|
214
|
+
groupPolicy: allowlist # Default for unknown groups
|
|
215
|
+
requireMention: true # Global default (can be overridden per group)
|
|
216
|
+
groupPermissions:
|
|
217
|
+
alice/team:
|
|
218
|
+
groupPolicy: open
|
|
219
|
+
requireMention: false
|
|
220
|
+
bob/project-x:
|
|
221
|
+
groupPolicy: allowlist
|
|
222
|
+
requireMention: true
|
|
223
|
+
allowFrom: [bob, charlie, david]
|
|
224
|
+
private/secret-group:
|
|
225
|
+
groupPolicy: disabled
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Tool Restrictions
|
|
229
|
+
|
|
230
|
+
Control which tools are available in each group:
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
channels:
|
|
234
|
+
ztm-chat:
|
|
235
|
+
accounts:
|
|
236
|
+
my-bot:
|
|
237
|
+
groupPermissions:
|
|
238
|
+
alice/team:
|
|
239
|
+
groupPolicy: open
|
|
240
|
+
requireMention: false
|
|
241
|
+
tools:
|
|
242
|
+
allow:
|
|
243
|
+
- group:messaging
|
|
244
|
+
- group:sessions
|
|
245
|
+
- group:runtime
|
|
246
|
+
toolsBySender:
|
|
247
|
+
admin:
|
|
248
|
+
alsoAllow:
|
|
249
|
+
- exec
|
|
250
|
+
- fs
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### Tool Policy Options
|
|
254
|
+
|
|
255
|
+
| Option | Description |
|
|
256
|
+
|--------|-------------|
|
|
257
|
+
| `tools.allow` | Only allow these tools (deny all others) |
|
|
258
|
+
| `tools.deny` | Deny these tools (allow all others) |
|
|
259
|
+
| `toolsBySender.{user}.alsoAllow` | Additional tools for specific users |
|
|
260
|
+
| `toolsBySender.{user}.deny` | Deny tools for specific users |
|
|
261
|
+
|
|
262
|
+
#### Default Tools
|
|
263
|
+
|
|
264
|
+
By default, groups only have access to:
|
|
265
|
+
- `group:messaging` - Send/receive messages
|
|
266
|
+
- `group:sessions` - Session management
|
|
267
|
+
|
|
268
|
+
### Creator Privileges
|
|
269
|
+
|
|
270
|
+
Group creators have special privileges that allow them to bypass certain policy checks:
|
|
271
|
+
|
|
272
|
+
| Check | Creator Bypass? |
|
|
273
|
+
|-------|---------------|
|
|
274
|
+
| `groupPolicy` (disabled/allowlist/open) | ✅ Yes |
|
|
275
|
+
| `allowFrom` whitelist | ✅ Yes |
|
|
276
|
+
| `requireMention` | ❌ No (still required) |
|
|
277
|
+
|
|
278
|
+
This ensures the bot owner can always interact with their own groups while still requiring explicit @mentions to trigger responses.
|
|
279
|
+
|
|
280
|
+
## Usage
|
|
281
|
+
|
|
282
|
+
### Sending a Message
|
|
283
|
+
|
|
284
|
+
From any ZTM user, send a message to your bot:
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
Hello! Can you help me with something?
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The bot will respond through OpenClaw's AI agent.
|
|
291
|
+
|
|
292
|
+
### Pairing Mode
|
|
293
|
+
|
|
294
|
+
By default, the bot uses **pairing mode** (`dmPolicy: "pairing"`):
|
|
295
|
+
|
|
296
|
+
1. **New users** must be approved before they can send messages
|
|
297
|
+
2. When an unapproved user sends a message, the bot sends them a pairing code
|
|
298
|
+
3. Approve users using the CLI with their pairing code
|
|
299
|
+
|
|
300
|
+
#### List Pending Requests
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
openclaw pairing list ztm-chat
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
#### Approve a Pairing Request
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
openclaw pairing approve ztm-chat <code>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
#### Pairing Mode Policies
|
|
313
|
+
|
|
314
|
+
| Policy | Behavior |
|
|
315
|
+
|--------|----------|
|
|
316
|
+
| `allow` | Accept messages from all users (no approval needed) |
|
|
317
|
+
| `deny` | Reject messages from all users (except allowFrom list) |
|
|
318
|
+
| `pairing` | Require explicit approval for new users (recommended) |
|
|
319
|
+
|
|
320
|
+
## CLI Commands
|
|
321
|
+
|
|
322
|
+
### Plugin Commands
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# Setup wizard
|
|
326
|
+
openclaw ztm-chat-wizard
|
|
327
|
+
|
|
328
|
+
# Auto-discover existing configuration
|
|
329
|
+
openclaw ztm-chat-discover
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Channel Commands
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
# Check channel status
|
|
336
|
+
openclaw channels status ztm-chat
|
|
337
|
+
|
|
338
|
+
# View configuration
|
|
339
|
+
openclaw channels describe ztm-chat
|
|
340
|
+
|
|
341
|
+
# Probe connection
|
|
342
|
+
openclaw channels status ztm-chat --probe
|
|
343
|
+
|
|
344
|
+
# Enable/disable channel
|
|
345
|
+
openclaw channels disable ztm-chat
|
|
346
|
+
openclaw channels enable ztm-chat
|
|
347
|
+
|
|
348
|
+
# List connected peers
|
|
349
|
+
openclaw channels directory ztm-chat peers
|
|
350
|
+
|
|
351
|
+
# List groups (if enabled)
|
|
352
|
+
openclaw channels directory ztm-chat groups
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Pairing Commands
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# List pending pairing requests
|
|
359
|
+
openclaw pairing list ztm-chat
|
|
360
|
+
|
|
361
|
+
# Approve a pairing request
|
|
362
|
+
openclaw pairing approve ztm-chat <code>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Configuration
|
|
366
|
+
|
|
367
|
+
### Configuration File
|
|
368
|
+
|
|
369
|
+
Configuration is stored in `openclaw.yaml` under `channels.ztm-chat`:
|
|
370
|
+
|
|
371
|
+
#### Mode 1: Server (from permit server)
|
|
372
|
+
|
|
373
|
+
```yaml
|
|
374
|
+
channels:
|
|
375
|
+
ztm-chat:
|
|
376
|
+
enabled: true
|
|
377
|
+
accounts:
|
|
378
|
+
my-bot:
|
|
379
|
+
agentUrl: "http://localhost:7777"
|
|
380
|
+
permitSource: "server"
|
|
381
|
+
permitUrl: "https://ztm-portal.flomesh.io:7779/permit"
|
|
382
|
+
meshName: "production-mesh"
|
|
383
|
+
username: "my-bot"
|
|
384
|
+
enableGroups: true
|
|
385
|
+
autoReply: true
|
|
386
|
+
dmPolicy: "pairing"
|
|
387
|
+
allowFrom:
|
|
388
|
+
- alice
|
|
389
|
+
- trusted-team
|
|
390
|
+
groupPolicy: "allowlist"
|
|
391
|
+
requireMention: true
|
|
392
|
+
groupPermissions:
|
|
393
|
+
alice/team:
|
|
394
|
+
creator: "alice"
|
|
395
|
+
group: "team"
|
|
396
|
+
groupPolicy: "open"
|
|
397
|
+
requireMention: false
|
|
398
|
+
allowFrom: []
|
|
399
|
+
tools:
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
#### Mode 2: File (from local permit.json)
|
|
403
|
+
|
|
404
|
+
```yaml
|
|
405
|
+
channels:
|
|
406
|
+
ztm-chat:
|
|
407
|
+
enabled: true
|
|
408
|
+
accounts:
|
|
409
|
+
my-bot:
|
|
410
|
+
agentUrl: "http://localhost:7777"
|
|
411
|
+
permitSource: "file"
|
|
412
|
+
permitFilePath: "/path/to/permit.json"
|
|
413
|
+
meshName: "production-mesh"
|
|
414
|
+
username: "my-bot"
|
|
415
|
+
enableGroups: true
|
|
416
|
+
autoReply: true
|
|
417
|
+
dmPolicy: "pairing"
|
|
418
|
+
allowFrom:
|
|
419
|
+
- alice
|
|
420
|
+
- trusted-team
|
|
421
|
+
groupPolicy: "allowlist"
|
|
422
|
+
requireMention: true
|
|
423
|
+
groupPermissions:
|
|
424
|
+
alice/team:
|
|
425
|
+
creator: "alice"
|
|
426
|
+
group: "team"
|
|
427
|
+
groupPolicy: "open"
|
|
428
|
+
requireMention: false
|
|
429
|
+
allowFrom: []
|
|
430
|
+
tools:
|
|
431
|
+
allow:
|
|
432
|
+
- group:messaging
|
|
433
|
+
- group:sessions
|
|
434
|
+
- group:runtime
|
|
435
|
+
toolsBySender:
|
|
436
|
+
admin:
|
|
437
|
+
alsoAllow:
|
|
438
|
+
- exec
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Configuration Options
|
|
442
|
+
|
|
443
|
+
**Required:**
|
|
444
|
+
|
|
445
|
+
| Option | Type | Description |
|
|
446
|
+
|--------|------|-------------|
|
|
447
|
+
| `agentUrl` | string | ZTM Agent API URL |
|
|
448
|
+
| `permitSource` | string | Permit source: `"server"` (from permit server) or `"file"` (from local file) |
|
|
449
|
+
| `meshName` | string | Name of your ZTM mesh |
|
|
450
|
+
| `username` | string | Bot's ZTM username |
|
|
451
|
+
|
|
452
|
+
**Required (when permitSource is "server"):**
|
|
453
|
+
|
|
454
|
+
| Option | Type | Description |
|
|
455
|
+
|--------|------|-------------|
|
|
456
|
+
| `permitUrl` | string | Permit Server URL |
|
|
457
|
+
|
|
458
|
+
**Required (when permitSource is "file"):**
|
|
459
|
+
|
|
460
|
+
| Option | Type | Description |
|
|
461
|
+
|--------|------|-------------|
|
|
462
|
+
| `permitFilePath` | string | Path to local permit.json file |
|
|
463
|
+
|
|
464
|
+
**Optional - Basic:**
|
|
465
|
+
|
|
466
|
+
| Option | Type | Default | Description |
|
|
467
|
+
|--------|------|---------|-------------|
|
|
468
|
+
| `enabled` | boolean | `true` | Enable/disable account |
|
|
469
|
+
| `enableGroups` | boolean | `false` | Enable group chat support |
|
|
470
|
+
| `autoReply` | boolean | `true` | Automatically reply to messages |
|
|
471
|
+
| `dmPolicy` | string | `"pairing"` | DM policy: `allow`, `deny`, `pairing` |
|
|
472
|
+
| `allowFrom` | string[] | `[]` | List of approved usernames |
|
|
473
|
+
| `permitFilePath` | string | - | Path to permit.json file (when permitSource is `"file"`) |
|
|
474
|
+
|
|
475
|
+
**Optional - Group:**
|
|
476
|
+
|
|
477
|
+
| Option | Type | Default | Description |
|
|
478
|
+
|--------|------|---------|-------------|
|
|
479
|
+
| `groupPolicy` | string | `"allowlist"` | Default group policy: `open`, `allowlist`, `disabled` |
|
|
480
|
+
| `requireMention` | boolean | `true` | Require @mention for group messages (global default) |
|
|
481
|
+
| `groupPermissions` | object | `{}` | Per-group permission overrides |
|
|
482
|
+
|
|
483
|
+
### Group Permission Options
|
|
484
|
+
|
|
485
|
+
| Option | Type | Description |
|
|
486
|
+
|--------|------|-------------|
|
|
487
|
+
| `groupPolicy` | string | Policy for this group: `open`, `allowlist`, `disabled` |
|
|
488
|
+
| `requireMention` | boolean | Require @mention to process message (default: `true`) |
|
|
489
|
+
| `allowFrom` | string[] | Whitelist of allowed senders |
|
|
490
|
+
| `tools.allow` | string[] | Only allow these tools |
|
|
491
|
+
| `tools.deny` | string[] | Deny these tools |
|
|
492
|
+
| `toolsBySender` | object | Sender-specific tool overrides |
|
|
493
|
+
|
|
494
|
+
### Environment Variables
|
|
495
|
+
|
|
496
|
+
| Variable | Description |
|
|
497
|
+
|----------|-------------|
|
|
498
|
+
| `ZTM_CHAT_LOG_LEVEL` | Logging level: `debug`, `info`, `warn`, `error` |
|
|
499
|
+
|
|
500
|
+
## Message Flow
|
|
501
|
+
|
|
502
|
+
### Direct Message (DM)
|
|
503
|
+
|
|
504
|
+
```mermaid
|
|
505
|
+
sequenceDiagram
|
|
506
|
+
participant U as ZTM User
|
|
507
|
+
participant A as ZTM Agent
|
|
508
|
+
participant P as Plugin
|
|
509
|
+
participant B as AI Agent
|
|
510
|
+
|
|
511
|
+
U->>A: 1. Send DM to bot
|
|
512
|
+
A->>A: 2. Store message
|
|
513
|
+
P->>A: 3. Poll /api/meshes/{mesh}/apps/ztm/chat/api/peers/{bot}/messages
|
|
514
|
+
A->>P: 4. Return new messages
|
|
515
|
+
P->>P: 5. Check DM policy (allow/deny/pairing)
|
|
516
|
+
alt Policy allows
|
|
517
|
+
P->>B: 6. Route to AI agent
|
|
518
|
+
B->>P: 7. Generate response
|
|
519
|
+
P->>A: 8. Send via Chat App API
|
|
520
|
+
A->>U: 9. Deliver to recipient
|
|
521
|
+
else Policy denied
|
|
522
|
+
P->>P: 6. Ignore message
|
|
523
|
+
end
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Group Message
|
|
527
|
+
|
|
528
|
+
```mermaid
|
|
529
|
+
sequenceDiagram
|
|
530
|
+
participant M as ZTM Member
|
|
531
|
+
participant A as ZTM Agent
|
|
532
|
+
participant P as Plugin
|
|
533
|
+
participant B as AI Agent
|
|
534
|
+
|
|
535
|
+
M->>A: 1. Send @mention to group
|
|
536
|
+
A->>A: 2. Store message
|
|
537
|
+
P->>A: 3. Poll Chat App API for new messages
|
|
538
|
+
A->>P: 4. Return new messages
|
|
539
|
+
P->>P: 5. Get group permissions (creator/groupId)
|
|
540
|
+
P->>P: 6. Check: creator? → allow
|
|
541
|
+
P->>P: 7. Check: policy (open/allowlist/disabled)
|
|
542
|
+
P->>P: 8. Check: allowFrom whitelist
|
|
543
|
+
P->>P: 9. Check: requireMention (@{bot})
|
|
544
|
+
alt All checks pass
|
|
545
|
+
P->>B: 10. Route to AI agent (with tools filter)
|
|
546
|
+
B->>P: 11. Generate response
|
|
547
|
+
P->>A: 12. Send reply to group
|
|
548
|
+
A->>M: 13. Deliver to all members
|
|
549
|
+
else Any check fails
|
|
550
|
+
P->>P: Log and ignore message
|
|
551
|
+
end
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### Message Processing Pipeline
|
|
555
|
+
|
|
556
|
+
```mermaid
|
|
557
|
+
flowchart TD
|
|
558
|
+
A[Incoming Message] --> B{isGroup?}
|
|
559
|
+
|
|
560
|
+
B -->|No| C[DM Flow]
|
|
561
|
+
B -->|Yes| D[Group Flow]
|
|
562
|
+
|
|
563
|
+
C --> C1{DM Policy}
|
|
564
|
+
C1 -->|allow| E[Route to AI]
|
|
565
|
+
C1 -->|deny| F[Ignore]
|
|
566
|
+
C1 -->|pairing| G{Paired?}
|
|
567
|
+
G -->|Yes| E
|
|
568
|
+
G -->|No| H[Send Pairing Request]
|
|
569
|
+
|
|
570
|
+
D --> D1{Get Group Permissions}
|
|
571
|
+
D1 --> D2{Is Creator?}
|
|
572
|
+
D2 -->|Yes| E
|
|
573
|
+
D2 -->|No| D3{Policy}
|
|
574
|
+
D3 -->|disabled| F
|
|
575
|
+
D3 -->|allowlist| D4{In allowFrom?}
|
|
576
|
+
D3 -->|open| D5{requireMention?}
|
|
577
|
+
D4 -->|Yes| E
|
|
578
|
+
D4 -->|No| F
|
|
579
|
+
D5 -->|Yes| D6{Mention?}
|
|
580
|
+
D5 -->|No| E
|
|
581
|
+
D6 -->|Yes| E
|
|
582
|
+
D6 -->|No| F
|
|
583
|
+
|
|
584
|
+
E --> E1{Resolve Agent Route}
|
|
585
|
+
E1 --> E2{Dispatch to Agent}
|
|
586
|
+
E2 --> E3{Filter Tools}
|
|
587
|
+
|
|
588
|
+
E3 --> I[Generate Response]
|
|
589
|
+
I --> J{Send Response}
|
|
590
|
+
J -->|DM| J1[sendZTMMessage]
|
|
591
|
+
J -->|Group| J2[sendGroupMessage]
|
|
592
|
+
|
|
593
|
+
F --> K[Log and Ignore]
|
|
594
|
+
H --> K
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Policy Decision Matrix
|
|
598
|
+
|
|
599
|
+
**DM Policy Check Order:**
|
|
600
|
+
|
|
601
|
+
| Step | Condition | Next Step |
|
|
602
|
+
|------|-----------|-----------|
|
|
603
|
+
| 1 | Empty sender | → Deny (ignore) |
|
|
604
|
+
| 2 | Sender in `allowFrom` config | → Allow (whitelisted) |
|
|
605
|
+
| 3 | Sender in pairing store | → Allow (whitelisted) |
|
|
606
|
+
| 4 | Policy = `allow` | → Allow (allowed) |
|
|
607
|
+
| 5 | Policy = `deny` | → Deny (denied) |
|
|
608
|
+
| 6 | Policy = `pairing` | → Send pairing request |
|
|
609
|
+
|
|
610
|
+
**Group Policy Check Order:**
|
|
611
|
+
|
|
612
|
+
| Step | Condition | Next Step |
|
|
613
|
+
|------|-----------|-----------|
|
|
614
|
+
| 1 | Empty sender | → Deny (ignore) |
|
|
615
|
+
| 2 | Sender = creator | → Step 6 (bypass policy) |
|
|
616
|
+
| 3 | groupPolicy = `disabled` | → Deny (denied) |
|
|
617
|
+
| 4 | groupPolicy = `allowlist` + not in allowFrom | → Deny (whitelisted) |
|
|
618
|
+
| 5 | groupPolicy = `open` | → Continue |
|
|
619
|
+
| 6 | requireMention = true + no @mention | → Deny (mention_required) |
|
|
620
|
+
| 7 | All checks passed | → Allow (creator/whitelisted/allowed) |
|
|
621
|
+
|
|
622
|
+
**Result Actions:**
|
|
623
|
+
|
|
624
|
+
| Action | Description |
|
|
625
|
+
|--------|-------------|
|
|
626
|
+
| `process` | Message allowed, route to AI agent |
|
|
627
|
+
| `ignore` | Message denied, log and discard |
|
|
628
|
+
| `pairing` | Send pairing request to user |
|
|
629
|
+
|
|
630
|
+
## ZTM API
|
|
631
|
+
|
|
632
|
+
The plugin uses the ZTM Agent API for identity/mesh operations and the Chat App API for messaging:
|
|
633
|
+
|
|
634
|
+
### Agent API (Identity & Mesh)
|
|
635
|
+
|
|
636
|
+
| Method | Path | Description |
|
|
637
|
+
|--------|------|-------------|
|
|
638
|
+
| GET | `/api/identity` | Get agent identity (certificate) |
|
|
639
|
+
| GET | `/api/meshes/{meshName}` | Get mesh connection status |
|
|
640
|
+
| POST | `/api/meshes/{meshName}` | Join mesh with permit data |
|
|
641
|
+
|
|
642
|
+
### Chat App API
|
|
643
|
+
|
|
644
|
+
| Method | Path | Description |
|
|
645
|
+
|--------|------|-------------|
|
|
646
|
+
| GET | `/api/meshes/{meshName}/apps/ztm/chat/api/users` | List all users in mesh |
|
|
647
|
+
| GET | `/api/meshes/{meshName}/apps/ztm/chat/api/chats` | Get all chats (DMs and groups) |
|
|
648
|
+
| GET | `/api/meshes/{meshName}/apps/ztm/chat/api/peers/{peer}/messages` | Get peer messages (with since/before) |
|
|
649
|
+
| POST | `/api/meshes/{meshName}/apps/ztm/chat/api/peers/{peer}/messages` | Send message to peer |
|
|
650
|
+
| GET | `/api/meshes/{meshName}/apps/ztm/chat/api/groups/{creator}/{group}/messages` | Get group messages |
|
|
651
|
+
| POST | `/api/meshes/{meshName}/apps/ztm/chat/api/groups/{creator}/{group}/messages` | Send message to group |
|
|
652
|
+
|
|
653
|
+
### Message API Parameters
|
|
654
|
+
|
|
655
|
+
| Parameter | Type | Description |
|
|
656
|
+
|-----------|------|-------------|
|
|
657
|
+
| `since` | number | Get messages after this timestamp (Unix ms) |
|
|
658
|
+
| `before` | number | Get messages before this timestamp (Unix ms) |
|
|
659
|
+
| `limit` | number | Maximum number of messages to return (default: 50) |
|
|
660
|
+
|
|
661
|
+
### Example API Calls
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
# Get agent identity (certificate)
|
|
665
|
+
curl http://localhost:7777/api/identity
|
|
666
|
+
|
|
667
|
+
# Get mesh status
|
|
668
|
+
curl http://localhost:7777/api/meshes/openclaw-mesh
|
|
669
|
+
|
|
670
|
+
# Join mesh (with permit data)
|
|
671
|
+
curl -X POST http://localhost:7777/api/meshes/openclaw-mesh \
|
|
672
|
+
-H "Content-Type: application/json" \
|
|
673
|
+
-d '{"ca":"...","agent":{"certificate":"..."},"bootstraps":["host:port"]}'
|
|
674
|
+
|
|
675
|
+
# List users
|
|
676
|
+
curl http://localhost:7777/api/meshes/openclaw-mesh/apps/ztm/chat/api/users
|
|
677
|
+
|
|
678
|
+
# Get peer messages (last 10)
|
|
679
|
+
curl "http://localhost:7777/api/meshes/openclaw-mesh/apps/ztm/chat/api/peers/alice/messages?limit=10"
|
|
680
|
+
|
|
681
|
+
# Send message to peer
|
|
682
|
+
curl -X POST http://localhost:7777/api/meshes/openclaw-mesh/apps/ztm/chat/api/peers/alice/messages \
|
|
683
|
+
-H "Content-Type: application/json" \
|
|
684
|
+
-d '{"text": "Hello!"}'
|
|
685
|
+
|
|
686
|
+
# Get group messages
|
|
687
|
+
curl "http://localhost:7777/api/meshes/openclaw-mesh/apps/ztm/chat/api/groups/alice/team/messages"
|
|
688
|
+
|
|
689
|
+
# Send message to group
|
|
690
|
+
curl -X POST http://localhost:7777/api/meshes/openclaw-mesh/apps/ztm/chat/api/groups/alice/team/messages \
|
|
691
|
+
-H "Content-Type: application/json" \
|
|
692
|
+
-d '{"text": "Hello everyone!"}'
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
## Troubleshooting
|
|
696
|
+
|
|
697
|
+
### Connection Failed
|
|
698
|
+
|
|
699
|
+
1. Verify ZTM Agent is running:
|
|
700
|
+
```bash
|
|
701
|
+
curl http://localhost:7777/api/meshes
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
2. Check mesh name matches:
|
|
705
|
+
```bash
|
|
706
|
+
curl http://localhost:7777/api/meshes
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
3. Check plugin logs:
|
|
710
|
+
```bash
|
|
711
|
+
openclaw logs --level debug --channel ztm-chat
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### No Messages Received
|
|
715
|
+
|
|
716
|
+
1. Check bot username is correct in configuration
|
|
717
|
+
2. Verify ZTM Agent is running:
|
|
718
|
+
```bash
|
|
719
|
+
curl http://localhost:7777/api/meshes
|
|
720
|
+
```
|
|
721
|
+
3. Check mesh connectivity:
|
|
722
|
+
```bash
|
|
723
|
+
openclaw channels status ztm-chat --probe
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
## Development
|
|
727
|
+
|
|
728
|
+
### Running Tests
|
|
729
|
+
|
|
730
|
+
```bash
|
|
731
|
+
npm install
|
|
732
|
+
npm test # Run all tests
|
|
733
|
+
npm test:watch # Watch mode
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
### Test Coverage
|
|
737
|
+
|
|
738
|
+
```
|
|
739
|
+
Test Files 59 passed (59)
|
|
740
|
+
Tests 1354 passed (1354)
|
|
741
|
+
|
|
742
|
+
Coverage: ~70% Statements | ~60% Branches | ~65% Functions | ~70% Lines
|
|
743
|
+
|
|
744
|
+
Coverage Areas:
|
|
745
|
+
- Group Policy: Creator bypass, requireMention, allowlist, open/disabled modes
|
|
746
|
+
- DM Policy: allow/deny/pairing modes, pairing flow
|
|
747
|
+
- Configuration: Schema validation, defaults, helpers
|
|
748
|
+
- Onboarding: Wizard flow, buildConfig
|
|
749
|
+
- Messaging: Processing, dispatch, deduplication, polling, watcher
|
|
750
|
+
- Runtime: State management, pairing store, persistence, caching
|
|
751
|
+
- API: ZTM client, mesh connectivity, permit
|
|
752
|
+
- Utils: Logger, retry, validation, result handling, concurrency
|
|
753
|
+
- Channel: Gateway, plugin, config
|
|
754
|
+
- DI: Container, dependency resolution
|
|
755
|
+
- Types: Result, common utilities, errors
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Debug Logging
|
|
759
|
+
|
|
760
|
+
```bash
|
|
761
|
+
ZTM_CHAT_LOG_LEVEL=debug openclaw restart
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
## Project Structure
|
|
765
|
+
|
|
766
|
+
```
|
|
767
|
+
.
|
|
768
|
+
├── index.ts # Plugin entry point
|
|
769
|
+
├── index.test.ts # Plugin tests
|
|
770
|
+
├── package.json # NPM package config
|
|
771
|
+
├── openclaw.plugin.json # OpenClaw plugin manifest
|
|
772
|
+
├── tsconfig.json # TypeScript config
|
|
773
|
+
├── vitest.config.ts # Test config
|
|
774
|
+
├── eslint.config.js # ESLint config
|
|
775
|
+
├── prettier.config.js # Prettier config
|
|
776
|
+
└── src/
|
|
777
|
+
├── api/ # ZTM API client
|
|
778
|
+
│ ├── ztm-api.ts # Main API client factory
|
|
779
|
+
│ ├── chat-api.ts # Send/receive messages
|
|
780
|
+
│ ├── message-api.ts # Message operations (list, read, delete)
|
|
781
|
+
│ ├── mesh-api.ts # Mesh network operations
|
|
782
|
+
│ ├── file-api.ts # File transfers
|
|
783
|
+
│ ├── request.ts # HTTP request utilities with retry
|
|
784
|
+
│ ├── test-utils.ts # Test utilities for API
|
|
785
|
+
│ └── index.ts # Barrel exports
|
|
786
|
+
├── channel/ # OpenClaw channel adapter
|
|
787
|
+
│ ├── plugin.ts # Main plugin definition
|
|
788
|
+
│ ├── gateway.ts # Account lifecycle
|
|
789
|
+
│ ├── config.ts # Account configuration resolution
|
|
790
|
+
│ ├── state.ts # Account state management
|
|
791
|
+
│ ├── connectivity-manager.ts # Mesh connectivity monitoring
|
|
792
|
+
│ ├── message-dispatcher.ts # Message dispatch to callbacks
|
|
793
|
+
│ └── index.ts # Barrel exports
|
|
794
|
+
├── config/ # Configuration
|
|
795
|
+
│ ├── schema.ts # TypeBox schema definitions
|
|
796
|
+
│ ├── defaults.ts # Default values
|
|
797
|
+
│ ├── validation.ts # Config validation
|
|
798
|
+
│ ├── helpers.ts # Config helpers
|
|
799
|
+
│ └── index.ts # Barrel exports
|
|
800
|
+
├── connectivity/ # Network connectivity
|
|
801
|
+
│ ├── mesh.ts # Mesh operations
|
|
802
|
+
│ ├── permit.ts # Permit management
|
|
803
|
+
│ └── index.ts # Barrel exports
|
|
804
|
+
├── core/ # Core business logic
|
|
805
|
+
│ ├── group-policy.ts # Group permissions
|
|
806
|
+
│ ├── dm-policy.ts # DM policy
|
|
807
|
+
│ └── index.ts # Barrel exports
|
|
808
|
+
├── di/ # Dependency injection
|
|
809
|
+
│ ├── container.ts # DI container
|
|
810
|
+
│ ├── index.ts # Service factories & barrel exports
|
|
811
|
+
│ └── example-usage.ts # Usage examples
|
|
812
|
+
├── messaging/ # Message processing
|
|
813
|
+
│ ├── processor.ts # Message validation & normalization
|
|
814
|
+
│ ├── chat-processor.ts # High-level chat processing
|
|
815
|
+
│ ├── message-processor-helpers.ts # Shared utilities
|
|
816
|
+
│ ├── dispatcher.ts # Policy checking & dispatch
|
|
817
|
+
│ ├── outbound.ts # Send messages
|
|
818
|
+
│ ├── watcher.ts # Watch mechanism
|
|
819
|
+
│ ├── polling.ts # Polling fallback
|
|
820
|
+
│ ├── index.ts # Barrel exports
|
|
821
|
+
│ └── *.test.ts # Test files
|
|
822
|
+
├── onboarding/ # Setup wizard
|
|
823
|
+
│ ├── onboarding.ts # CLI wizard implementation
|
|
824
|
+
│ └── index.ts # Barrel exports
|
|
825
|
+
├── runtime/ # Runtime management
|
|
826
|
+
│ ├── runtime.ts # Runtime provider interface
|
|
827
|
+
│ ├── state.ts # Account runtime state
|
|
828
|
+
│ ├── store.ts # Message state persistence
|
|
829
|
+
│ ├── pairing-store.ts # Pairing request persistence
|
|
830
|
+
│ ├── cache.ts # LRU cache for group permissions
|
|
831
|
+
│ ├── repository.ts # Repository interfaces
|
|
832
|
+
│ ├── repository-impl.ts # Repository implementations
|
|
833
|
+
│ └── index.ts # Barrel exports
|
|
834
|
+
├── types/ # TypeScript types
|
|
835
|
+
│ ├── api.ts # ZTM API types
|
|
836
|
+
│ ├── config.ts # Configuration types
|
|
837
|
+
│ ├── common.ts # Common types (Result, etc)
|
|
838
|
+
│ ├── errors.ts # Custom error classes
|
|
839
|
+
│ ├── group-policy.ts # Group policy types
|
|
840
|
+
│ ├── messaging.ts # Message types
|
|
841
|
+
│ ├── runtime.ts # Runtime types
|
|
842
|
+
│ ├── connectivity.ts # Connectivity types
|
|
843
|
+
│ └── index.ts # Barrel exports
|
|
844
|
+
├── utils/ # Utilities
|
|
845
|
+
│ ├── logger.ts # Context-aware logger
|
|
846
|
+
│ ├── validation.ts # Input validation
|
|
847
|
+
│ ├── retry.ts # Retry utilities
|
|
848
|
+
│ ├── result.ts # Result/Either type
|
|
849
|
+
│ ├── error.ts # Error handling
|
|
850
|
+
│ ├── guards.ts # Type guards
|
|
851
|
+
│ ├── concurrency.ts # Concurrency utilities
|
|
852
|
+
│ ├── log-sanitize.ts # Log sanitization
|
|
853
|
+
│ ├── paths.ts # Path utilities
|
|
854
|
+
│ ├── time-boundaries.ts # Time utilities
|
|
855
|
+
│ └── index.ts # Barrel exports
|
|
856
|
+
├── mocks/ # Test mocks
|
|
857
|
+
│ ├── ztm-client.ts # Mock ZTM client
|
|
858
|
+
│ └── index.ts # Barrel exports
|
|
859
|
+
└── test-utils/ # Test utilities
|
|
860
|
+
├── fixtures.ts # Test fixtures
|
|
861
|
+
├── mocks.ts # Test mocks
|
|
862
|
+
├── helpers.ts # Test helpers
|
|
863
|
+
├── vitest-setup.ts # Vitest setup
|
|
864
|
+
└── index.ts # Barrel exports
|
|
865
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flomesh/ztm-chat",
|
|
3
|
+
"version": "2026.2.15",
|
|
4
|
+
"description": "ZTM Chat channel plugin for OpenClaw",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"overrides": {
|
|
18
|
+
"tar": ">=7.5.7"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"lint": "eslint src --ext .ts",
|
|
26
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@sinclair/typebox": "^0.34.48",
|
|
31
|
+
"openclaw": "^2026.2.9"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^24.10.13",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
36
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
37
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
38
|
+
"eslint": "^9.0.0",
|
|
39
|
+
"prettier": "^3.0.0",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"vitest": "^4.0.18"
|
|
42
|
+
},
|
|
43
|
+
"openclaw": {
|
|
44
|
+
"extensions": [
|
|
45
|
+
"./index.ts"
|
|
46
|
+
],
|
|
47
|
+
"channel": {
|
|
48
|
+
"id": "ztm-chat",
|
|
49
|
+
"label": "ZTM Chat",
|
|
50
|
+
"selectionLabel": "ZTM Chat",
|
|
51
|
+
"blurb": "Decentralized P2P messaging via ZTM network",
|
|
52
|
+
"aliases": ["ztm"],
|
|
53
|
+
"order": 40,
|
|
54
|
+
"quickstartAllowFrom": true
|
|
55
|
+
},
|
|
56
|
+
"install": {
|
|
57
|
+
"npmSpec": "@flomesh/ztm-chat",
|
|
58
|
+
"localPath": "extensions/ztm-chat",
|
|
59
|
+
"defaultChoice": "npm"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"publishConfig": {
|
|
63
|
+
"access": "public"
|
|
64
|
+
}
|
|
65
|
+
}
|