clawdbot-penfield 1.0.1 → 1.0.2
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 +3 -32
- package/dist/src/auth-service.d.ts +1 -0
- package/dist/src/auth-service.d.ts.map +1 -1
- package/dist/src/store.d.ts +16 -3
- package/dist/src/store.d.ts.map +1 -1
- package/dist/src/store.js +19 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,14 +38,14 @@ Penfield is in **free beta**. Sign up for access:
|
|
|
38
38
|
|
|
39
39
|
Native Clawdbot 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
40
|
|
|
41
|
-
- **16 Memory Tools
|
|
41
|
+
- **16 Memory Tools**
|
|
42
42
|
- **OAuth Device Code Flow**: Secure authentication following RFC 8628
|
|
43
|
-
- **Automatic Token Refresh**: Transparent token management with 240-minute expiry buffer
|
|
44
43
|
- **Hybrid Search**: BM25 + vector + graph search capabilities
|
|
45
44
|
- **Knowledge Graph**: Build and traverse relationships between memories
|
|
46
45
|
- **Context Management**: Save and restore memory checkpoints
|
|
47
46
|
- **Artifact Storage**: Store and retrieve files in Penfield
|
|
48
47
|
- **Reflection & Analysis**: Analyze memory patterns and generate insights
|
|
48
|
+
- **Context Management**: Save and restore memory checkpoints
|
|
49
49
|
|
|
50
50
|
## Installation
|
|
51
51
|
|
|
@@ -67,35 +67,6 @@ clawdbot plugins install -l .
|
|
|
67
67
|
|
|
68
68
|
The plugin is **auto-enabled when loaded**. No configuration required for production use.
|
|
69
69
|
|
|
70
|
-
**Default URLs (production):**
|
|
71
|
-
- API: `https://api.penfield.app`
|
|
72
|
-
- Auth: `https://auth.penfield.app`
|
|
73
|
-
|
|
74
|
-
**Override with environment variables (for development):**
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
export PENFIELD_API_URL="https://api-dev.penfield.app"
|
|
78
|
-
export PENFIELD_AUTH_URL="https://auth-dev.penfield.app"
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Or with config in `~/.clawdbot/clawdbot.json`:**
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"plugins": {
|
|
86
|
-
"entries": {
|
|
87
|
-
"penfield": {
|
|
88
|
-
"enabled": true,
|
|
89
|
-
"config": {
|
|
90
|
-
"apiUrl": "https://api-dev.penfield.app",
|
|
91
|
-
"authUrl": "https://auth-dev.penfield.app"
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
70
|
## Authentication
|
|
100
71
|
|
|
101
72
|
The plugin uses OAuth 2.0 Device Code Flow (RFC 8628) with automatic token refresh.
|
|
@@ -125,7 +96,7 @@ This will:
|
|
|
125
96
|
}
|
|
126
97
|
```
|
|
127
98
|
|
|
128
|
-
Location: `~/.clawdbot/extensions/penfield/credentials.json`
|
|
99
|
+
Location: `~/.clawdbot/extensions/clawdbot-penfield/credentials.json`
|
|
129
100
|
File permissions: `0o600` (owner-only read/write)
|
|
130
101
|
|
|
131
102
|
## Available Tools
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../src/auth-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAKzC,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,mCAAmC;IACnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,qDAAqD;IACrD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,oDAAoD;IACpD,eAAe,IAAI,OAAO,CAAC;CAC5B;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../src/auth-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAKzC,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,mCAAmC;IACnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,qDAAqD;IACrD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,oDAAoD;IACpD,eAAe,IAAI,OAAO,CAAC;CAC5B;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,EAC1E,OAAO,EAAE,kBAAkB,GAC1B,WAAW,CAsMb"}
|
package/dist/src/store.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* File-based credential storage for Penfield plugin
|
|
3
3
|
*
|
|
4
|
-
* Credentials are stored at: ~/.clawdbot/extensions/
|
|
4
|
+
* Credentials are stored at: ~/.clawdbot/extensions/{pluginId}/credentials.json
|
|
5
5
|
* Directory permissions: 0o700 (only owner can access)
|
|
6
6
|
* File permissions: 0o600 (only owner can read/write)
|
|
7
|
+
*
|
|
8
|
+
* The path is derived from the plugin ID, so credentials follow the plugin
|
|
9
|
+
* installation automatically (future-proofing for potential folder renames).
|
|
7
10
|
*/
|
|
8
|
-
export declare const CRED_DIR = "~/.clawdbot/extensions/penfield";
|
|
9
|
-
export declare const CRED_FILE = "~/.clawdbot/extensions/penfield/credentials.json";
|
|
10
11
|
export declare const TOKEN_EXPIRY_BUFFER_MS: number;
|
|
12
|
+
/**
|
|
13
|
+
* Get credential directory path for the plugin
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCredDir(pluginId: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Get credential file path for the plugin
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCredFile(pluginId: string): string;
|
|
11
20
|
export interface CredentialFile {
|
|
12
21
|
version: number;
|
|
13
22
|
clientId: string;
|
|
@@ -20,6 +29,7 @@ export interface CredentialFile {
|
|
|
20
29
|
* Save credentials to file with schema versioning
|
|
21
30
|
*/
|
|
22
31
|
export declare function saveCredential(api: {
|
|
32
|
+
id: string;
|
|
23
33
|
resolvePath(path: string): string;
|
|
24
34
|
logger?: {
|
|
25
35
|
info(...args: unknown[]): void;
|
|
@@ -32,18 +42,21 @@ export declare function saveCredential(api: {
|
|
|
32
42
|
* Returns null if file doesn't exist or is corrupted
|
|
33
43
|
*/
|
|
34
44
|
export declare function loadCredential(api: {
|
|
45
|
+
id: string;
|
|
35
46
|
resolvePath(path: string): string;
|
|
36
47
|
}): CredentialFile | null;
|
|
37
48
|
/**
|
|
38
49
|
* Check if we have valid (non-expired) credentials
|
|
39
50
|
*/
|
|
40
51
|
export declare function hasValidCredentials(api: {
|
|
52
|
+
id: string;
|
|
41
53
|
resolvePath(path: string): string;
|
|
42
54
|
}): boolean;
|
|
43
55
|
/**
|
|
44
56
|
* Get refresh token if available
|
|
45
57
|
*/
|
|
46
58
|
export declare function getRefreshToken(api: {
|
|
59
|
+
id: string;
|
|
47
60
|
resolvePath(path: string): string;
|
|
48
61
|
}): string | null;
|
|
49
62
|
//# sourceMappingURL=store.d.ts.map
|
package/dist/src/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,eAAO,MAAM,sBAAsB,QAAkB,CAAC;AAEtD;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;KAAE,CAAA;CAAE,EACpK,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,WAAW,CAAC,GAClD,IAAI,CAiBN;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GACrD,cAAc,GAAG,IAAI,CAevB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GACrD,OAAO,CAMT;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GACrD,MAAM,GAAG,IAAI,CAGf"}
|
package/dist/src/store.js
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* File-based credential storage for Penfield plugin
|
|
3
3
|
*
|
|
4
|
-
* Credentials are stored at: ~/.clawdbot/extensions/
|
|
4
|
+
* Credentials are stored at: ~/.clawdbot/extensions/{pluginId}/credentials.json
|
|
5
5
|
* Directory permissions: 0o700 (only owner can access)
|
|
6
6
|
* File permissions: 0o600 (only owner can read/write)
|
|
7
|
+
*
|
|
8
|
+
* The path is derived from the plugin ID, so credentials follow the plugin
|
|
9
|
+
* installation automatically (future-proofing for potential folder renames).
|
|
7
10
|
*/
|
|
8
11
|
import * as fs from 'fs';
|
|
9
|
-
// Credential storage paths
|
|
10
|
-
export const CRED_DIR = '~/.clawdbot/extensions/penfield';
|
|
11
|
-
export const CRED_FILE = `${CRED_DIR}/credentials.json`;
|
|
12
12
|
// Token buffer: refresh if token expires within 240 minutes (4 hours)
|
|
13
13
|
export const TOKEN_EXPIRY_BUFFER_MS = 240 * 60 * 1000;
|
|
14
|
+
/**
|
|
15
|
+
* Get credential directory path for the plugin
|
|
16
|
+
*/
|
|
17
|
+
export function getCredDir(pluginId) {
|
|
18
|
+
return `~/.clawdbot/extensions/${pluginId}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get credential file path for the plugin
|
|
22
|
+
*/
|
|
23
|
+
export function getCredFile(pluginId) {
|
|
24
|
+
return `${getCredDir(pluginId)}/credentials.json`;
|
|
25
|
+
}
|
|
14
26
|
/**
|
|
15
27
|
* Save credentials to file with schema versioning
|
|
16
28
|
*/
|
|
17
29
|
export function saveCredential(api, cred) {
|
|
18
|
-
const dirPath = api.resolvePath(
|
|
19
|
-
const filePath = api.resolvePath(
|
|
30
|
+
const dirPath = api.resolvePath(getCredDir(api.id));
|
|
31
|
+
const filePath = api.resolvePath(getCredFile(api.id));
|
|
20
32
|
const content = {
|
|
21
33
|
version: 1,
|
|
22
34
|
...cred,
|
|
@@ -34,7 +46,7 @@ export function saveCredential(api, cred) {
|
|
|
34
46
|
* Returns null if file doesn't exist or is corrupted
|
|
35
47
|
*/
|
|
36
48
|
export function loadCredential(api) {
|
|
37
|
-
const filePath = api.resolvePath(
|
|
49
|
+
const filePath = api.resolvePath(getCredFile(api.id));
|
|
38
50
|
try {
|
|
39
51
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
40
52
|
const content = JSON.parse(raw);
|