clawaxis 1.0.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/CLAWAXIS.md +954 -0
- package/LICENSE +21 -0
- package/README.md +441 -0
- package/index.ts +53 -0
- package/openclaw.plugin.json +86 -0
- package/package.json +33 -0
- package/src/channel.ts +78 -0
- package/src/config.ts +82 -0
- package/src/governance/hooks.ts +92 -0
- package/src/governance/logging.ts +58 -0
- package/src/governance/style-injection.ts +114 -0
- package/src/governance/validation.ts +206 -0
- package/src/message-handler.ts +212 -0
- package/src/runtime.ts +91 -0
- package/src/sync/documents.ts +127 -0
- package/src/sync/routines.ts +56 -0
- package/src/tools/content.ts +64 -0
- package/src/tools/helpers.ts +40 -0
- package/src/tools/index.ts +16 -0
- package/src/tools/logging.ts +33 -0
- package/src/tools/media.ts +21 -0
- package/src/tools/memory.ts +78 -0
- package/src/tools/routines.ts +54 -0
- package/src/tools/sync.ts +36 -0
- package/src/types.ts +64 -0
- package/src/utils.ts +161 -0
- package/src/websocket.ts +294 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ClawAxis
|
|
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,441 @@
|
|
|
1
|
+
# ClawAxis Plugin for OpenClaw
|
|
2
|
+
|
|
3
|
+
**Version:** 1.0.0
|
|
4
|
+
**License:** MIT
|
|
5
|
+
**Status:** Production Ready
|
|
6
|
+
|
|
7
|
+
Official OpenClaw channel plugin for ClawAxis - enables real-time communication between your OpenClaw agent and the ClawAxis iOS app.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
### Real-Time WebSocket Communication
|
|
14
|
+
- Persistent WebSocket connection to ClawAxis relay (Supabase)
|
|
15
|
+
- Automatic reconnection with exponential backoff
|
|
16
|
+
- Bidirectional messaging (user <-> agent)
|
|
17
|
+
- Message status updates ("processing", "complete", "error")
|
|
18
|
+
- Keepalive pings + periodic heartbeats
|
|
19
|
+
|
|
20
|
+
### Three-Layer Governance System
|
|
21
|
+
|
|
22
|
+
**Layer 1: Activity Logging**
|
|
23
|
+
- Real-time visibility into agent operations
|
|
24
|
+
- Batched relay calls (debounced, max 10/batch)
|
|
25
|
+
- Tool execution tracking with duration/tokens/cost
|
|
26
|
+
- Error and warning collection
|
|
27
|
+
|
|
28
|
+
**Layer 2: Style Injection**
|
|
29
|
+
- Automatic brand guideline enforcement
|
|
30
|
+
- Memory-based style doc search (cached 5 minutes)
|
|
31
|
+
- Content-aware injection (blog/social/image tools)
|
|
32
|
+
- Zero manual prompt engineering required
|
|
33
|
+
|
|
34
|
+
**Layer 3: Content Validation**
|
|
35
|
+
- Pre-publish quality checks (CTA, image domains, attribution)
|
|
36
|
+
- Auto-fix for common issues
|
|
37
|
+
- Blocking errors vs non-blocking warnings
|
|
38
|
+
- Permanent image URL enforcement (R2/S3/B2)
|
|
39
|
+
|
|
40
|
+
### 10 Registered Tools
|
|
41
|
+
|
|
42
|
+
| Tool | Purpose |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| `clawaxis_post_content` | Post content for review (blog, social, website, email, ad) |
|
|
45
|
+
| `clawaxis_update_content` | Edit existing content by ID |
|
|
46
|
+
| `clawaxis_get_content` | Retrieve content list or specific item |
|
|
47
|
+
| `clawaxis_post_log` | Manual activity logging |
|
|
48
|
+
| `clawaxis_confirm_doc_sync` | Confirm document upload received |
|
|
49
|
+
| `clawaxis_confirm_routine_sync` | Confirm cron job created |
|
|
50
|
+
| `clawaxis_notify_routine` | Register new routine/cron in app |
|
|
51
|
+
| `clawaxis_update_routine` | Update existing routine in app |
|
|
52
|
+
| `clawaxis_upload_media` | Upload image to R2 (permanent storage) |
|
|
53
|
+
| `clawaxis_memory_search` | Search ClawAxis governed memory (pgvector) |
|
|
54
|
+
|
|
55
|
+
### Document Sync
|
|
56
|
+
- Automatic document downloads from ClawAxis app
|
|
57
|
+
- Writes to `workspace/memory/docs/{category}/` (auto-indexed by OpenClaw)
|
|
58
|
+
- Agent notification on upload (with confirmation tool)
|
|
59
|
+
- Update detection (version tracking)
|
|
60
|
+
- Deletion handling (file cleanup + agent notification)
|
|
61
|
+
|
|
62
|
+
### Routine/Cron Sync
|
|
63
|
+
- Collaborative model: agent owns cron execution
|
|
64
|
+
- App requests routine -> Agent creates cron -> Confirmation loop
|
|
65
|
+
- Update support (modify existing routines)
|
|
66
|
+
- Full cron expression + human-readable schedule
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
### 1. Install Plugin
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mkdir -p ~/.openclaw/extensions/clawaxis-plugin
|
|
76
|
+
cd ~/.openclaw/extensions/clawaxis-plugin
|
|
77
|
+
|
|
78
|
+
# Download plugin files
|
|
79
|
+
git clone https://github.com/vdiscobot/clawaxis-plugin.git .
|
|
80
|
+
|
|
81
|
+
# Install dependencies (optional - OpenClaw resolves npm modules automatically)
|
|
82
|
+
npm install
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Configure OpenClaw
|
|
86
|
+
|
|
87
|
+
Add to `~/.openclaw/openclaw.json`. The primary config location is `channels.clawaxis`:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"channels": {
|
|
92
|
+
"clawaxis": {
|
|
93
|
+
"relayUrl": "https://fqwpwypyzcbmdeajlkzt.supabase.co/functions/v1/ws-relay",
|
|
94
|
+
"agentToken": "oc_tk_YOUR_AGENT_TOKEN_HERE",
|
|
95
|
+
"mediaDomain": "pub-YOUR_R2_BUCKET.r2.dev",
|
|
96
|
+
"agentName": "YourAgentName"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"bindings": [
|
|
100
|
+
{
|
|
101
|
+
"surface": "clawaxis",
|
|
102
|
+
"channel": "clawaxis",
|
|
103
|
+
"agent": "main",
|
|
104
|
+
"enabled": true
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> **Backward compatibility:** The plugin also reads from `plugins.entries.clawaxis-plugin.config` if `channels.clawaxis` is not present.
|
|
111
|
+
|
|
112
|
+
**Required fields:**
|
|
113
|
+
- `relayUrl` - ClawAxis WebSocket relay endpoint
|
|
114
|
+
- `agentToken` - Your unique agent authentication token (get from ClawAxis app)
|
|
115
|
+
|
|
116
|
+
**Optional fields:**
|
|
117
|
+
- `mediaDomain` - Your R2/S3/B2 bucket domain for permanent image storage
|
|
118
|
+
- `agentName` - Agent's name (for author attribution validation)
|
|
119
|
+
|
|
120
|
+
### 3. Optional: Configure Governance
|
|
121
|
+
|
|
122
|
+
Add governance settings inside the channel config:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"channels": {
|
|
127
|
+
"clawaxis": {
|
|
128
|
+
"relayUrl": "...",
|
|
129
|
+
"agentToken": "...",
|
|
130
|
+
"governance": {
|
|
131
|
+
"imageTools": ["generate_image", "dall_e", "stability"],
|
|
132
|
+
"validation": {
|
|
133
|
+
"requireCTA": true,
|
|
134
|
+
"requirePermanentImages": true,
|
|
135
|
+
"requireValidAuthor": true
|
|
136
|
+
},
|
|
137
|
+
"logging": {
|
|
138
|
+
"enabled": true,
|
|
139
|
+
"logAllTools": false
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 4. Restart OpenClaw
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
openclaw gateway restart
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Check logs for successful connection:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
tail -f ~/.openclaw/logs/gateway.log | grep 🦞
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Expected output:
|
|
160
|
+
```
|
|
161
|
+
🦞 ==========================================
|
|
162
|
+
🦞 🦞 ClawAxis Plugin (WebSocket)
|
|
163
|
+
🦞 ==========================================
|
|
164
|
+
🦞 ✓ Config loaded
|
|
165
|
+
🦞 ✓ Channel 'clawaxis' registered
|
|
166
|
+
🦞 🛡️ Registering governance hooks...
|
|
167
|
+
🦞 ✓ Governance hooks registered (2 hooks)
|
|
168
|
+
🦞 ✅ All 10 tools registered successfully
|
|
169
|
+
🦞 ✓ WebSocket service registered
|
|
170
|
+
🦞 ✓ ClawAxis plugin loaded (WebSocket mode)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Configuration Reference
|
|
176
|
+
|
|
177
|
+
### Core Settings
|
|
178
|
+
|
|
179
|
+
| Field | Type | Required | Description |
|
|
180
|
+
|-------|------|----------|-------------|
|
|
181
|
+
| `relayUrl` | string | Yes | ClawAxis relay endpoint (WebSocket or HTTPS) |
|
|
182
|
+
| `agentToken` | string | Yes | Agent authentication token |
|
|
183
|
+
| `mediaDomain` | string | No | R2/S3/B2 bucket domain for permanent images |
|
|
184
|
+
| `agentName` | string | No | Agent name (used for author validation) |
|
|
185
|
+
|
|
186
|
+
### Governance Settings
|
|
187
|
+
|
|
188
|
+
#### `governance.imageTools`
|
|
189
|
+
Array of tool name patterns to detect image generation tools.
|
|
190
|
+
|
|
191
|
+
**Example:**
|
|
192
|
+
```json
|
|
193
|
+
["generate_image", "dall_e", "stability", "midjourney", "flux"]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### `governance.validation`
|
|
197
|
+
|
|
198
|
+
| Field | Type | Default | Description |
|
|
199
|
+
|-------|------|---------|-------------|
|
|
200
|
+
| `requireCTA` | boolean | `false` | Require call-to-action in blog/website content |
|
|
201
|
+
| `requirePermanentImages` | boolean | `false` | Block content with non-permanent image URLs |
|
|
202
|
+
| `requireValidAuthor` | boolean | `false` | Block content with agent self-attribution |
|
|
203
|
+
| `allowedContentTypes` | string[] | See below | Valid content_type values |
|
|
204
|
+
|
|
205
|
+
**Default allowed content types:**
|
|
206
|
+
```json
|
|
207
|
+
["twitter", "instagram", "linkedin", "facebook", "tiktok", "youtube",
|
|
208
|
+
"blog", "report", "email", "ad", "website", "document", "other"]
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### `governance.logging`
|
|
212
|
+
|
|
213
|
+
| Field | Type | Default | Description |
|
|
214
|
+
|-------|------|---------|-------------|
|
|
215
|
+
| `enabled` | boolean | `true` | Enable activity logging |
|
|
216
|
+
| `logAllTools` | boolean | `false` | Log all tools (not just clawaxis/governance tools) |
|
|
217
|
+
| `logGovernanceIssues` | boolean | `true` | Log validation warnings/errors |
|
|
218
|
+
| `debounceMs` | number | `100` | Batch log flush delay (milliseconds) |
|
|
219
|
+
|
|
220
|
+
#### `governance.memorySearch`
|
|
221
|
+
|
|
222
|
+
| Field | Type | Default | Description |
|
|
223
|
+
|-------|------|---------|-------------|
|
|
224
|
+
| `contentQuery` | string | `"{content_type} style guide writing tone brand voice"` | Memory search query for content tools |
|
|
225
|
+
| `imageQuery` | string | `"image style guide brand visual aesthetic colors"` | Memory search query for image tools |
|
|
226
|
+
| `maxResults` | number | `5` | Max memory chunks to inject |
|
|
227
|
+
| `minScore` | number | `0.65` | Minimum similarity score (0.0-1.0) |
|
|
228
|
+
| `cacheDurationMs` | number | `300000` | Cache duration (5 minutes) |
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Architecture
|
|
233
|
+
|
|
234
|
+
### File Structure
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
clawaxis-plugin/
|
|
238
|
+
openclaw.plugin.json # Plugin manifest (id, configSchema, uiHints)
|
|
239
|
+
package.json # @clawaxis/plugin
|
|
240
|
+
index.ts # Thin entry point (~40 lines)
|
|
241
|
+
CLAWAXIS.md # Agent instruction manual (untouched)
|
|
242
|
+
src/
|
|
243
|
+
types.ts # All TypeScript interfaces
|
|
244
|
+
runtime.ts # Centralized global state (getters/setters)
|
|
245
|
+
config.ts # Config loading, defaults, constants
|
|
246
|
+
utils.ts # relayFetch, relayLog, flushLogQueue, helpers
|
|
247
|
+
channel.ts # Channel definition + outbound methods
|
|
248
|
+
websocket.ts # WebSocket service (api.registerService lifecycle)
|
|
249
|
+
message-handler.ts # Inbound message dispatch + dispatchSystemMessage
|
|
250
|
+
tools/
|
|
251
|
+
index.ts # Barrel - registerTools()
|
|
252
|
+
content.ts # post_content, update_content, get_content
|
|
253
|
+
logging.ts # post_log
|
|
254
|
+
sync.ts # confirm_doc_sync, confirm_routine_sync
|
|
255
|
+
routines.ts # notify_routine, update_routine
|
|
256
|
+
media.ts # upload_media
|
|
257
|
+
memory.ts # memory_search
|
|
258
|
+
governance/
|
|
259
|
+
hooks.ts # registerGovernanceHooks() (before/after_tool_call)
|
|
260
|
+
logging.ts # Layer 1: logToolCall()
|
|
261
|
+
style-injection.ts # Layer 2: searchMemory() + injectStyleDocs()
|
|
262
|
+
validation.ts # Layer 3: validateContent() + enforceGovernance()
|
|
263
|
+
sync/
|
|
264
|
+
documents.ts # processPendingDocs, processDocDeletion, resolveDocPath
|
|
265
|
+
routines.ts # processPendingRoutines
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Key Architectural Decisions
|
|
269
|
+
|
|
270
|
+
- **WebSocket lifecycle** is managed by `api.registerService()` instead of manual signal handlers. OpenClaw handles `start()` and `stop()` calls.
|
|
271
|
+
- **Global state** lives in `src/runtime.ts` behind getter/setter functions. No module imports scattered mutable `let` variables.
|
|
272
|
+
- **Internal API isolation**: The `dispatchReplyWithBufferedBlockDispatcher` call is centralized in `dispatchSystemMessage()` in `src/message-handler.ts`. All sync code (docs, routines) uses this helper.
|
|
273
|
+
- **Config hierarchy**: Primary location is `channels.clawaxis`, fallback to `plugins.entries.clawaxis-plugin.config` for backward compatibility.
|
|
274
|
+
|
|
275
|
+
### WebSocket Protocol
|
|
276
|
+
|
|
277
|
+
**Message Types (Plugin -> Relay):**
|
|
278
|
+
- `auth` - Initial authentication
|
|
279
|
+
- `ping` - Keepalive (30s)
|
|
280
|
+
- `heartbeat` - Status report (60s)
|
|
281
|
+
- `reply` - Agent response
|
|
282
|
+
- `log` - Activity logging (batched)
|
|
283
|
+
- `content` - New/updated content
|
|
284
|
+
- `doc_synced` - Document sync confirmation
|
|
285
|
+
- `routine_synced` - Routine sync confirmation
|
|
286
|
+
|
|
287
|
+
**Message Types (Relay -> Plugin):**
|
|
288
|
+
- `auth_ok` - Authentication success (includes `agent_id`)
|
|
289
|
+
- `auth_error` - Authentication failure
|
|
290
|
+
- `pong` - Keepalive response
|
|
291
|
+
- `heartbeat_ack` - Heartbeat acknowledged + pending sync data
|
|
292
|
+
- `message` - User message to process
|
|
293
|
+
- `command` - System command (future use)
|
|
294
|
+
- `sync` - Pending documents/routines
|
|
295
|
+
- `doc_deleted` - Document deleted by user
|
|
296
|
+
- `content_ack` - Content received/processed
|
|
297
|
+
- `routine_ack` - Routine received/processed
|
|
298
|
+
- `reauth` - Token expiring (re-auth deadline)
|
|
299
|
+
- `error` - Server error
|
|
300
|
+
|
|
301
|
+
### Session Isolation
|
|
302
|
+
|
|
303
|
+
Each authenticated agent gets a unique session key:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
agent:main:clawaxis:{agent_id}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Multiple ClawAxis agents (iOS app, dashboard, future installs) can share one OpenClaw gateway without session file lock contention.
|
|
310
|
+
|
|
311
|
+
### Governance Hook Execution
|
|
312
|
+
|
|
313
|
+
**`before_tool_call` (3 layers):**
|
|
314
|
+
1. **Activity Logging** - Log tool start
|
|
315
|
+
2. **Style Injection** - Search memory for brand docs, inject into tool params
|
|
316
|
+
3. **Content Validation** - Check content against governance rules, auto-fix or block
|
|
317
|
+
|
|
318
|
+
**`after_tool_call` (1 layer):**
|
|
319
|
+
1. **Activity Logging** - Log tool completion (duration, tokens, success/error)
|
|
320
|
+
2. **Flush Logs** - Send batched logs to relay
|
|
321
|
+
|
|
322
|
+
### Document Sync Flow
|
|
323
|
+
|
|
324
|
+
1. **User uploads document in ClawAxis app**
|
|
325
|
+
2. **App stores in Supabase database** (`documents` table)
|
|
326
|
+
3. **Next heartbeat_ack includes `pending_docs`**
|
|
327
|
+
4. **Plugin downloads and writes to workspace:**
|
|
328
|
+
```
|
|
329
|
+
~/.openclaw/workspace/memory/docs/{category}/{slug}.md
|
|
330
|
+
```
|
|
331
|
+
5. **OpenClaw auto-indexes file** (searchable via `memory_search`)
|
|
332
|
+
6. **Plugin notifies agent via system message**
|
|
333
|
+
7. **Agent confirms sync with `clawaxis_confirm_doc_sync`**
|
|
334
|
+
|
|
335
|
+
### Routine Sync Flow
|
|
336
|
+
|
|
337
|
+
1. **User creates routine in ClawAxis app**
|
|
338
|
+
2. **App stores in database** (`routines` table)
|
|
339
|
+
3. **Next heartbeat_ack includes `pending_routines`**
|
|
340
|
+
4. **Plugin dispatches routine request to agent**
|
|
341
|
+
5. **Agent creates OpenClaw cron job**
|
|
342
|
+
6. **Agent calls `clawaxis_notify_routine` with cron ID**
|
|
343
|
+
7. **App links routine to cron job**
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Security Model
|
|
348
|
+
|
|
349
|
+
### Authentication Layers
|
|
350
|
+
|
|
351
|
+
**Layer 1: Supabase Anon Key (Public)**
|
|
352
|
+
- Hardcoded in plugin source
|
|
353
|
+
- Allows connection to Supabase
|
|
354
|
+
- **No data access without additional auth**
|
|
355
|
+
|
|
356
|
+
**Layer 2: Agent Token (Secret)**
|
|
357
|
+
- Unique per user/agent
|
|
358
|
+
- Format: `oc_tk_{64_hex_chars}`
|
|
359
|
+
- Stored in OpenClaw config (encrypted)
|
|
360
|
+
- Sent in `x-agent-token` header + WebSocket auth
|
|
361
|
+
|
|
362
|
+
**Layer 3: Row Level Security (RLS)**
|
|
363
|
+
- Backend validates agent token belongs to user
|
|
364
|
+
- User can only access their own data
|
|
365
|
+
- Zero-trust: even with anon key, RLS blocks unauthorized access
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Development
|
|
370
|
+
|
|
371
|
+
### Testing Locally
|
|
372
|
+
|
|
373
|
+
1. **Edit plugin code** in the `src/` modules
|
|
374
|
+
2. **Restart gateway:**
|
|
375
|
+
```bash
|
|
376
|
+
openclaw gateway stop
|
|
377
|
+
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist
|
|
378
|
+
```
|
|
379
|
+
3. **Watch logs:**
|
|
380
|
+
```bash
|
|
381
|
+
tail -f ~/.openclaw/logs/gateway.log
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Common Issues
|
|
385
|
+
|
|
386
|
+
**Issue:** Plugin not loading
|
|
387
|
+
**Fix:** Check `openclaw gateway status` - plugin must show `ON | OK`
|
|
388
|
+
|
|
389
|
+
**Issue:** WebSocket disconnects every 10s
|
|
390
|
+
**Fix:** Check relay URL is correct (must be `ws-relay`, not `agent-relay`)
|
|
391
|
+
|
|
392
|
+
**Issue:** Agent doesn't see tools
|
|
393
|
+
**Fix:** Restart gateway (SIGUSR1 isn't enough for plugin changes)
|
|
394
|
+
|
|
395
|
+
**Issue:** Document sync doesn't trigger
|
|
396
|
+
**Fix:** Wait for next heartbeat (60s) or force reconnect
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Changelog
|
|
401
|
+
|
|
402
|
+
### v1.0.0 (2026-02-18)
|
|
403
|
+
- Modular architecture: 2066-line monolith split into 20 focused modules
|
|
404
|
+
- Plugin manifest (`openclaw.plugin.json`) with configSchema and uiHints
|
|
405
|
+
- WebSocket lifecycle managed via `api.registerService()`
|
|
406
|
+
- Centralized runtime state with getter/setter pattern
|
|
407
|
+
- `dispatchSystemMessage()` helper isolates internal API usage
|
|
408
|
+
- Config reads from `channels.clawaxis` (primary) with backward compat
|
|
409
|
+
|
|
410
|
+
### v0.1.0 (2026-02-18)
|
|
411
|
+
- Initial production release
|
|
412
|
+
- WebSocket real-time communication
|
|
413
|
+
- 10 tools registered
|
|
414
|
+
- 3-layer governance system
|
|
415
|
+
- Document sync with auto-indexing
|
|
416
|
+
- Routine/cron collaboration
|
|
417
|
+
- Session isolation (multi-agent support)
|
|
418
|
+
- ClawAxis Memory Search (Tool 10)
|
|
419
|
+
- Message status updates
|
|
420
|
+
- Document deletion handling
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Links
|
|
425
|
+
|
|
426
|
+
- **GitHub:** https://github.com/vdiscobot/clawaxis-plugin
|
|
427
|
+
- **Documentation:** [CLAWAXIS.md](./CLAWAXIS.md)
|
|
428
|
+
- **ClawAxis iOS App:** (Coming soon)
|
|
429
|
+
- **OpenClaw:** https://openclaw.ai
|
|
430
|
+
- **OpenClaw Docs:** https://docs.openclaw.ai
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## License
|
|
435
|
+
|
|
436
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
**Built with love by the ClawAxis team**
|
|
441
|
+
**Powered by OpenClaw**
|
package/index.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { LOG_PREFIX, PLUGIN_VERSION, loadConfig } from "./src/config.js";
|
|
2
|
+
import { setRuntime } from "./src/runtime.js";
|
|
3
|
+
import { setUtilsConfig } from "./src/utils.js";
|
|
4
|
+
import { clawaxisChannel } from "./src/channel.js";
|
|
5
|
+
import { registerGovernanceHooks } from "./src/governance/hooks.js";
|
|
6
|
+
import { registerTools } from "./src/tools/index.js";
|
|
7
|
+
|
|
8
|
+
function register(api: any) {
|
|
9
|
+
console.log(`${LOG_PREFIX} ==========================================`);
|
|
10
|
+
console.log(`${LOG_PREFIX} \uD83E\uDD9E ClawAxis Plugin v${PLUGIN_VERSION}`);
|
|
11
|
+
console.log(`${LOG_PREFIX} ==========================================`);
|
|
12
|
+
|
|
13
|
+
setRuntime(api.runtime);
|
|
14
|
+
|
|
15
|
+
const config = loadConfig(api.config);
|
|
16
|
+
if (!config) {
|
|
17
|
+
console.warn(`${LOG_PREFIX} No channels.clawaxis config found (or missing relayUrl/agentToken). Plugin disabled.`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
setUtilsConfig(config);
|
|
22
|
+
|
|
23
|
+
console.log(`${LOG_PREFIX} \u2713 Config loaded`);
|
|
24
|
+
if (config.mediaDomain) console.log(`${LOG_PREFIX} \u2022 Media domain: ${config.mediaDomain}`);
|
|
25
|
+
if (config.agentName) console.log(`${LOG_PREFIX} \u2022 Agent name: ${config.agentName}`);
|
|
26
|
+
|
|
27
|
+
if (typeof api.registerChannel === "function") {
|
|
28
|
+
api.registerChannel({ plugin: clawaxisChannel });
|
|
29
|
+
console.log(`${LOG_PREFIX} \u2713 Channel 'clawaxis' registered (WebSocket starts via gateway.startAccount)`);
|
|
30
|
+
} else {
|
|
31
|
+
console.warn(`${LOG_PREFIX} api.registerChannel not available — channel not registered`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
registerGovernanceHooks(api, config);
|
|
35
|
+
|
|
36
|
+
if (typeof api.registerTool === "function") {
|
|
37
|
+
registerTools(api, config.agentToken);
|
|
38
|
+
console.log(`${LOG_PREFIX} \u2705 All 10 tools registered successfully`);
|
|
39
|
+
} else {
|
|
40
|
+
console.warn(`${LOG_PREFIX} api.registerTool not available — tools not registered`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log(`${LOG_PREFIX} ==========================================`);
|
|
44
|
+
console.log(`${LOG_PREFIX} \u2713 ClawAxis plugin loaded`);
|
|
45
|
+
console.log(`${LOG_PREFIX} ==========================================`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
id: "clawaxis",
|
|
50
|
+
name: "ClawAxis",
|
|
51
|
+
version: PLUGIN_VERSION,
|
|
52
|
+
register,
|
|
53
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "clawaxis",
|
|
3
|
+
"name": "ClawAxis",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Real-time bridge between OpenClaw agents and the ClawAxis iOS app. Channel plugin with governance, content management, and document/routine sync.",
|
|
6
|
+
"channels": ["clawaxis"],
|
|
7
|
+
"configSchema": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"additionalProperties": false,
|
|
10
|
+
"properties": {
|
|
11
|
+
"relayUrl": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "ClawAxis WebSocket relay endpoint URL"
|
|
14
|
+
},
|
|
15
|
+
"agentToken": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Agent authentication token (oc_tk_...)"
|
|
18
|
+
},
|
|
19
|
+
"mediaDomain": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "R2/S3 bucket domain for permanent image storage"
|
|
22
|
+
},
|
|
23
|
+
"agentName": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Agent name for author attribution validation"
|
|
26
|
+
},
|
|
27
|
+
"governance": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"additionalProperties": false,
|
|
30
|
+
"properties": {
|
|
31
|
+
"imageTools": {
|
|
32
|
+
"type": "array",
|
|
33
|
+
"items": { "type": "string" },
|
|
34
|
+
"description": "Tool name patterns to detect image generation tools"
|
|
35
|
+
},
|
|
36
|
+
"contentTools": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": { "type": "string" }
|
|
39
|
+
},
|
|
40
|
+
"publishingTools": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"items": { "type": "string" }
|
|
43
|
+
},
|
|
44
|
+
"memorySearch": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"properties": {
|
|
47
|
+
"contentQuery": { "type": "string" },
|
|
48
|
+
"imageQuery": { "type": "string" },
|
|
49
|
+
"maxResults": { "type": "number" },
|
|
50
|
+
"minScore": { "type": "number" },
|
|
51
|
+
"cacheDurationMs": { "type": "number" }
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"validation": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"properties": {
|
|
57
|
+
"requireCTA": { "type": "boolean" },
|
|
58
|
+
"requirePermanentImages": { "type": "boolean" },
|
|
59
|
+
"requireValidAuthor": { "type": "boolean" },
|
|
60
|
+
"allowedContentTypes": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"items": { "type": "string" }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"logging": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"properties": {
|
|
69
|
+
"enabled": { "type": "boolean" },
|
|
70
|
+
"logAllTools": { "type": "boolean" },
|
|
71
|
+
"logGovernanceIssues": { "type": "boolean" },
|
|
72
|
+
"debounceMs": { "type": "number" }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"required": ["relayUrl", "agentToken"]
|
|
79
|
+
},
|
|
80
|
+
"uiHints": {
|
|
81
|
+
"relayUrl": { "label": "Relay URL", "placeholder": "https://your-relay.supabase.co/functions/v1/ws-relay" },
|
|
82
|
+
"agentToken": { "label": "Agent Token", "sensitive": true, "placeholder": "oc_tk_..." },
|
|
83
|
+
"mediaDomain": { "label": "Media Domain", "placeholder": "pub-xxxxx.r2.dev" },
|
|
84
|
+
"agentName": { "label": "Agent Name" }
|
|
85
|
+
}
|
|
86
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clawaxis",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"index.ts",
|
|
8
|
+
"src/",
|
|
9
|
+
"openclaw.plugin.json",
|
|
10
|
+
"CLAWAXIS.md"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"openclaw",
|
|
14
|
+
"openclaw-plugin",
|
|
15
|
+
"clawaxis",
|
|
16
|
+
"websocket",
|
|
17
|
+
"mobile",
|
|
18
|
+
"channel"
|
|
19
|
+
],
|
|
20
|
+
"openclaw": {
|
|
21
|
+
"extensions": ["./index.ts"],
|
|
22
|
+
"channel": {
|
|
23
|
+
"id": "clawaxis",
|
|
24
|
+
"label": "ClawAxis",
|
|
25
|
+
"selectionLabel": "ClawAxis (Mobile)",
|
|
26
|
+
"blurb": "Control your OpenClaw agent from your phone."
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@sinclair/typebox": "^0.34.48",
|
|
31
|
+
"ws": "^8.19.0"
|
|
32
|
+
}
|
|
33
|
+
}
|