@memoryrelay/plugin-memoryrelay-ai 0.8.2 → 0.8.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/index.ts +44 -4
- package/openclaw.plugin.json +2 -2
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw Memory Plugin - MemoryRelay
|
|
3
|
-
* Version: 0.8.
|
|
3
|
+
* Version: 0.8.3 (Security & Installation Fixes)
|
|
4
4
|
*
|
|
5
5
|
* Long-term memory with vector search using MemoryRelay API.
|
|
6
6
|
* Provides auto-recall and auto-capture via lifecycle hooks.
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
* API: https://api.memoryrelay.net
|
|
10
10
|
* Docs: https://memoryrelay.ai
|
|
11
11
|
*
|
|
12
|
+
* ENHANCEMENTS (v0.8.3):
|
|
13
|
+
* - Security fix: logFile now restricted to relative paths only
|
|
14
|
+
* - Rejects absolute paths and path traversal attempts
|
|
15
|
+
* - Passes OpenClaw security validation for npm installation
|
|
16
|
+
* - Clean installation without security warnings
|
|
17
|
+
*
|
|
12
18
|
* ENHANCEMENTS (v0.8.2):
|
|
13
19
|
* - Human-readable gateway logs with memory previews
|
|
14
20
|
* - Show similarity scores and memory snippets during auto-recall
|
|
@@ -154,6 +160,8 @@ async function fetchWithTimeout(
|
|
|
154
160
|
class MemoryRelayClient {
|
|
155
161
|
private debugLogger?: DebugLogger;
|
|
156
162
|
private statusReporter?: StatusReporter;
|
|
163
|
+
private config?: MemoryRelayConfig;
|
|
164
|
+
private api?: OpenClawPluginApi;
|
|
157
165
|
|
|
158
166
|
constructor(
|
|
159
167
|
private readonly apiKey: string,
|
|
@@ -161,9 +169,12 @@ class MemoryRelayClient {
|
|
|
161
169
|
private readonly apiUrl: string = DEFAULT_API_URL,
|
|
162
170
|
debugLogger?: DebugLogger,
|
|
163
171
|
statusReporter?: StatusReporter,
|
|
172
|
+
api?: OpenClawPluginApi,
|
|
164
173
|
) {
|
|
165
174
|
this.debugLogger = debugLogger;
|
|
166
175
|
this.statusReporter = statusReporter;
|
|
176
|
+
this.api = api;
|
|
177
|
+
this.config = api?.pluginConfig as MemoryRelayConfig | undefined;
|
|
167
178
|
}
|
|
168
179
|
|
|
169
180
|
/**
|
|
@@ -840,9 +851,34 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
840
851
|
|
|
841
852
|
const debugEnabled = cfg?.debug || false;
|
|
842
853
|
const verboseEnabled = cfg?.verbose || false;
|
|
843
|
-
const logFile = cfg?.logFile;
|
|
844
854
|
const maxLogEntries = cfg?.maxLogEntries || 100;
|
|
845
855
|
|
|
856
|
+
// Security fix (v0.8.3): logFile must be relative to workspace/plugin directory
|
|
857
|
+
// Absolute paths and path traversal are rejected
|
|
858
|
+
let logFile: string | undefined;
|
|
859
|
+
if (cfg?.logFile) {
|
|
860
|
+
const requestedPath = cfg.logFile;
|
|
861
|
+
|
|
862
|
+
// Reject absolute paths
|
|
863
|
+
if (requestedPath.startsWith('/') || requestedPath.startsWith('~') || /^[A-Za-z]:/.test(requestedPath)) {
|
|
864
|
+
api.logger.warn(
|
|
865
|
+
`memory-memoryrelay: logFile must be relative path (got: ${requestedPath}). Using default location.`
|
|
866
|
+
);
|
|
867
|
+
logFile = undefined;
|
|
868
|
+
}
|
|
869
|
+
// Reject path traversal
|
|
870
|
+
else if (requestedPath.includes('..')) {
|
|
871
|
+
api.logger.warn(
|
|
872
|
+
`memory-memoryrelay: logFile cannot contain '..' (got: ${requestedPath}). Using default location.`
|
|
873
|
+
);
|
|
874
|
+
logFile = undefined;
|
|
875
|
+
}
|
|
876
|
+
// Accept relative path (will be resolved by DebugLogger relative to workspace)
|
|
877
|
+
else {
|
|
878
|
+
logFile = requestedPath;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
846
882
|
let debugLogger: DebugLogger | undefined;
|
|
847
883
|
let statusReporter: StatusReporter | undefined;
|
|
848
884
|
|
|
@@ -853,12 +889,16 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
853
889
|
maxEntries: maxLogEntries,
|
|
854
890
|
logFile: logFile,
|
|
855
891
|
});
|
|
856
|
-
|
|
892
|
+
|
|
893
|
+
const logLocation = logFile ? ` → ${logFile}` : '';
|
|
894
|
+
api.logger.info(
|
|
895
|
+
`memory-memoryrelay: debug mode enabled (verbose: ${verboseEnabled}, maxEntries: ${maxLogEntries}${logLocation})`
|
|
896
|
+
);
|
|
857
897
|
}
|
|
858
898
|
|
|
859
899
|
statusReporter = new StatusReporter(debugLogger);
|
|
860
900
|
|
|
861
|
-
const client = new MemoryRelayClient(apiKey, agentId, apiUrl, debugLogger, statusReporter);
|
|
901
|
+
const client = new MemoryRelayClient(apiKey, agentId, apiUrl, debugLogger, statusReporter, api);
|
|
862
902
|
|
|
863
903
|
// Verify connection on startup (with timeout)
|
|
864
904
|
try {
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"kind": "memory",
|
|
4
4
|
"name": "MemoryRelay AI",
|
|
5
5
|
"description": "AI memory service with sessions, decisions, patterns & projects (api.memoryrelay.net)",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.8.3",
|
|
7
7
|
"uiHints": {
|
|
8
8
|
"apiKey": {
|
|
9
9
|
"label": "MemoryRelay API Key",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
"logFile": {
|
|
115
115
|
"type": "string",
|
|
116
|
-
"description": "
|
|
116
|
+
"description": "Relative file path for persistent debug logs (e.g., 'memoryrelay-debug.log'). Absolute paths and path traversal (..) are rejected for security."
|
|
117
117
|
},
|
|
118
118
|
"maxLogEntries": {
|
|
119
119
|
"type": "number",
|
package/package.json
CHANGED