@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * OpenClaw Memory Plugin - MemoryRelay
3
- * Version: 0.8.2 (Enhanced Gateway Logging)
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
- api.logger.info(`memory-memoryrelay: debug mode enabled (verbose: ${verboseEnabled}, maxEntries: ${maxLogEntries})`);
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 {
@@ -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.7.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": "Optional file path for persistent debug logs"
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoryrelay/plugin-memoryrelay-ai",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "OpenClaw memory plugin for MemoryRelay API - sessions, decisions, patterns, projects & semantic search",
5
5
  "type": "module",
6
6
  "main": "index.ts",