clawmatrix 0.2.11 → 0.4.0
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 +27 -0
- package/README.md +123 -12
- package/cli/bin/clawmatrix.mjs +1006 -0
- package/cli/package.json +27 -0
- package/cli/skills/clawmatrix/SKILL.md +104 -0
- package/openclaw.plugin.json +1 -0
- package/package.json +3 -1
- package/src/acp-proxy.ts +820 -96
- package/src/cluster-service.ts +186 -16
- package/src/compat.ts +0 -6
- package/src/config.ts +8 -5
- package/src/connection.ts +61 -55
- package/src/e2e/helpers.ts +1 -5
- package/src/file-transfer.ts +64 -14
- package/src/handoff.ts +21 -8
- package/src/health-tracker.ts +40 -11
- package/src/index.ts +686 -14
- package/src/knowledge-sync.ts +62 -10
- package/src/model-proxy.ts +40 -10
- package/src/peer-manager.ts +114 -17
- package/src/rate-limiter.ts +16 -10
- package/src/router.ts +115 -33
- package/src/sentinel-manager.ts +51 -0
- package/src/sentinel.ts +13 -3
- package/src/tool-proxy.ts +52 -6
- package/src/tools/cluster-diagnostic.ts +3 -2
- package/src/tools/cluster-edit.ts +2 -1
- package/src/tools/cluster-events.ts +3 -1
- package/src/tools/cluster-exec.ts +2 -0
- package/src/tools/cluster-handoff.ts +3 -1
- package/src/tools/cluster-notify.ts +132 -0
- package/src/tools/cluster-peers.ts +3 -1
- package/src/tools/cluster-read.ts +4 -1
- package/src/tools/cluster-send.ts +2 -1
- package/src/tools/cluster-terminal.ts +4 -7
- package/src/tools/cluster-tool.ts +2 -2
- package/src/tools/cluster-write.ts +3 -1
- package/src/types.ts +103 -1
- package/src/web.ts +2 -10
- package/src/cli.ts +0 -243
- package/src/web-ui.ts +0 -1622
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Ruiming Zhuang
|
|
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.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Note: The contents of `contrib/ios-node/` and `contrib/mac-app/` are licensed
|
|
26
|
+
separately under the Business Source License 1.1 (BSL-1.1). See the LICENSE
|
|
27
|
+
files in those directories for details.
|
package/README.md
CHANGED
|
@@ -2,19 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# ClawMatrix
|
|
4
4
|
|
|
5
|
-
A decentralized mesh cluster plugin that connects multiple [OpenClaw](https://github.com/nicepkg/openclaw) Gateways into a peer-to-peer network, sharing Agents, models, tools, and
|
|
5
|
+
A decentralized mesh cluster plugin that connects multiple [OpenClaw](https://github.com/nicepkg/openclaw) Gateways into a peer-to-peer network, sharing Agents, models, tools, files, and workspace knowledge across nodes.
|
|
6
6
|
|
|
7
7
|
> **Warning**: This project is under active development and testing. APIs and protocols may change without notice. Not recommended for production use.
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
+
**Model Proxy** — No API key on your home node? Use LLMs from intranet nodes through the cluster, as if they were local models. Supports both Chat Completions and Responses API with auto-detection.
|
|
12
|
+
|
|
13
|
+
**Task Handoff** — Need intranet resources? Delegate tasks to remote Agents with repository access and stream results back. Supports input continuation for mid-task prompts and automatic failover.
|
|
14
|
+
|
|
15
|
+
**Tool Proxy** — Want to run a command or read a file on a remote node? Call it directly without delegating the entire task. Supports batch invocations in a single round-trip.
|
|
16
|
+
|
|
17
|
+
**ACP Agent Proxy** — Spawn remote coding agents (Claude Code, Codex, Gemini) on other nodes via ACP protocol with persistent sessions.
|
|
18
|
+
|
|
19
|
+
**Interactive Terminal** — Open a PTY session on any remote node for interactive shell access.
|
|
20
|
+
|
|
21
|
+
**File Transfer** — Transfer files up to 100MB between nodes with chunked transfer and SHA-256 integrity check.
|
|
22
|
+
|
|
11
23
|
**Knowledge Sync (optional)** — Synchronize workspace files such as `MEMORY.md`, `memory/*.md`, `skills/`, and other selected knowledge files across nodes using CRDT + mesh sync, with git-friendly local files as the source of truth.
|
|
12
24
|
|
|
13
|
-
**
|
|
25
|
+
**Sentinel** — A detached subprocess that survives OpenClaw crashes, maintains peer connections, and handles diagnostic commands when the gateway is down.
|
|
14
26
|
|
|
15
|
-
**
|
|
27
|
+
**Peer Approval** — Control which nodes can join your mesh with notify or required approval modes. Enabled by default.
|
|
16
28
|
|
|
17
|
-
**
|
|
29
|
+
**E2EE** — X25519 ECDH end-to-end encryption for all post-handshake frames, enabled by default.
|
|
18
30
|
|
|
19
31
|
**Auto-Discovery & Failover** — Gossip protocol automatically discovers nodes; requests are rerouted to backups when a node goes down.
|
|
20
32
|
|
|
@@ -79,13 +91,15 @@ Edit `openclaw.json` to add the plugin configuration. All nodes share the same `
|
|
|
79
91
|
"secret": "your-shared-secret-min-16-chars",
|
|
80
92
|
"peers": [{ "nodeId": "cloud-01", "url": "wss://cloud-01.example.com:19000" }],
|
|
81
93
|
"agents": [{ "id": "assistant", "description": "Personal assistant", "tags": ["general"] }],
|
|
82
|
-
"proxyModels": [
|
|
94
|
+
"proxyModels": [
|
|
95
|
+
{ "nodeId": "office-01", "models": [{ "id": "claude-sonnet" }] }
|
|
96
|
+
]
|
|
83
97
|
}
|
|
84
98
|
```
|
|
85
99
|
|
|
86
100
|
**Important**: Nodes sharing models only need to declare `{ id, provider }` in `models`. ClawMatrix automatically reads the corresponding `baseUrl` and `apiKey` from OpenClaw's `models.providers` and calls the model API directly (bypassing the OpenClaw Gateway's agent system).
|
|
87
101
|
|
|
88
|
-
Nodes consuming remote models need to register them in `models.providers` (using the nodeId as the key, with baseUrl pointing to
|
|
102
|
+
Nodes consuming remote models need to register them in `models.providers` (using the nodeId as the key, with baseUrl pointing to the proxy port). See [BOOTSTRAP.md](BOOTSTRAP.md) for details.
|
|
89
103
|
|
|
90
104
|
To use a cluster model: `/model <nodeId>/<modelId>`.
|
|
91
105
|
|
|
@@ -103,34 +117,128 @@ After installation, the Agent automatically gains access to the following tools:
|
|
|
103
117
|
| Tool | Description |
|
|
104
118
|
|------|-------------|
|
|
105
119
|
| `cluster_handoff` | Delegate a task to a remote Agent and wait for the result |
|
|
120
|
+
| `cluster_handoff_reply` | Continue a handoff by sending additional input to the remote Agent |
|
|
106
121
|
| `cluster_send` | Send a one-way message to a remote Agent |
|
|
107
122
|
| `cluster_peers` | View cluster topology and connection status |
|
|
108
123
|
| `cluster_exec` | Execute a command on a remote node |
|
|
109
124
|
| `cluster_read` | Read a file on a remote node |
|
|
110
125
|
| `cluster_write` | Write a file on a remote node |
|
|
126
|
+
| `cluster_edit` | Edit (find-and-replace) a file on a remote node |
|
|
127
|
+
| `cluster_batch` | Execute multiple tools on a remote node in one round-trip |
|
|
111
128
|
| `cluster_tool` | Invoke any OpenClaw tool on a remote node |
|
|
129
|
+
| `cluster_terminal` | Open an interactive PTY session on a remote node |
|
|
130
|
+
| `cluster_transfer` | Transfer files between local and remote nodes (up to 100MB) |
|
|
131
|
+
| `cluster_events` | Query and consume cluster events |
|
|
132
|
+
| `cluster_diagnostic` | Diagnose or exec on a remote node's sentinel (works even when gateway is down) |
|
|
133
|
+
| `cluster_acp` | Spawn a remote coding agent (Claude Code, Codex, Gemini, etc.) via ACP |
|
|
112
134
|
|
|
113
135
|
The target parameter supports nodeId (`"office-01"`) or tag queries (`"tags:coding"`).
|
|
114
136
|
|
|
115
137
|
## Configuration Reference
|
|
116
138
|
|
|
139
|
+
### Core
|
|
140
|
+
|
|
117
141
|
| Field | Type | Default | Description |
|
|
118
142
|
|-------|------|---------|-------------|
|
|
119
143
|
| `nodeId` | string | required | Unique node identifier |
|
|
120
144
|
| `secret` | string | required | Cluster shared secret (>= 16 characters) |
|
|
121
145
|
| `listen` | boolean | `false` | Accept inbound WS connections |
|
|
122
146
|
| `listenHost` | string | `"0.0.0.0"` | Listen address |
|
|
123
|
-
| `listenPort` | number | `
|
|
147
|
+
| `listenPort` | number | `0` (random) | Inbound WS port |
|
|
124
148
|
| `peers` | array | `[]` | Peers to connect to: `{ nodeId, url }` |
|
|
125
149
|
| `agents` | array | `[]` | Local Agents: `{ id, description, tags }` |
|
|
126
150
|
| `models` | array | `[]` | Models shared with the cluster: `{ id, provider }` (auto-reads OpenClaw provider config; optional `baseUrl`/`apiKey` override) |
|
|
127
|
-
| `proxyModels` | array | `[]` | Remote
|
|
128
|
-
| `tags` | array | `[]` | Free-form tags |
|
|
129
|
-
| `proxyPort` | number | `
|
|
151
|
+
| `proxyModels` | array | `[]` | Remote model groups to consume: `{ nodeId, models: [{ id }] }` |
|
|
152
|
+
| `tags` | array | `[]` | Free-form node tags |
|
|
153
|
+
| `proxyPort` | number | `0` (random) | Local model proxy port |
|
|
154
|
+
| `e2ee` | boolean | `true` | End-to-end encryption (X25519 ECDH) |
|
|
155
|
+
| `compression` | boolean | `false` | Message compression |
|
|
156
|
+
|
|
157
|
+
### Timeouts
|
|
158
|
+
|
|
159
|
+
| Field | Type | Default | Description |
|
|
160
|
+
|-------|------|---------|-------------|
|
|
130
161
|
| `handoffTimeout` | number | `600000` | Handoff timeout (ms) |
|
|
162
|
+
| `modelTimeout` | number | `120000` | Model proxy request timeout (ms) |
|
|
163
|
+
| `toolTimeout` | number | `30000` | Tool execution timeout (ms) |
|
|
164
|
+
| `disconnectGrace` | number | `30000` | Grace period before broadcasting peer_leave (ms) |
|
|
165
|
+
|
|
166
|
+
### Tool Proxy
|
|
167
|
+
|
|
168
|
+
| Field | Type | Default | Description |
|
|
169
|
+
|-------|------|---------|-------------|
|
|
131
170
|
| `toolProxy.enabled` | boolean | `false` | Allow remote tool execution |
|
|
132
|
-
| `toolProxy.allow` | array | `[]` | Allowed tool names; `["*"]` or `[]` means all
|
|
171
|
+
| `toolProxy.allow` | array | `[]` | Allowed tool names; `["*"]` or `[]` means all |
|
|
133
172
|
| `toolProxy.deny` | array | `[]` | Denied tools (takes precedence over allow) |
|
|
173
|
+
| `toolProxy.maxOutputBytes` | number | `1048576` | Max tool output size (bytes) |
|
|
174
|
+
|
|
175
|
+
### Peer Approval
|
|
176
|
+
|
|
177
|
+
Peer approval accepts either a boolean shorthand or an object. The default is `true` (required mode enabled).
|
|
178
|
+
|
|
179
|
+
| Field | Type | Default | Description |
|
|
180
|
+
|-------|------|---------|-------------|
|
|
181
|
+
| `peerApproval` | boolean \| object | `true` | `true` = required mode, `false` = disabled, or object for fine-grained config |
|
|
182
|
+
| `peerApproval.enabled` | boolean | `false` | Enable peer approval (object form) |
|
|
183
|
+
| `peerApproval.mode` | string | `"notify"` | `"notify"` (log only) or `"required"` (block until approved) |
|
|
184
|
+
| `peerApproval.timeout` | number | `1200000` | Approval request timeout (ms) |
|
|
185
|
+
| `peerApproval.allowList` | array | `[]` | NodeIds that skip approval |
|
|
186
|
+
| `peerApproval.persistPath` | string | `"approved-peers.json"` | Path to store approved peers |
|
|
187
|
+
| `peerApproval.notifyTargets` | array | `[]` | Notification targets: `{ channel, to, accountId?, threadId? }` |
|
|
188
|
+
|
|
189
|
+
### Terminal
|
|
190
|
+
|
|
191
|
+
| Field | Type | Default | Description |
|
|
192
|
+
|-------|------|---------|-------------|
|
|
193
|
+
| `terminal.enabled` | boolean | `true` | Allow remote PTY sessions |
|
|
194
|
+
| `terminal.shell` | string | system default | Shell to use |
|
|
195
|
+
| `terminal.sessionTTL` | number | `1800000` | Idle session timeout (ms) |
|
|
196
|
+
| `terminal.maxSessions` | number | `3` | Max concurrent PTY sessions |
|
|
197
|
+
| `terminal.allowFrom` | array | `[]` | Allowed nodeIds (empty = all) |
|
|
198
|
+
|
|
199
|
+
### File Transfer
|
|
200
|
+
|
|
201
|
+
| Field | Type | Default | Description |
|
|
202
|
+
|-------|------|---------|-------------|
|
|
203
|
+
| `fileTransfer.enabled` | boolean | `false` | Allow file transfers |
|
|
204
|
+
| `fileTransfer.chunkSize` | number | `262144` | Chunk size in bytes (256KB) |
|
|
205
|
+
| `fileTransfer.maxFileSize` | number | `104857600` | Max file size (100MB) |
|
|
206
|
+
| `fileTransfer.timeout` | number | `300000` | Per-chunk timeout (ms) |
|
|
207
|
+
| `fileTransfer.allowedPaths` | array | `[]` | Allowed paths (empty = no restriction) |
|
|
208
|
+
|
|
209
|
+
### Knowledge Sync
|
|
210
|
+
|
|
211
|
+
| Field | Type | Default | Description |
|
|
212
|
+
|-------|------|---------|-------------|
|
|
213
|
+
| `knowledge.enabled` | boolean | `false` | Enable CRDT knowledge sync |
|
|
214
|
+
| `knowledge.paths` | array | `[]` | File/glob patterns to sync |
|
|
215
|
+
| `knowledge.debounce` | number | `5000` | File watch debounce (ms) |
|
|
216
|
+
| `knowledge.maxFileSize` | number | `524288` | Max file size to sync (bytes) |
|
|
217
|
+
|
|
218
|
+
### ACP Agents
|
|
219
|
+
|
|
220
|
+
| Field | Type | Default | Description |
|
|
221
|
+
|-------|------|---------|-------------|
|
|
222
|
+
| `acp.enabled` | boolean | `false` | Enable ACP agent proxy |
|
|
223
|
+
| `acp.agents` | array | `[]` | Available agents: `{ id, description }` |
|
|
224
|
+
| `acp.commands` | object | `{}` | Override spawn commands per agent name |
|
|
225
|
+
| `acp.timeout` | number | `600000` | Per-turn timeout (ms) |
|
|
226
|
+
| `acp.sessionTTL` | number | `1800000` | Idle session TTL (ms) |
|
|
227
|
+
| `acp.maxSessions` | number | `5` | Max concurrent ACP sessions |
|
|
228
|
+
|
|
229
|
+
### Sentinel
|
|
230
|
+
|
|
231
|
+
| Field | Type | Default | Description |
|
|
232
|
+
|-------|------|---------|-------------|
|
|
233
|
+
| `sentinel.enabled` | boolean | `true` | Enable sentinel subprocess |
|
|
234
|
+
| `sentinel.listenPort` | number | same as `listenPort` | Port sentinel listens on (takes over when gateway dies) |
|
|
235
|
+
|
|
236
|
+
### Web UI
|
|
237
|
+
|
|
238
|
+
| Field | Type | Default | Description |
|
|
239
|
+
|-------|------|---------|-------------|
|
|
240
|
+
| `web.enabled` | boolean | `false` | Enable HTTP web interface |
|
|
241
|
+
| `web.token` | string | required if enabled | Auth token (>= 8 characters) |
|
|
134
242
|
|
|
135
243
|
## Architecture
|
|
136
244
|
|
|
@@ -149,9 +257,12 @@ The target parameter supports nodeId (`"office-01"`) or tag queries (`"tags:codi
|
|
|
149
257
|
```
|
|
150
258
|
|
|
151
259
|
- Decentralized mesh — no leader, no consensus protocol
|
|
152
|
-
- HMAC-SHA256 challenge-response authentication
|
|
260
|
+
- X25519 TOFU identity + HMAC-SHA256 challenge-response authentication
|
|
261
|
+
- End-to-end encryption via X25519 ECDH (enabled by default)
|
|
153
262
|
- Message relay + TTL loop prevention + ID deduplication
|
|
263
|
+
- Per-IP rate limiting on inbound connections
|
|
154
264
|
- Heartbeat detection + exponential backoff reconnection + automatic failover
|
|
265
|
+
- Sentinel survives gateway crashes and takes over the listen port
|
|
155
266
|
- `wss://` (TLS) recommended for production
|
|
156
267
|
|
|
157
268
|
## Development
|