openclaw-penfield 1.0.4

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 penfieldlabs
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,490 @@
1
+ # Penfield Memory for OpenClaw (openclaw-penfield)
2
+
3
+ [![npm version](https://img.shields.io/npm/v/openclaw-penfield.svg)](https://www.npmjs.com/package/openclaw-penfield)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ **Persistent, searchable memory for [OpenClaw](https://openclaw.ai).**
7
+
8
+ Your agent remembers every conversation, learns your preferences, and builds knowledge over time—across all your channels.
9
+
10
+ ## What is this?
11
+
12
+ An OpenClaw plugin that connects your agent to [Penfield](https://penfield.app), giving it:
13
+
14
+ - **Long-term memory** — Conversations persist forever, not just one session
15
+ - **Semantic search** — "What did I say about the Tokyo trip?" actually works
16
+ - **Knowledge graphs** — Memories connect to memories, building real understanding
17
+ - **Cross-channel recall** — Remember WhatsApp convos from Discord
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ openclaw plugins install openclaw-penfield
23
+ ```
24
+
25
+ ```bash
26
+ openclaw penfield login
27
+ ```
28
+
29
+ Tell your agent to "Awaken with Penfield"
30
+
31
+ ## Get Access
32
+
33
+ Penfield is in **free beta**. Sign up for access:
34
+
35
+ **[accounts.penfield.app/waitlist](https://accounts.penfield.app/waitlist)**
36
+
37
+ ## Features
38
+
39
+ Native OpenClaw plugin providing direct integration with Penfield's memory and knowledge graph API. This plugin offers 4-5x performance improvement over the MCP server approach by eliminating the mcporter → MCP → Penfield stack.
40
+
41
+ - **16 Memory Tools**
42
+ - **OAuth Device Code Flow**: Secure authentication following RFC 8628
43
+ - **Hybrid Search**: BM25 + vector + graph search capabilities
44
+ - **Knowledge Graph**: Build and traverse relationships between memories
45
+ - **Context Management**: Save and restore memory checkpoints
46
+ - **Artifact Storage**: Store and retrieve files in Penfield
47
+ - **Reflection & Analysis**: Analyze memory patterns and generate insights
48
+ - **Context Management**: Save and restore memory checkpoints
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ openclaw plugins install openclaw-penfield
54
+ ```
55
+
56
+ ### From Source (for contributors)
57
+
58
+ ```bash
59
+ git clone https://github.com/penfieldlabs/openclaw-penfield.git
60
+ cd openclaw-penfield
61
+ npm install
62
+ npm run build
63
+ openclaw plugins install -l .
64
+ ```
65
+
66
+ ## Configuration
67
+
68
+ The plugin is **auto-enabled when loaded**. No configuration required for production use.
69
+
70
+ ## Authentication
71
+
72
+ The plugin uses OAuth 2.0 Device Code Flow (RFC 8628) with automatic token refresh.
73
+
74
+ ### CLI Login
75
+
76
+ ```bash
77
+ openclaw penfield login
78
+ ```
79
+
80
+ This will:
81
+ 1. Discover OAuth endpoints from the auth server
82
+ 2. Register a dynamic client (DCR) if needed
83
+ 3. Display a device code for user authentication
84
+ 4. Poll for token completion
85
+
86
+ ### Credentials
87
+
88
+ ```json
89
+ {
90
+ "version": 1,
91
+ "clientId": "dyn_abc123...",
92
+ "access": "eyJ...",
93
+ "refresh": "eyJ...",
94
+ "expires": 1234567890000,
95
+ "createdAt": 1234567890000
96
+ }
97
+ ```
98
+
99
+ Location: `~/.openclaw/extensions/openclaw-penfield/credentials.json`
100
+ File permissions: `0o600` (owner-only read/write)
101
+
102
+ ## Available Tools
103
+
104
+ ### Memory Management
105
+
106
+ #### `penfield_store`
107
+ Store a new memory in Penfield.
108
+
109
+ **Parameters:**
110
+ - `content` (required): Memory content (max 10,000 chars)
111
+ - `memory_type` (optional): Type of memory (default: "fact")
112
+ - Options: fact, insight, conversation, correction, reference, task, checkpoint, identity_core, personality_trait, relationship, strategy
113
+ - `importance` (optional): Score 0-1 (default: 0.5)
114
+ - `confidence` (optional): Score 0-1 (default: 0.8)
115
+ - `source_type` (optional): Source type (e.g., "direct_input", "conversation")
116
+ - `tags` (optional): Array of tags (max 10)
117
+
118
+ **Example:**
119
+ ```typescript
120
+ {
121
+ "content": "User prefers TypeScript over JavaScript",
122
+ "memory_type": "fact",
123
+ "importance": 0.7,
124
+ "tags": ["preferences", "programming"]
125
+ }
126
+ ```
127
+
128
+ #### `penfield_recall`
129
+ Hybrid search using BM25 + vector + graph.
130
+
131
+ **Parameters:**
132
+ - `query` (required): Search query (1-4,000 chars)
133
+ - `limit` (optional): Max results (default: 20, max: 100)
134
+ - `bm25_weight` (optional): Keyword weight (default: 0.4)
135
+ - `vector_weight` (optional): Semantic weight (default: 0.4)
136
+ - `graph_weight` (optional): Relationship weight (default: 0.2)
137
+ - `memory_types` (optional): Filter by types
138
+ - `importance_threshold` (optional): Minimum importance
139
+ - `enable_graph_expansion` (optional): Enable traversal (default: true)
140
+
141
+ **Example:**
142
+ ```typescript
143
+ {
144
+ "query": "programming preferences",
145
+ "limit": 10,
146
+ "vector_weight": 0.5,
147
+ "bm25_weight": 0.3,
148
+ "graph_weight": 0.2
149
+ }
150
+ ```
151
+
152
+ #### `penfield_search`
153
+ Semantic search variant (higher vector weight).
154
+
155
+ **Parameters:**
156
+ - `query` (required): Search query
157
+ - `limit` (optional): Max results
158
+ - `memory_types` (optional): Filter by types
159
+ - `importance_threshold` (optional): Minimum importance
160
+
161
+ #### `penfield_fetch`
162
+ Get a specific memory by ID.
163
+
164
+ **Parameters:**
165
+ - `memory_id` (required): Memory ID to fetch
166
+
167
+ #### `penfield_update_memory`
168
+ Update an existing memory.
169
+
170
+ **Parameters:**
171
+ - `memory_id` (required): Memory ID to update
172
+ - `content` (optional): Updated content
173
+ - `memory_type` (optional): Updated type
174
+ - `importance` (optional): Updated importance
175
+ - `confidence` (optional): Updated confidence
176
+ - `tags` (optional): Updated tags
177
+
178
+ ### Knowledge Graph
179
+
180
+ #### `penfield_connect`
181
+ Create a relationship between two memories.
182
+
183
+ **Parameters:**
184
+ - `from_memory_id` (required): Source memory ID
185
+ - `to_memory_id` (required): Target memory ID
186
+ - `relationship_type` (required): Type of relationship
187
+ - **Knowledge Evolution**: supersedes, updates, evolution_of
188
+ - **Evidence & Support**: supports, contradicts, disputes
189
+ - **Hierarchy & Structure**: parent_of, child_of, sibling_of, composed_of, part_of
190
+ - **Cause & Prerequisites**: causes, influenced_by, prerequisite_for
191
+ - **Implementation & Testing**: implements, documents, tests, example_of
192
+ - **Conversation & Attribution**: responds_to, references, inspired_by
193
+ - **Sequence & Flow**: follows, precedes
194
+ - **Dependencies**: depends_on
195
+ - `strength` (optional): Relationship strength 0-1 (default: 0.8)
196
+
197
+ **Example:**
198
+ ```typescript
199
+ {
200
+ "from_memory_id": "22618318-8d82-49c9-8bb8-1cf3a61b3c75",
201
+ "to_memory_id": "20413926-2446-4f88-bfd6-749b37969f34",
202
+ "relationship_type": "supports",
203
+ "strength": 0.9
204
+ }
205
+ ```
206
+
207
+ #### `penfield_explore`
208
+ Traverse the knowledge graph from a starting memory.
209
+
210
+ **Parameters:**
211
+ - `start_memory_id` (required): Starting memory ID
212
+ - `max_depth` (optional): Max traversal depth (default: 3, max: 10)
213
+ - `relationship_types` (optional): Filter by relationship types
214
+ - `min_strength` (optional): Minimum relationship strength
215
+
216
+ ### Context Management
217
+
218
+ #### `penfield_save_context`
219
+ Save a checkpoint of current memory state.
220
+
221
+ **Parameters:**
222
+ - `memory_ids` (required): Array of memory IDs to save
223
+ - `session_id` (optional): Session identifier
224
+
225
+ #### `penfield_restore_context`
226
+ Restore a previously saved checkpoint.
227
+
228
+ **Parameters:**
229
+ - `checkpoint_id` (required): Checkpoint ID to restore
230
+ - `full_restore` (optional): Create new copies of memories instead of referencing existing (default: false)
231
+ - `merge_mode` (optional): How to handle conflicts - "append", "replace", or "smart_merge" (default: "append")
232
+
233
+ #### `penfield_list_contexts`
234
+ List all saved checkpoints.
235
+
236
+ **Parameters:**
237
+ - `session_id` (optional): Filter by session ID
238
+ - `limit` (optional): Max results (default: 20, max: 100)
239
+
240
+ ### Analysis
241
+
242
+ #### `penfield_reflect`
243
+ Analyze memory patterns and generate insights.
244
+
245
+ **Parameters:**
246
+ - `time_window` (optional): Time window - "1d", "7d", "30d", or "90d" (default: "7d")
247
+ - `focus_areas` (optional): Areas to analyze - "memory_usage", "relationships", "importance", "topics", "patterns"
248
+ - `memory_types` (optional): Filter by memory types - "fact", "insight", "conversation", "correction", "reference", "task", "checkpoint", "identity_core", "personality_trait", "relationship", "strategy"
249
+
250
+ ### Artifact Storage
251
+
252
+ #### `penfield_save_artifact`
253
+ Save a file artifact to Penfield storage.
254
+
255
+ **Parameters:**
256
+ - `path` (required): Artifact path (e.g., "/project/file.txt")
257
+ - `content` (required): Artifact content
258
+ - `content_type` (optional): MIME type (default: "text/plain")
259
+
260
+ #### `penfield_retrieve_artifact`
261
+ Retrieve a file artifact from Penfield storage.
262
+
263
+ **Parameters:**
264
+ - `path` (required): Artifact path to retrieve
265
+
266
+ #### `penfield_list_artifacts`
267
+ List artifacts in a directory.
268
+
269
+ **Parameters:**
270
+ - `prefix` (optional): Directory prefix (e.g., "/project/")
271
+ - `limit` (optional): Max results (default: 100, max: 1000)
272
+
273
+ #### `penfield_delete_artifact`
274
+ Delete a file artifact from Penfield storage.
275
+
276
+ **Parameters:**
277
+ - `path` (required): Artifact path to delete
278
+
279
+ ### Personality
280
+
281
+ #### `penfield_awaken`
282
+ Load personality configuration and identity core memories.
283
+
284
+ **Parameters:** None
285
+
286
+ ## Usage Examples
287
+
288
+ ### Basic Memory Storage and Retrieval
289
+
290
+ ```typescript
291
+ // Store a memory
292
+ await penfield_store({
293
+ content: "User prefers dark mode for coding",
294
+ memory_type: "fact",
295
+ importance: 0.8,
296
+ tags: ["preferences", "ui"]
297
+ });
298
+
299
+ // Recall memories
300
+ const results = await penfield_recall({
301
+ query: "user interface preferences",
302
+ limit: 5
303
+ });
304
+ ```
305
+
306
+ ### Building Knowledge Graphs
307
+
308
+ ```typescript
309
+ // Store two related memories
310
+ const mem1 = await penfield_store({
311
+ content: "TypeScript provides static typing",
312
+ memory_type: "fact"
313
+ });
314
+
315
+ const mem2 = await penfield_store({
316
+ content: "Static typing helps catch bugs early",
317
+ memory_type: "insight"
318
+ });
319
+
320
+ // Connect them
321
+ await penfield_connect({
322
+ from_memory_id: mem1.id,
323
+ to_memory_id: mem2.id,
324
+ relationship_type: "supports",
325
+ strength: 0.9
326
+ });
327
+
328
+ // Explore the graph
329
+ const graph = await penfield_explore({
330
+ start_memory_id: mem1.id,
331
+ max_depth: 2
332
+ });
333
+ ```
334
+
335
+ ### Context Checkpoints
336
+
337
+ ```typescript
338
+ // Save context
339
+ const checkpoint = await penfield_save_context({
340
+ memory_ids: ["mem_1", "mem_2", "mem_3"],
341
+ session_id: "session_123"
342
+ });
343
+
344
+ // Restore later
345
+ await penfield_restore_context({
346
+ checkpoint_id: checkpoint.id,
347
+ full_restore: true
348
+ });
349
+ ```
350
+
351
+ ## Development
352
+
353
+ ### Setup
354
+
355
+ ```bash
356
+ npm install
357
+ ```
358
+
359
+ ### Type Check
360
+
361
+ ```bash
362
+ npm run typecheck
363
+ ```
364
+
365
+ ### Lint
366
+
367
+ ```bash
368
+ npm run lint
369
+ npm run lint:fix
370
+ ```
371
+
372
+ ### Format
373
+
374
+ ```bash
375
+ npm run format
376
+ npm run format:check
377
+ ```
378
+
379
+ ### Build
380
+
381
+ ```bash
382
+ npm run build
383
+ ```
384
+
385
+ ## Architecture
386
+
387
+ ```
388
+ index.ts # Plugin entry point and registration
389
+ src/
390
+ ├── config.ts # Zod configuration schema with DEFAULT_AUTH_URL/DEFAULT_API_URL
391
+ ├── types.ts # TypeScript type definitions (OpenClaw plugin API types)
392
+ ├── types/typebox.ts # Centralized TypeBox exports
393
+ ├── auth-service.ts # Background OAuth token refresh service
394
+ ├── api-client.ts # HTTP client wrapper
395
+ ├── runtime.ts # Runtime factory (receives authService from index.ts)
396
+ ├── store.ts # Credential file I/O with TOKEN_EXPIRY_BUFFER_MS
397
+ ├── cli.ts # CLI command registration (penfield login)
398
+ ├── device-flow.ts # RFC 8628 Device Code Flow implementation
399
+ └── tools/
400
+ ├── index.ts # Tool registry (16 tools)
401
+ ├── store.ts # penfield_store
402
+ ├── recall.ts # penfield_recall
403
+ ├── search.ts # penfield_search
404
+ ├── fetch.ts # penfield_fetch
405
+ ├── update-memory.ts # penfield_update_memory
406
+ ├── connect.ts # penfield_connect
407
+ ├── explore.ts # penfield_explore
408
+ ├── save-context.ts # penfield_save_context
409
+ ├── restore-context.ts # penfield_restore_context
410
+ ├── list-contexts.ts # penfield_list_contexts
411
+ ├── reflect.ts # penfield_reflect
412
+ ├── save-artifact.ts # penfield_save_artifact
413
+ ├── retrieve-artifact.ts # penfield_retrieve_artifact
414
+ ├── list-artifacts.ts # penfield_list_artifacts
415
+ ├── delete-artifact.ts # penfield_delete_artifact
416
+ └── awaken.ts # penfield_awaken
417
+ ```
418
+
419
+ ## Service Lifecycle
420
+
421
+ The plugin uses two services registered with OpenClaw:
422
+
423
+ 1. **penfield-auth**: Background token refresh service
424
+ - Started when plugin loads
425
+ - Checks token expiry every 60 minutes
426
+ - Auto-refreshes if within 240-minute buffer
427
+
428
+ 2. **penfield**: Runtime lifecycle service
429
+ - Manages runtime initialization
430
+ - Handles cleanup on shutdown
431
+
432
+ ## API Endpoint Mapping
433
+
434
+ | Tool | Method | Endpoint |
435
+ |------|--------|----------|
436
+ | awaken | GET | /api/v2/personality/awakening |
437
+ | connect | POST | /api/v2/relationships |
438
+ | delete_artifact | DELETE | /api/v2/artifacts |
439
+ | explore | POST | /api/v2/relationships/traverse |
440
+ | fetch | GET | /api/v2/memories/{id} |
441
+ | list_artifacts | GET | /api/v2/artifacts/list |
442
+ | list_contexts | GET | /api/v2/checkpoint |
443
+ | recall | POST | /api/v2/search/hybrid |
444
+ | reflect | POST | /api/v2/analysis/reflect |
445
+ | restore_context | POST | /api/v2/checkpoint/{id}/recall |
446
+ | retrieve_artifact | GET | /api/v2/artifacts |
447
+ | save_artifact | POST | /api/v2/artifacts |
448
+ | save_context | POST | /api/v2/checkpoint/create |
449
+ | search | POST | /api/v2/search/hybrid |
450
+ | store | POST | /api/v2/memories |
451
+ | update_memory | PUT | /api/v2/memories/{id} |
452
+
453
+ ## Error Handling
454
+
455
+ All tools return errors in a consistent format:
456
+
457
+ ```json
458
+ {
459
+ "error": "Error message here"
460
+ }
461
+ ```
462
+
463
+ Common errors:
464
+ - **401 Unauthorized**: Token expired or invalid (auto-refreshes)
465
+ - **429 Rate Limited**: Too many requests (includes retry-after header)
466
+ - **500 Internal Server Error**: API error
467
+
468
+ ## Performance
469
+
470
+ This native plugin provides significant performance improvements over the MCP server approach:
471
+
472
+ - **4-5x faster**: Direct HTTP calls vs. mcporter → MCP → Penfield
473
+ - **Lower latency**: No intermediate proxy servers
474
+ - **Reduced overhead**: Fewer serialization/deserialization steps
475
+ - **Auto token refresh**: No re-authentication delays
476
+
477
+ ## Security
478
+
479
+ - Automatic token refresh 240 minutes before expiry
480
+ - RFC 8628 compliant Device Code Flow
481
+ - All API calls use HTTPS
482
+
483
+ ## License
484
+
485
+ MIT
486
+
487
+ ## Support
488
+
489
+ For issues or questions:
490
+ - GitHub Issues: https://github.com/penfieldlabs/openclaw-penfield/issues
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "openclaw-penfield",
3
+ "kind": "memory",
4
+ "configSchema": {
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "authUrl": { "type": "string" },
9
+ "apiUrl": { "type": "string" }
10
+ }
11
+ }
12
+ }
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "openclaw-penfield",
3
+ "version": "1.0.4",
4
+ "type": "module",
5
+ "description": "Native OpenClaw plugin for Penfield memory integration",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "openclaw.plugin.json"
11
+ ],
12
+ "keywords": [
13
+ "openclaw",
14
+ "penfield",
15
+ "memory",
16
+ "knowledge-graph"
17
+ ],
18
+ "author": "Frank Fiegel",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/penfieldlabs/openclaw-penfield.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/penfieldlabs/openclaw-penfield/issues"
26
+ },
27
+ "homepage": "https://github.com/penfieldlabs/openclaw-penfield#readme",
28
+ "dependencies": {
29
+ "@sinclair/typebox": "^0.34.47",
30
+ "zod": "^3.22.4"
31
+ },
32
+ "peerDependencies": {
33
+ "openclaw": ">=2026.1.26"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^25.0.9",
37
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
38
+ "@typescript-eslint/parser": "^7.0.0",
39
+ "eslint": "^8.56.0",
40
+ "prettier": "^3.2.5",
41
+ "typescript": "^5.3.3"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc",
45
+ "lint": "eslint . --ext .ts",
46
+ "lint:fix": "eslint . --ext .ts --fix",
47
+ "format": "prettier --write \"**/*.{ts,json,md}\"",
48
+ "format:check": "prettier --check \"**/*.{ts,json,md}\"",
49
+ "typecheck": "tsc --noEmit"
50
+ },
51
+ "openclaw": {
52
+ "extensions": [
53
+ "./dist/index.js"
54
+ ]
55
+ }
56
+ }