@troykelly/openclaw-projects 0.0.1 → 0.0.3
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 +200 -254
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +48 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/register-openclaw.d.ts +7 -0
- package/dist/register-openclaw.d.ts.map +1 -1
- package/dist/register-openclaw.js +412 -4
- package/dist/register-openclaw.js.map +1 -1
- package/dist/secrets.d.ts +12 -0
- package/dist/secrets.d.ts.map +1 -1
- package/dist/secrets.js +37 -0
- package/dist/secrets.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/skill-store.d.ts +277 -0
- package/dist/tools/skill-store.d.ts.map +1 -0
- package/dist/tools/skill-store.js +860 -0
- package/dist/tools/skill-store.js.map +1 -0
- package/openclaw.plugin.json +1 -3
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -1,376 +1,321 @@
|
|
|
1
1
|
# @troykelly/openclaw-projects
|
|
2
2
|
|
|
3
|
-
An [OpenClaw](https://docs.openclaw.ai/) plugin that connects agents to the openclaw-projects backend for project management, memory, todos, and
|
|
3
|
+
An [OpenClaw](https://docs.openclaw.ai/) plugin that connects agents to the openclaw-projects backend for project management, memory, todos, contacts, and communications.
|
|
4
4
|
|
|
5
5
|
> **Note:** This is a third-party plugin — not part of OpenClaw itself. It provides OpenClaw agents with tools to interact with the [openclaw-projects](https://github.com/troykelly/openclaw-projects) backend service.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **Memory Management**: Store, recall, and forget memories with semantic search
|
|
9
|
+
- **Memory Management**: Store, recall, and forget memories with semantic search (pgvector)
|
|
10
10
|
- **Project Management**: List, get, and create projects
|
|
11
11
|
- **Todo Management**: Manage todos with completion tracking
|
|
12
|
-
- **Contact Management**: Search, get, and create contacts
|
|
12
|
+
- **Contact Management**: Search, get, and create contacts with relationship mapping
|
|
13
|
+
- **Communications**: Send SMS (Twilio) and email (Postmark) directly from agents
|
|
14
|
+
- **Message History**: Search and browse message threads across channels
|
|
15
|
+
- **Skill Store**: Persist and query structured data for agent skills
|
|
13
16
|
- **Auto-Recall**: Automatically inject relevant context into conversations
|
|
14
17
|
- **Auto-Capture**: Capture important information from completed conversations
|
|
15
|
-
- **
|
|
16
|
-
- **Multi-User Support**: Flexible user scoping (agent, session, identity)
|
|
18
|
+
- **Bundled Skills**: 4 ready-to-use skills for common workflows
|
|
17
19
|
|
|
18
20
|
## Installation
|
|
19
21
|
|
|
22
|
+
### Via OpenClaw CLI (recommended)
|
|
23
|
+
|
|
20
24
|
```bash
|
|
21
|
-
|
|
25
|
+
openclaw plugins install @troykelly/openclaw-projects
|
|
22
26
|
```
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
Then configure the plugin in your OpenClaw config file (`~/.openclaw/config.yaml` or equivalent):
|
|
25
29
|
|
|
26
|
-
```
|
|
27
|
-
|
|
30
|
+
```yaml
|
|
31
|
+
plugins:
|
|
32
|
+
entries:
|
|
33
|
+
openclaw-projects:
|
|
34
|
+
enabled: true
|
|
35
|
+
config:
|
|
36
|
+
apiUrl: https://your-backend.example.com
|
|
37
|
+
apiKey: your-api-key
|
|
38
|
+
```
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
config: {
|
|
31
|
-
apiUrl: 'https://your-backend.example.com',
|
|
32
|
-
apiKey: process.env.OPENCLAW_API_KEY,
|
|
33
|
-
},
|
|
34
|
-
})
|
|
40
|
+
### Via npm (for programmatic use)
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
query: 'user preferences',
|
|
39
|
-
})
|
|
42
|
+
```bash
|
|
43
|
+
pnpm add @troykelly/openclaw-projects
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
This method is for integrating the plugin programmatically outside of the OpenClaw runtime. Most users should use the OpenClaw CLI method above.
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|--------|------|---------|-------------|
|
|
46
|
-
| `apiUrl` | string | **required** | Backend API URL |
|
|
47
|
-
| `apiKey` | string | **required** | API authentication key |
|
|
48
|
-
| `autoRecall` | boolean | `true` | Enable auto-recall hook |
|
|
49
|
-
| `autoCapture` | boolean | `true` | Enable auto-capture hook |
|
|
50
|
-
| `userScoping` | string | `'agent'` | User scoping mode |
|
|
51
|
-
| `maxRecallMemories` | number | `5` | Max memories to return |
|
|
52
|
-
| `minRecallScore` | number | `0.7` | Minimum similarity score |
|
|
53
|
-
| `timeout` | number | `30000` | API timeout (ms) |
|
|
54
|
-
| `maxRetries` | number | `3` | Max retry attempts |
|
|
55
|
-
| `debug` | boolean | `false` | Enable debug logging |
|
|
48
|
+
## Verification
|
|
56
49
|
|
|
57
|
-
|
|
50
|
+
After installation, verify the plugin is loaded:
|
|
58
51
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
| `session` | Scope by session key | Maximum isolation |
|
|
63
|
-
| `identity` | Scope by canonical identity | Shared identity across agents |
|
|
52
|
+
```bash
|
|
53
|
+
openclaw plugins info openclaw-projects
|
|
54
|
+
```
|
|
64
55
|
|
|
65
|
-
|
|
56
|
+
Check that the plugin is healthy and can reach the backend:
|
|
66
57
|
|
|
67
58
|
```bash
|
|
68
|
-
|
|
69
|
-
OPENCLAW_API_KEY=your-api-key
|
|
59
|
+
openclaw plugins doctor
|
|
70
60
|
```
|
|
71
61
|
|
|
72
|
-
##
|
|
73
|
-
|
|
74
|
-
### Memory Tools
|
|
62
|
+
## Configuration
|
|
75
63
|
|
|
76
|
-
|
|
77
|
-
Search memories semantically.
|
|
64
|
+
Configure the plugin in your OpenClaw config file or pass config programmatically.
|
|
78
65
|
|
|
79
|
-
|
|
80
|
-
const result = await plugin.tools.memoryRecall.execute({
|
|
81
|
-
query: 'user preferences for notifications',
|
|
82
|
-
limit: 10, // optional, default: 5
|
|
83
|
-
category: 'preference', // optional filter
|
|
84
|
-
})
|
|
85
|
-
```
|
|
66
|
+
### Required Settings
|
|
86
67
|
|
|
87
|
-
|
|
88
|
-
|
|
68
|
+
| Option | Type | Description |
|
|
69
|
+
|--------|------|-------------|
|
|
70
|
+
| `apiUrl` | string | Backend API URL (must be HTTPS in production) |
|
|
71
|
+
| `apiKey` | string | API authentication key (direct value) |
|
|
89
72
|
|
|
90
|
-
|
|
91
|
-
const result = await plugin.tools.memoryStore.execute({
|
|
92
|
-
text: 'User prefers dark mode',
|
|
93
|
-
category: 'preference', // preference, fact, decision, context, other
|
|
94
|
-
importance: 0.8, // optional, 0-1
|
|
95
|
-
})
|
|
96
|
-
```
|
|
73
|
+
You must provide the API key via one of three methods:
|
|
97
74
|
|
|
98
|
-
|
|
99
|
-
|
|
75
|
+
| Method | Config Key | Description |
|
|
76
|
+
|--------|-----------|-------------|
|
|
77
|
+
| Direct value | `apiKey` | Plaintext key (for development only) |
|
|
78
|
+
| File reference | `apiKeyFile` | Path to file containing key (e.g., `~/.secrets/api_key`) |
|
|
79
|
+
| Command | `apiKeyCommand` | Shell command to retrieve key (e.g., `op read op://Personal/openclaw/api_key`) |
|
|
100
80
|
|
|
101
|
-
|
|
102
|
-
// By ID
|
|
103
|
-
const result = await plugin.tools.memoryForget.execute({
|
|
104
|
-
memoryId: '123e4567-e89b-12d3-a456-426614174000',
|
|
105
|
-
})
|
|
81
|
+
### Optional Settings
|
|
106
82
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
83
|
+
| Option | Type | Default | Description |
|
|
84
|
+
|--------|------|---------|-------------|
|
|
85
|
+
| `autoRecall` | boolean | `true` | Inject relevant memories at conversation start |
|
|
86
|
+
| `autoCapture` | boolean | `true` | Capture important info from completed conversations |
|
|
87
|
+
| `userScoping` | string | `'agent'` | User scoping mode (`agent`, `session`, `identity`) |
|
|
88
|
+
| `maxRecallMemories` | number | `5` | Max memories to inject in auto-recall |
|
|
89
|
+
| `minRecallScore` | number | `0.7` | Minimum similarity score for auto-recall (0-1) |
|
|
90
|
+
| `timeout` | number | `30000` | API request timeout (ms) |
|
|
91
|
+
| `maxRetries` | number | `3` | Max retry attempts for failed requests |
|
|
92
|
+
| `debug` | boolean | `false` | Enable debug logging (never logs secrets) |
|
|
93
|
+
|
|
94
|
+
### Secret Management
|
|
95
|
+
|
|
96
|
+
All secret fields (API key, Twilio credentials, Postmark token) support three resolution methods. The plugin resolves secrets in priority order: command > file > direct value.
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
plugins:
|
|
100
|
+
entries:
|
|
101
|
+
openclaw-projects:
|
|
102
|
+
enabled: true
|
|
103
|
+
config:
|
|
104
|
+
apiUrl: https://your-backend.example.com
|
|
105
|
+
# Option 1: Direct value (development only)
|
|
106
|
+
apiKey: sk-dev-key-here
|
|
107
|
+
# Option 2: File reference
|
|
108
|
+
# apiKeyFile: ~/.secrets/openclaw-api-key
|
|
109
|
+
# Option 3: Command (e.g., 1Password CLI)
|
|
110
|
+
# apiKeyCommand: op read op://Personal/openclaw/api_key
|
|
112
111
|
```
|
|
113
112
|
|
|
114
|
-
###
|
|
113
|
+
### Twilio SMS (optional)
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
List projects with optional filtering.
|
|
115
|
+
To enable SMS sending, add Twilio credentials using the same direct/file/command pattern:
|
|
118
116
|
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
})
|
|
117
|
+
```yaml
|
|
118
|
+
twilioAccountSid: AC...
|
|
119
|
+
twilioAuthToken: your-auth-token
|
|
120
|
+
twilioPhoneNumber: "+15551234567"
|
|
124
121
|
```
|
|
125
122
|
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
### Postmark Email (optional)
|
|
124
|
+
|
|
125
|
+
To enable email sending, add Postmark credentials:
|
|
128
126
|
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
})
|
|
127
|
+
```yaml
|
|
128
|
+
postmarkToken: your-postmark-token
|
|
129
|
+
postmarkFromEmail: noreply@example.com
|
|
133
130
|
```
|
|
134
131
|
|
|
135
|
-
|
|
136
|
-
Create a new project.
|
|
132
|
+
### User Scoping Modes
|
|
137
133
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
})
|
|
144
|
-
```
|
|
134
|
+
| Mode | Description | Use Case |
|
|
135
|
+
|------|-------------|----------|
|
|
136
|
+
| `agent` | Scope by agent ID | Single user per agent (default) |
|
|
137
|
+
| `session` | Scope by session key | Maximum isolation between sessions |
|
|
138
|
+
| `identity` | Scope by canonical identity | Shared identity across agents |
|
|
145
139
|
|
|
146
|
-
|
|
140
|
+
## Tools
|
|
147
141
|
|
|
148
|
-
|
|
149
|
-
List todos with optional filtering.
|
|
142
|
+
The plugin registers 27 tools that agents can use. Tools are automatically available to any agent with the plugin enabled.
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
const result = await plugin.tools.todoList.execute({
|
|
153
|
-
projectId: '123e4567-e89b-12d3-a456-426614174000', // optional
|
|
154
|
-
completed: false, // optional
|
|
155
|
-
limit: 50, // optional
|
|
156
|
-
})
|
|
157
|
-
```
|
|
144
|
+
### Memory Tools
|
|
158
145
|
|
|
159
|
-
|
|
160
|
-
|
|
146
|
+
| Tool | Description |
|
|
147
|
+
|------|-------------|
|
|
148
|
+
| `memory_recall` | Search memories semantically by query |
|
|
149
|
+
| `memory_store` | Store a new memory (preference, fact, decision, context) |
|
|
150
|
+
| `memory_forget` | Delete memories by ID or search query |
|
|
161
151
|
|
|
162
|
-
|
|
163
|
-
const result = await plugin.tools.todoCreate.execute({
|
|
164
|
-
title: 'Buy groceries',
|
|
165
|
-
projectId: '123e4567-e89b-12d3-a456-426614174000', // optional
|
|
166
|
-
dueDate: '2024-01-15', // optional, ISO 8601
|
|
167
|
-
})
|
|
168
|
-
```
|
|
152
|
+
### Project Tools
|
|
169
153
|
|
|
170
|
-
|
|
171
|
-
|
|
154
|
+
| Tool | Description |
|
|
155
|
+
|------|-------------|
|
|
156
|
+
| `project_list` | List projects with optional status filter |
|
|
157
|
+
| `project_get` | Get full details of a specific project |
|
|
158
|
+
| `project_create` | Create a new project |
|
|
172
159
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
160
|
+
### Todo Tools
|
|
161
|
+
|
|
162
|
+
| Tool | Description |
|
|
163
|
+
|------|-------------|
|
|
164
|
+
| `todo_list` | List todos, optionally filtered by project or status |
|
|
165
|
+
| `todo_create` | Create a new todo item |
|
|
166
|
+
| `todo_complete` | Mark a todo as complete |
|
|
178
167
|
|
|
179
168
|
### Contact Tools
|
|
180
169
|
|
|
181
|
-
|
|
182
|
-
|
|
170
|
+
| Tool | Description |
|
|
171
|
+
|------|-------------|
|
|
172
|
+
| `contact_search` | Search contacts by name, email, or other fields |
|
|
173
|
+
| `contact_get` | Get full details of a specific contact |
|
|
174
|
+
| `contact_create` | Create a new contact |
|
|
183
175
|
|
|
184
|
-
|
|
185
|
-
const result = await plugin.tools.contactSearch.execute({
|
|
186
|
-
query: 'Alice',
|
|
187
|
-
limit: 10, // optional
|
|
188
|
-
})
|
|
189
|
-
```
|
|
176
|
+
### Communication Tools
|
|
190
177
|
|
|
191
|
-
|
|
192
|
-
|
|
178
|
+
| Tool | Description |
|
|
179
|
+
|------|-------------|
|
|
180
|
+
| `sms_send` | Send an SMS message (requires Twilio config) |
|
|
181
|
+
| `email_send` | Send an email message (requires Postmark config) |
|
|
182
|
+
| `message_search` | Search message history semantically |
|
|
183
|
+
| `thread_list` | List message threads (conversations) |
|
|
184
|
+
| `thread_get` | Get a thread with full message history |
|
|
193
185
|
|
|
194
|
-
|
|
195
|
-
const result = await plugin.tools.contactGet.execute({
|
|
196
|
-
id: '123e4567-e89b-12d3-a456-426614174000',
|
|
197
|
-
})
|
|
198
|
-
```
|
|
186
|
+
### Relationship Tools
|
|
199
187
|
|
|
200
|
-
|
|
201
|
-
|
|
188
|
+
| Tool | Description |
|
|
189
|
+
|------|-------------|
|
|
190
|
+
| `relationship_set` | Record a relationship between contacts |
|
|
191
|
+
| `relationship_query` | Query a contact's relationships |
|
|
202
192
|
|
|
203
|
-
|
|
204
|
-
const result = await plugin.tools.contactCreate.execute({
|
|
205
|
-
name: 'Alice Smith',
|
|
206
|
-
email: 'alice@example.com', // optional
|
|
207
|
-
phone: '+1-555-123-4567', // optional
|
|
208
|
-
})
|
|
209
|
-
```
|
|
193
|
+
### Skill Store Tools
|
|
210
194
|
|
|
211
|
-
|
|
195
|
+
| Tool | Description |
|
|
196
|
+
|------|-------------|
|
|
197
|
+
| `skill_store_put` | Store or update data in the skill store |
|
|
198
|
+
| `skill_store_get` | Retrieve an item by ID or composite key |
|
|
199
|
+
| `skill_store_list` | List items with filtering and pagination |
|
|
200
|
+
| `skill_store_delete` | Delete an item (soft delete) |
|
|
201
|
+
| `skill_store_search` | Search items by text or semantic similarity |
|
|
202
|
+
| `skill_store_collections` | List all collections with item counts |
|
|
203
|
+
| `skill_store_aggregate` | Run aggregations on skill store items |
|
|
212
204
|
|
|
213
|
-
###
|
|
205
|
+
### Other Tools
|
|
214
206
|
|
|
215
|
-
|
|
207
|
+
| Tool | Description |
|
|
208
|
+
|------|-------------|
|
|
209
|
+
| `file_share` | Generate a time-limited shareable download link |
|
|
216
210
|
|
|
217
|
-
|
|
218
|
-
const context = await plugin.hooks.beforeAgentStart({
|
|
219
|
-
prompt: 'What are my notification preferences?',
|
|
220
|
-
})
|
|
211
|
+
## Skills
|
|
221
212
|
|
|
222
|
-
|
|
223
|
-
// Prepend context.prependContext to the conversation
|
|
224
|
-
}
|
|
225
|
-
```
|
|
213
|
+
The plugin includes 4 bundled skills that agents can invoke as high-level workflows. Skills combine multiple tools to accomplish common tasks.
|
|
226
214
|
|
|
227
|
-
### `
|
|
215
|
+
### `contact-lookup`
|
|
228
216
|
|
|
229
|
-
|
|
217
|
+
Look up contact information and recent communications.
|
|
230
218
|
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
messages: [
|
|
234
|
-
{ role: 'user', content: 'Remember I prefer email notifications' },
|
|
235
|
-
{ role: 'assistant', content: 'Noted! I will remember your preference.' },
|
|
236
|
-
],
|
|
237
|
-
})
|
|
219
|
+
```
|
|
220
|
+
/contact-lookup name="Alice Smith"
|
|
238
221
|
```
|
|
239
222
|
|
|
240
|
-
|
|
223
|
+
Searches contacts, retrieves details, shows recent messages, related projects/tasks, and stored memories about the person.
|
|
241
224
|
|
|
242
|
-
|
|
225
|
+
### `daily-summary`
|
|
243
226
|
|
|
244
|
-
|
|
245
|
-
Check API connectivity.
|
|
227
|
+
Get a summary of today's tasks, messages, and activities.
|
|
246
228
|
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
// { success: true, message: 'API is healthy (latency: 50ms)', data: { ... } }
|
|
229
|
+
```
|
|
230
|
+
/daily-summary
|
|
250
231
|
```
|
|
251
232
|
|
|
252
|
-
|
|
253
|
-
Show user scoping configuration.
|
|
233
|
+
Shows tasks due today, recent messages, upcoming deadlines, and items requiring attention.
|
|
254
234
|
|
|
255
|
-
|
|
256
|
-
const result = await plugin.cli.users()
|
|
257
|
-
// { success: true, data: { scopingMode: 'agent', description: '...', currentUserId: '...' } }
|
|
258
|
-
```
|
|
235
|
+
### `project-status`
|
|
259
236
|
|
|
260
|
-
|
|
261
|
-
Search memories from CLI.
|
|
237
|
+
Get a status overview of a specific project.
|
|
262
238
|
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
// { success: true, data: { memories: [...], query: '...', limit: 10 } }
|
|
239
|
+
```
|
|
240
|
+
/project-status project="Home Renovation"
|
|
266
241
|
```
|
|
267
242
|
|
|
268
|
-
|
|
269
|
-
Show memory statistics.
|
|
243
|
+
Shows project overview, task breakdown with completion percentage, recent activity, blockers, and recommended next steps.
|
|
270
244
|
|
|
271
|
-
|
|
272
|
-
const result = await plugin.cli.stats()
|
|
273
|
-
// { success: true, data: { totalMemories: 42, byCategory: { ... } } }
|
|
274
|
-
```
|
|
245
|
+
### `send-reminder`
|
|
275
246
|
|
|
276
|
-
|
|
277
|
-
Export all memories (GDPR data portability).
|
|
247
|
+
Send a reminder message to a contact via SMS or email.
|
|
278
248
|
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
// { success: true, data: { memories: [...], exportedAt: '...', userId: '...' } }
|
|
249
|
+
```
|
|
250
|
+
/send-reminder contact="Alice" message="Don't forget the meeting tomorrow" channel="sms"
|
|
282
251
|
```
|
|
283
252
|
|
|
284
|
-
|
|
253
|
+
Looks up the contact, verifies their endpoint, sends the message, and confirms delivery.
|
|
285
254
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
255
|
+
## Lifecycle Hooks
|
|
256
|
+
|
|
257
|
+
### `before_agent_start` (Auto-Recall)
|
|
258
|
+
|
|
259
|
+
When `autoRecall` is enabled (default), the plugin automatically searches for relevant memories before each conversation. It uses the user's prompt for semantic search and injects matching memories as context via `prependContext`.
|
|
260
|
+
|
|
261
|
+
### `agent_end` (Auto-Capture)
|
|
262
|
+
|
|
263
|
+
When `autoCapture` is enabled (default), the plugin automatically analyzes completed conversations and stores important information (preferences, facts, decisions) as memories for future recall.
|
|
292
264
|
|
|
293
265
|
## Security
|
|
294
266
|
|
|
295
|
-
###
|
|
267
|
+
### Secret Management
|
|
296
268
|
|
|
297
|
-
-
|
|
298
|
-
-
|
|
299
|
-
-
|
|
269
|
+
- Use file references or command execution for secrets in production
|
|
270
|
+
- Direct values are for development only
|
|
271
|
+
- The plugin supports 1Password CLI, Vault, AWS Secrets Manager, or any command-line tool
|
|
272
|
+
- Secret files are checked for world-readable permissions (warns if `chmod 644`)
|
|
300
273
|
|
|
301
274
|
### Data Isolation
|
|
302
275
|
|
|
303
276
|
- All data is scoped to the configured user scope
|
|
304
277
|
- Cross-user access is prevented at the API level
|
|
305
|
-
|
|
278
|
+
|
|
279
|
+
### HTTPS
|
|
280
|
+
|
|
281
|
+
- HTTPS is required in production (`NODE_ENV=production`)
|
|
282
|
+
- HTTP is permitted for local development only
|
|
306
283
|
|
|
307
284
|
### Sensitive Content
|
|
308
285
|
|
|
309
|
-
-
|
|
310
|
-
- PII is not logged at info level
|
|
286
|
+
- Secrets are never logged (config is redacted in logs)
|
|
311
287
|
- Error messages are sanitized to prevent information leakage
|
|
312
288
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
- Use HTTPS in production
|
|
316
|
-
- HTTP is only recommended for local development
|
|
289
|
+
## Troubleshooting
|
|
317
290
|
|
|
318
|
-
|
|
291
|
+
### Plugin not loading
|
|
319
292
|
|
|
320
|
-
|
|
293
|
+
Verify the plugin is installed and the manifest is detected:
|
|
321
294
|
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
success: boolean
|
|
325
|
-
content?: string // Human-readable response
|
|
326
|
-
data?: unknown // Structured data
|
|
327
|
-
error?: string // Error message if success is false
|
|
328
|
-
}
|
|
295
|
+
```bash
|
|
296
|
+
openclaw plugins info openclaw-projects
|
|
329
297
|
```
|
|
330
298
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
### Connection Issues
|
|
299
|
+
### Connection issues
|
|
334
300
|
|
|
335
|
-
|
|
336
|
-
// Check health
|
|
337
|
-
const health = await plugin.healthCheck()
|
|
338
|
-
console.log('Healthy:', health.healthy, 'Error:', health.error)
|
|
301
|
+
Check that the backend API is reachable:
|
|
339
302
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
console.log('Status:', status.message, 'Latency:', status.data?.latencyMs)
|
|
303
|
+
```bash
|
|
304
|
+
openclaw plugins doctor
|
|
343
305
|
```
|
|
344
306
|
|
|
345
|
-
### No
|
|
307
|
+
### No memories found
|
|
346
308
|
|
|
347
309
|
- Verify the user scoping mode matches your setup
|
|
348
310
|
- Check that memories were stored for the same user scope
|
|
349
311
|
- Try broadening your search query
|
|
350
312
|
|
|
351
|
-
### API
|
|
313
|
+
### API errors
|
|
352
314
|
|
|
353
|
-
- Verify
|
|
354
|
-
- Check API key is valid
|
|
315
|
+
- Verify `apiUrl` is correct and accessible
|
|
316
|
+
- Check that the API key is valid
|
|
355
317
|
- Review network connectivity
|
|
356
318
|
|
|
357
|
-
## API Reference
|
|
358
|
-
|
|
359
|
-
Full TypeScript types are exported:
|
|
360
|
-
|
|
361
|
-
```typescript
|
|
362
|
-
import type {
|
|
363
|
-
PluginConfig,
|
|
364
|
-
PluginInstance,
|
|
365
|
-
MemoryRecallParams,
|
|
366
|
-
MemoryStoreParams,
|
|
367
|
-
ProjectListParams,
|
|
368
|
-
TodoCreateParams,
|
|
369
|
-
ContactSearchParams,
|
|
370
|
-
// ... and more
|
|
371
|
-
} from '@troykelly/openclaw-projects'
|
|
372
|
-
```
|
|
373
|
-
|
|
374
319
|
## Contributing
|
|
375
320
|
|
|
376
321
|
1. Fork the repository
|
|
@@ -385,5 +330,6 @@ MIT
|
|
|
385
330
|
## Links
|
|
386
331
|
|
|
387
332
|
- [OpenClaw Documentation](https://docs.openclaw.ai/)
|
|
333
|
+
- [OpenClaw Plugin Guide](https://docs.openclaw.ai/plugins)
|
|
388
334
|
- [openclaw-projects Backend](https://github.com/troykelly/openclaw-projects)
|
|
389
335
|
- [Report Issues](https://github.com/troykelly/openclaw-projects/issues)
|
package/dist/config.d.ts
CHANGED
|
@@ -321,4 +321,16 @@ export declare function redactConfig(config: PluginConfig): PluginConfig;
|
|
|
321
321
|
* @throws If required secrets cannot be resolved
|
|
322
322
|
*/
|
|
323
323
|
export declare function resolveConfigSecrets(rawConfig: RawPluginConfig): Promise<PluginConfig>;
|
|
324
|
+
/**
|
|
325
|
+
* Resolves all secrets synchronously to produce a resolved config.
|
|
326
|
+
*
|
|
327
|
+
* Used during plugin registration where blocking I/O is acceptable.
|
|
328
|
+
* OpenClaw's loader does not await the register function, so all
|
|
329
|
+
* config resolution must complete synchronously.
|
|
330
|
+
*
|
|
331
|
+
* @param rawConfig - The raw plugin configuration with secret references
|
|
332
|
+
* @returns The resolved plugin configuration with actual secret values
|
|
333
|
+
* @throws If required secrets cannot be resolved
|
|
334
|
+
*/
|
|
335
|
+
export declare function resolveConfigSecretsSync(rawConfig: RawPluginConfig): PluginConfig;
|
|
324
336
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,6CAA2C,CAAA;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAS3D;;;GAGG;AACH,eAAO,MAAM,qBAAqB;IAE9B,oDAAoD;;IAUpD,4CAA4C;;IAE5C,sCAAsC;;IAEtC,wCAAwC;;IAIxC,wCAAwC;;IAExC,iDAAiD;;IAEjD,wCAAwC;;IAIxC,uCAAuC;;IAEvC,gDAAgD;;IAEhD,uCAAuC;;IAIvC,yCAAyC;;IAEzC,kDAAkD;;IAElD,yCAAyC;;IAIzC,wCAAwC;;IAExC,6CAA6C;;IAE7C,oCAAoC;;IAIpC,iDAAiD;;IAEjD,kDAAkD;;IAElD,yCAAyC;;IAGzC,2DAA2D;;IAS3D,mEAAmE;;IAGnE,8DAA8D;;IAG9D,iCAAiC;;IAGjC,gDAAgD;;IAShD,oDAAoD;;IAQpD,sCAAsC;;IAStC,0CAA0C;;IAS1C,gDAAgD;;IAGhD,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASrE,CAAA;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;GAGG;AACH,eAAO,MAAM,kBAAkB;IAC7B,sBAAsB;;IAGtB,sCAAsC;;IAGtC,kCAAkC;;IAGlC,iCAAiC;;IAGjC,mCAAmC;;IAGnC,8BAA8B;;IAG9B,mCAAmC;;IAGnC,6BAA6B;;IAG7B,2BAA2B;;IAG3B,4BAA4B;;IAG5B,4BAA4B;;IAG5B,iCAAiC;;IAGjC,8BAA8B;;IAG9B,4BAA4B;;IAG5B,sBAAsB;;IAGtB,2BAA2B;;IAG3B,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE3B,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAE7D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe,CAElE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,GACd;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;CAAE,CAMrF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAE5D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,GACd;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;CAAE,CAErF;AAWD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAS/D;AAsBD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CA6C5F"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,6CAA2C,CAAA;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAS3D;;;GAGG;AACH,eAAO,MAAM,qBAAqB;IAE9B,oDAAoD;;IAUpD,4CAA4C;;IAE5C,sCAAsC;;IAEtC,wCAAwC;;IAIxC,wCAAwC;;IAExC,iDAAiD;;IAEjD,wCAAwC;;IAIxC,uCAAuC;;IAEvC,gDAAgD;;IAEhD,uCAAuC;;IAIvC,yCAAyC;;IAEzC,kDAAkD;;IAElD,yCAAyC;;IAIzC,wCAAwC;;IAExC,6CAA6C;;IAE7C,oCAAoC;;IAIpC,iDAAiD;;IAEjD,kDAAkD;;IAElD,yCAAyC;;IAGzC,2DAA2D;;IAS3D,mEAAmE;;IAGnE,8DAA8D;;IAG9D,iCAAiC;;IAGjC,gDAAgD;;IAShD,oDAAoD;;IAQpD,sCAAsC;;IAStC,0CAA0C;;IAS1C,gDAAgD;;IAGhD,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASrE,CAAA;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;GAGG;AACH,eAAO,MAAM,kBAAkB;IAC7B,sBAAsB;;IAGtB,sCAAsC;;IAGtC,kCAAkC;;IAGlC,iCAAiC;;IAGjC,mCAAmC;;IAGnC,8BAA8B;;IAG9B,mCAAmC;;IAGnC,6BAA6B;;IAG7B,2BAA2B;;IAG3B,4BAA4B;;IAG5B,4BAA4B;;IAG5B,iCAAiC;;IAGjC,8BAA8B;;IAG9B,4BAA4B;;IAG5B,sBAAsB;;IAGtB,2BAA2B;;IAG3B,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE3B,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAE7D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe,CAElE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,GACd;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;CAAE,CAMrF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAE5D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,GACd;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;CAAE,CAErF;AAWD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAS/D;AAsBD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CA6C5F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,eAAe,GAAG,YAAY,CAyDjF"}
|
package/dist/config.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 3. Command reference (e.g., apiKeyCommand: "op read op://...")
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import { resolveSecret } from './secrets.js';
|
|
11
|
+
import { resolveSecret, resolveSecretSync } from './secrets.js';
|
|
12
12
|
/** User scoping strategies for memory isolation */
|
|
13
13
|
export const UserScopingSchema = z.enum(['agent', 'identity', 'session']);
|
|
14
14
|
/**
|
|
@@ -284,4 +284,51 @@ export async function resolveConfigSecrets(rawConfig) {
|
|
|
284
284
|
// Validate the resolved config
|
|
285
285
|
return validateConfig(resolvedConfig);
|
|
286
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Resolves all secrets synchronously to produce a resolved config.
|
|
289
|
+
*
|
|
290
|
+
* Used during plugin registration where blocking I/O is acceptable.
|
|
291
|
+
* OpenClaw's loader does not await the register function, so all
|
|
292
|
+
* config resolution must complete synchronously.
|
|
293
|
+
*
|
|
294
|
+
* @param rawConfig - The raw plugin configuration with secret references
|
|
295
|
+
* @returns The resolved plugin configuration with actual secret values
|
|
296
|
+
* @throws If required secrets cannot be resolved
|
|
297
|
+
*/
|
|
298
|
+
export function resolveConfigSecretsSync(rawConfig) {
|
|
299
|
+
const timeout = rawConfig.secretCommandTimeout;
|
|
300
|
+
// Resolve API key (required)
|
|
301
|
+
const apiKey = resolveSecretSync(buildSecretConfig(rawConfig, 'apiKey', timeout), 'apiKey');
|
|
302
|
+
if (!apiKey) {
|
|
303
|
+
throw new Error('Failed to resolve API key from config');
|
|
304
|
+
}
|
|
305
|
+
// Resolve optional secrets
|
|
306
|
+
const twilioAccountSid = resolveSecretSync(buildSecretConfig(rawConfig, 'twilioAccountSid', timeout), 'twilioAccountSid');
|
|
307
|
+
const twilioAuthToken = resolveSecretSync(buildSecretConfig(rawConfig, 'twilioAuthToken', timeout), 'twilioAuthToken');
|
|
308
|
+
const twilioPhoneNumber = resolveSecretSync(buildSecretConfig(rawConfig, 'twilioPhoneNumber', timeout), 'twilioPhoneNumber');
|
|
309
|
+
const postmarkToken = resolveSecretSync(buildSecretConfig(rawConfig, 'postmarkToken', timeout), 'postmarkToken');
|
|
310
|
+
const postmarkFromEmail = resolveSecretSync(buildSecretConfig(rawConfig, 'postmarkFromEmail', timeout), 'postmarkFromEmail');
|
|
311
|
+
// Build the resolved config
|
|
312
|
+
const resolvedConfig = {
|
|
313
|
+
apiUrl: rawConfig.apiUrl,
|
|
314
|
+
apiKey,
|
|
315
|
+
twilioAccountSid,
|
|
316
|
+
twilioAuthToken,
|
|
317
|
+
twilioPhoneNumber,
|
|
318
|
+
postmarkToken,
|
|
319
|
+
postmarkFromEmail,
|
|
320
|
+
secretCommandTimeout: timeout,
|
|
321
|
+
autoRecall: rawConfig.autoRecall,
|
|
322
|
+
autoCapture: rawConfig.autoCapture,
|
|
323
|
+
userScoping: rawConfig.userScoping,
|
|
324
|
+
maxRecallMemories: rawConfig.maxRecallMemories,
|
|
325
|
+
minRecallScore: rawConfig.minRecallScore,
|
|
326
|
+
timeout: rawConfig.timeout,
|
|
327
|
+
maxRetries: rawConfig.maxRetries,
|
|
328
|
+
debug: rawConfig.debug,
|
|
329
|
+
baseUrl: rawConfig.baseUrl,
|
|
330
|
+
};
|
|
331
|
+
// Validate the resolved config
|
|
332
|
+
return validateConfig(resolvedConfig);
|
|
333
|
+
}
|
|
287
334
|
//# sourceMappingURL=config.js.map
|