nodeclaw 0.1.0-alpha.1
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 +230 -0
- package/dist/chunk-F5XQ5PZF.js +9 -0
- package/dist/chunk-F5XQ5PZF.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1754 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
<h1 align="center">NodeClaw</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Minimal OpenClaw node protocol client — everything a node needs, nothing it doesn't.</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Full protocol v3 compatibility · Ed25519 device identity · Auto-reconnect · systemd/launchd ready
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://github.com/scottgl9/NodeClaw/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License" /></a>
|
|
13
|
+
<a href="https://github.com/scottgl9/NodeClaw/stargazers"><img src="https://img.shields.io/github/stars/scottgl9/NodeClaw" alt="GitHub stars" /></a>
|
|
14
|
+
<a href="https://github.com/scottgl9/NodeClaw/actions"><img src="https://img.shields.io/github/actions/workflow/status/scottgl9/NodeClaw/ci.yml?branch=main" alt="Build" /></a>
|
|
15
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="Node.js >= 20" />
|
|
16
|
+
<img src="https://img.shields.io/badge/tests-99%20passing-brightgreen" alt="99 tests passing" />
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g nodeclaw
|
|
25
|
+
|
|
26
|
+
# Pair with your OpenClaw gateway
|
|
27
|
+
nodeclaw pair wss://my-gateway:18789
|
|
28
|
+
|
|
29
|
+
# Start the node daemon
|
|
30
|
+
nodeclaw start
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
That's it. NodeClaw connects to your [OpenClaw](https://github.com/openclaw/openclaw) gateway and receives tasks — shell execution, system metrics, binary lookup — over a single outbound WebSocket.
|
|
34
|
+
|
|
35
|
+
## Why NodeClaw?
|
|
36
|
+
|
|
37
|
+
Running a full OpenClaw instance on every device is heavyweight. The full stack includes a gateway daemon, 20+ channel adapters, agent runtime, skills system, workspace, memory, and web UI. For devices that only need to **receive tasks and execute them**, none of that is needed.
|
|
38
|
+
|
|
39
|
+
| | What you get |
|
|
40
|
+
| -------------------------- | ---------------------------------------------------------------------------- |
|
|
41
|
+
| **Minimal footprint** | Single 42KB bundle, < 50MB RSS at idle — runs on Raspberry Pi, NAS, any VPS |
|
|
42
|
+
| **Full protocol compat** | Pairs and communicates with any OpenClaw gateway (protocol v3) |
|
|
43
|
+
| **Zero gateway** | No HTTP server, no channel adapters, no agent runtime, no web UI |
|
|
44
|
+
| **Secure by design** | Ed25519 identity, challenge-nonce handshake, no inbound ports |
|
|
45
|
+
| **Operationally simple** | Single config file, single process, systemd/launchd ready |
|
|
46
|
+
| **Auto-reconnect** | Exponential backoff (1s → 30s), tick-based health monitoring |
|
|
47
|
+
|
|
48
|
+
## How it compares
|
|
49
|
+
|
|
50
|
+
| Feature | NodeClaw | Full OpenClaw |
|
|
51
|
+
| ---------------------- | :---------------: | :-----------------------: |
|
|
52
|
+
| Receive & execute tasks | Yes | Yes |
|
|
53
|
+
| Gateway / HTTP server | No | Yes |
|
|
54
|
+
| Channel adapters | No | 20+ (Discord, etc.) |
|
|
55
|
+
| Agent runtime / LLM | No | Yes |
|
|
56
|
+
| Skills / memory / UI | No | Yes |
|
|
57
|
+
| Idle memory | < 50 MB | 200+ MB |
|
|
58
|
+
| Install footprint | 42 KB | 200+ MB npm |
|
|
59
|
+
| Startup time | < 2s | 5–10s |
|
|
60
|
+
| Service management | systemd / launchd | pm2 / Docker |
|
|
61
|
+
| Config complexity | Single JSON file | Multi-file + env + DB |
|
|
62
|
+
|
|
63
|
+
## Target Use Cases
|
|
64
|
+
|
|
65
|
+
- **Edge / SBC devices** — Raspberry Pi, Rock64 — remote shell + metrics without the full Node.js stack
|
|
66
|
+
- **Dedicated workstation** — dev machine or home server as a pure execution target
|
|
67
|
+
- **VPS / cloud node** — lightweight instance for task dispatch at a fraction of the cost
|
|
68
|
+
- **Air-gapped / private network** — devices behind Tailscale or VPN, outbound WS only
|
|
69
|
+
- **Local inference node** *(future)* — GPU machine running Ollama, registered as an inference-capable node
|
|
70
|
+
|
|
71
|
+
## CLI Reference
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Pairing
|
|
75
|
+
nodeclaw pair <gateway-url> # Pair with an OpenClaw gateway
|
|
76
|
+
nodeclaw unpair [--full] # Remove pairing token (--full removes identity)
|
|
77
|
+
|
|
78
|
+
# Running
|
|
79
|
+
nodeclaw start # Start node daemon (foreground)
|
|
80
|
+
|
|
81
|
+
# Status
|
|
82
|
+
nodeclaw status # Show pairing and connection status
|
|
83
|
+
nodeclaw info # Show version, protocol, platform
|
|
84
|
+
nodeclaw doctor # Run configuration health checks
|
|
85
|
+
|
|
86
|
+
# Service management
|
|
87
|
+
nodeclaw install-service # Install systemd (Linux) or launchd (macOS)
|
|
88
|
+
nodeclaw uninstall-service # Remove installed service
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
**`~/.nodeclaw/config.json`**
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"gateway": {
|
|
98
|
+
"url": "wss://my-gateway:18789",
|
|
99
|
+
"tlsVerify": true
|
|
100
|
+
},
|
|
101
|
+
"device": {
|
|
102
|
+
"name": "pi-node-01",
|
|
103
|
+
"workdir": "/home/pi/workspace"
|
|
104
|
+
},
|
|
105
|
+
"exec": {
|
|
106
|
+
"blockedCommands": ["rm -rf /", "sudo"],
|
|
107
|
+
"timeoutMs": 60000,
|
|
108
|
+
"maxConcurrent": 3
|
|
109
|
+
},
|
|
110
|
+
"log": {
|
|
111
|
+
"level": "info"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Override the config directory with `NODECLAW_HOME=/custom/path`.
|
|
117
|
+
|
|
118
|
+
## Architecture
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
┌─────────────────────────────────────────────┐
|
|
122
|
+
│ NodeClaw Process │
|
|
123
|
+
│ │
|
|
124
|
+
│ ┌──────────┐ ┌─────────────────────────┐│
|
|
125
|
+
│ │ CLI │ │ Core Runtime ││
|
|
126
|
+
│ │ (pair, │ │ ││
|
|
127
|
+
│ │ start, │ │ ┌─────────────────┐ ││
|
|
128
|
+
│ │ status) │ │ │ WS Client │ ││
|
|
129
|
+
│ └──────────┘ │ │ (gateway conn) │ ││
|
|
130
|
+
│ │ └────────┬────────┘ ││
|
|
131
|
+
│ │ │ ││
|
|
132
|
+
│ │ ┌────────▼────────┐ ││
|
|
133
|
+
│ │ │ Command Router │ ││
|
|
134
|
+
│ │ └────────┬────────┘ ││
|
|
135
|
+
│ │ │ ││
|
|
136
|
+
│ │ ┌────────▼────────┐ ││
|
|
137
|
+
│ │ │ Handlers │ ││
|
|
138
|
+
│ │ │ - system.run │ ││
|
|
139
|
+
│ │ │ - system.info │ ││
|
|
140
|
+
│ │ │ - system.which │ ││
|
|
141
|
+
│ │ └─────────────────┘ ││
|
|
142
|
+
│ └─────────────────────────┘│
|
|
143
|
+
└─────────────────────────────────────────────┘
|
|
144
|
+
│ outbound WS only
|
|
145
|
+
▼
|
|
146
|
+
┌──────────────────────┐
|
|
147
|
+
│ OpenClaw Gateway │
|
|
148
|
+
│ (host machine) │
|
|
149
|
+
└──────────────────────┘
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Modules
|
|
153
|
+
|
|
154
|
+
| Module | Description |
|
|
155
|
+
| ------------ | --------------------------------------------------------------- |
|
|
156
|
+
| `config/` | Zod-validated config schema, loader, path resolution |
|
|
157
|
+
| `crypto/` | Ed25519 identity, v3 device auth payload, token store |
|
|
158
|
+
| `protocol/` | Wire frame types, connect params, node invoke types, guards |
|
|
159
|
+
| `client/` | WebSocket client — two-phase handshake, backoff, tick watch |
|
|
160
|
+
| `pairing/` | Device pairing flow with token persistence |
|
|
161
|
+
| `runtime/` | Command router, event dispatch, node lifecycle |
|
|
162
|
+
| `handlers/` | system.run (exec), system.info (metrics), system.which (lookup) |
|
|
163
|
+
| `service/` | systemd unit and launchd plist generation |
|
|
164
|
+
| `cli/` | Commander-based CLI — pair, start, status, unpair, doctor |
|
|
165
|
+
|
|
166
|
+
## Security & Privacy
|
|
167
|
+
|
|
168
|
+
NodeClaw is designed for zero-trust environments. No inbound ports, no listening sockets.
|
|
169
|
+
|
|
170
|
+
| | NodeClaw |
|
|
171
|
+
| -------------------------- | --------------------------------------------------------------- |
|
|
172
|
+
| **Network posture** | Outbound WebSocket only — no inbound ports, no HTTP server |
|
|
173
|
+
| **Device identity** | Ed25519 keypair, SHA-256 device ID, stored with `0600` perms |
|
|
174
|
+
| **Authentication** | Two-phase challenge-nonce handshake — prevents replay attacks |
|
|
175
|
+
| **Transport** | TLS validation enforced for `wss://`, no insecure override |
|
|
176
|
+
| **Exec sandboxing** | Commands bounded to configured `workdir` path |
|
|
177
|
+
| **Command policy** | Configurable blocklist + concurrent execution limits |
|
|
178
|
+
| **Output cap** | 200KB stdout/stderr cap — prevents memory exhaustion |
|
|
179
|
+
| **Timeout enforcement** | Per-command timeout with SIGKILL escalation |
|
|
180
|
+
|
|
181
|
+
## Connection Lifecycle
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
nodeclaw pair <gateway-url>
|
|
185
|
+
→ WS connect to gateway
|
|
186
|
+
→ Receive connect.challenge (nonce)
|
|
187
|
+
→ Sign v3 auth payload with Ed25519
|
|
188
|
+
→ Send connect request with device identity
|
|
189
|
+
→ Gateway approves → device token stored
|
|
190
|
+
|
|
191
|
+
nodeclaw start
|
|
192
|
+
→ Load stored device token
|
|
193
|
+
→ WS connect with signed auth
|
|
194
|
+
→ Enter event loop:
|
|
195
|
+
← tick (heartbeat) → update health
|
|
196
|
+
← node.invoke.request → route to handler → execute → send result
|
|
197
|
+
← disconnect → reconnect with exponential backoff (1s → 30s)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Development
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git clone https://github.com/scottgl9/NodeClaw.git
|
|
204
|
+
cd NodeClaw
|
|
205
|
+
pnpm install
|
|
206
|
+
pnpm test # 99 tests across 19 test files
|
|
207
|
+
pnpm build # Build to dist/
|
|
208
|
+
pnpm dev start # Run CLI in dev mode
|
|
209
|
+
pnpm typecheck # TypeScript type checking
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Tech Stack
|
|
213
|
+
|
|
214
|
+
| Layer | Choice | Rationale |
|
|
215
|
+
| ---------------- | ------------ | ------------------------------------------------ |
|
|
216
|
+
| Runtime | Node.js 20+ | Matches OpenClaw's runtime, native crypto module |
|
|
217
|
+
| WS Client | `ws` | Battle-tested, minimal, same lib OpenClaw uses |
|
|
218
|
+
| CLI | `commander` | Standard Node.js CLI framework |
|
|
219
|
+
| Config | `zod` | Schema validation with TypeScript inference |
|
|
220
|
+
| Build | `tsup` | Fast ESM bundling with declarations |
|
|
221
|
+
| Test | `vitest` | Fast, ESM-native test runner |
|
|
222
|
+
|
|
223
|
+
## Community
|
|
224
|
+
|
|
225
|
+
- [GitHub Issues](https://github.com/scottgl9/NodeClaw/issues) — Bug reports and feature requests
|
|
226
|
+
- [OpenClaw](https://github.com/openclaw/openclaw) — The gateway NodeClaw pairs with
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export const VERSION = \"0.1.0\";\nexport const PROTOCOL_VERSION = 3;\n"],"mappings":";AAAO,IAAM,UAAU;AAChB,IAAM,mBAAmB;","names":[]}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|