@memtensor/memos-local-openclaw-plugin 0.3.12 → 0.3.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAQ,MAAM,EAAE,MAAM,UAAU,CAAC;AA0BlE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACrE,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,mBAAmB,EAAE,CAgCvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+CzD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAQ,MAAM,EAAE,MAAM,UAAU,CAAC;AA0BlE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACrE,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,mBAAmB,EAAE,CAgCvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4CzD"}
@@ -70,9 +70,11 @@ function captureMessages(messages, sessionKey, turnId, _evidenceTag, log) {
70
70
  * Also strips the envelope timestamp prefix like "[Tue 2026-03-03 21:58 GMT+8] "
71
71
  */
72
72
  function stripInboundMetadata(text) {
73
- if (!SENTINEL_FAST_RE.test(text))
74
- return text;
75
- const lines = text.split("\n");
73
+ // Strip envelope timestamp prefix: "[Tue 2026-03-03 21:58 GMT+8] actual message"
74
+ let cleaned = text.replace(/^\[(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?\s+[A-Z]{3}[+-]\d{1,2}\]\s*/, "");
75
+ if (!SENTINEL_FAST_RE.test(cleaned))
76
+ return cleaned.trim();
77
+ const lines = cleaned.split("\n");
76
78
  const result = [];
77
79
  let inMetaBlock = false;
78
80
  let inFencedJson = false;
@@ -85,7 +87,6 @@ function stripInboundMetadata(text) {
85
87
  inFencedJson = false;
86
88
  continue;
87
89
  }
88
- // Sentinel without fenced JSON — skip this line only
89
90
  continue;
90
91
  }
91
92
  if (inMetaBlock) {
@@ -102,9 +103,6 @@ function stripInboundMetadata(text) {
102
103
  }
103
104
  result.push(line);
104
105
  }
105
- let cleaned = result.join("\n").trim();
106
- // Strip envelope timestamp prefix: "[Tue 2026-03-03 21:58 GMT+8] actual message"
107
- cleaned = cleaned.replace(/^\[(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?\s+[A-Z]{3}[+-]\d{1,2}\]\s*/, "");
108
- return cleaned;
106
+ return result.join("\n").trim();
109
107
  }
110
108
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memtensor/memos-local-openclaw-plugin",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "description": "MemOS Local memory plugin for OpenClaw — full-write, hybrid-recall, progressive retrieval",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -13,16 +13,20 @@ const CYAN = "\x1b[36m";
13
13
  const BOLD = "\x1b[1m";
14
14
  const DIM = "\x1b[2m";
15
15
 
16
- function log(msg) { console.log(`${CYAN}[memos-local]${RESET} ${msg}`); }
17
- function warn(msg) { console.log(`${YELLOW}[memos-local]${RESET} ${msg}`); }
18
- function ok(msg) { console.log(`${GREEN}[memos-local]${RESET} ${msg}`); }
19
- function fail(msg) { console.log(`${RED}[memos-local]${RESET} ${msg}`); }
16
+ function log(msg) { console.log(` ${CYAN}[memos-local]${RESET} ${msg}`); }
17
+ function warn(msg) { console.log(` ${YELLOW}[memos-local]${RESET} ${msg}`); }
18
+ function ok(msg) { console.log(` ${GREEN}[memos-local]${RESET} ${msg}`); }
19
+ function fail(msg) { console.log(` ${RED}[memos-local]${RESET} ${msg}`); }
20
+
21
+ function phase(n, title) {
22
+ console.log(`\n${CYAN}${BOLD} ─── Phase ${n}: ${title} ───${RESET}\n`);
23
+ }
20
24
 
21
25
  const pluginDir = path.resolve(__dirname, "..");
22
26
 
23
27
  console.log(`
24
28
  ${CYAN}${BOLD}┌──────────────────────────────────────────────────┐
25
- │ MemOS Local Memory — postinstall
29
+ │ MemOS Local Memory — postinstall setup
26
30
  └──────────────────────────────────────────────────┘${RESET}
27
31
  `);
28
32
 
@@ -34,37 +38,43 @@ log(`Node: ${process.version} Platform: ${process.platform}-${process.arch}`);
34
38
  * ═══════════════════════════════════════════════════════════ */
35
39
 
36
40
  function ensureDependencies() {
41
+ phase(0, "检测核心依赖 / Check core dependencies");
42
+
37
43
  const coreDeps = ["@sinclair/typebox", "uuid", "posthog-node", "@huggingface/transformers"];
38
44
  const missing = [];
39
45
  for (const dep of coreDeps) {
40
46
  try {
41
47
  require.resolve(dep, { paths: [pluginDir] });
48
+ log(` ${dep} ${GREEN}✔${RESET}`);
42
49
  } catch {
43
50
  missing.push(dep);
51
+ log(` ${dep} ${RED}✖ missing${RESET}`);
44
52
  }
45
53
  }
46
54
 
47
55
  if (missing.length === 0) {
48
- ok("All dependencies present.");
56
+ ok("All core dependencies present.");
49
57
  return;
50
58
  }
51
59
 
52
- warn(`Missing dependencies: ${missing.join(", ")}`);
53
- log("Running: npm install --omit=dev (this may take a moment)...");
60
+ warn(`Missing ${missing.length} dependencies: ${BOLD}${missing.join(", ")}${RESET}`);
61
+ log("Running: npm install --omit=dev ...");
54
62
 
55
63
  const startMs = Date.now();
56
64
  const result = spawnSync("npm", ["install", "--omit=dev"], {
57
65
  cwd: pluginDir,
58
- stdio: "inherit",
66
+ stdio: "pipe",
59
67
  shell: true,
60
68
  timeout: 120_000,
61
69
  });
62
70
  const elapsed = ((Date.now() - startMs) / 1000).toFixed(1);
71
+ const stderr = (result.stderr || "").toString().trim();
63
72
 
64
73
  if (result.status === 0) {
65
- ok(`Dependencies installed (${elapsed}s).`);
74
+ ok(`Dependencies installed successfully (${elapsed}s).`);
66
75
  } else {
67
76
  fail(`npm install exited with code ${result.status} (${elapsed}s).`);
77
+ if (stderr) warn(`stderr: ${stderr.slice(0, 300)}`);
68
78
  warn("Some features may not work. Try running manually:");
69
79
  warn(` cd ${pluginDir} && npm install --omit=dev`);
70
80
  }
@@ -73,7 +83,7 @@ function ensureDependencies() {
73
83
  try {
74
84
  ensureDependencies();
75
85
  } catch (e) {
76
- warn(`Dependency check skipped: ${e.message}`);
86
+ warn(`Dependency check error: ${e.message}`);
77
87
  }
78
88
 
79
89
  /* ═══════════════════════════════════════════════════════════
@@ -81,15 +91,15 @@ try {
81
91
  * ═══════════════════════════════════════════════════════════ */
82
92
 
83
93
  function cleanupLegacy() {
94
+ phase(1, "清理旧版本插件 / Clean up legacy plugins");
95
+
84
96
  const home = process.env.HOME || process.env.USERPROFILE || "";
85
- if (!home) return;
97
+ if (!home) { log("Cannot determine HOME directory, skipping."); return; }
86
98
  const ocHome = path.join(home, ".openclaw");
87
- if (!fs.existsSync(ocHome)) return;
99
+ if (!fs.existsSync(ocHome)) { log("No ~/.openclaw directory found, skipping."); return; }
88
100
 
89
101
  const extDir = path.join(ocHome, "extensions");
90
- if (!fs.existsSync(extDir)) return;
91
-
92
- log("Checking for legacy plugin versions...");
102
+ if (!fs.existsSync(extDir)) { log("No extensions directory found, skipping."); return; }
93
103
 
94
104
  const legacyDirs = [
95
105
  path.join(extDir, "memos-lite"),
@@ -102,7 +112,7 @@ function cleanupLegacy() {
102
112
  if (fs.existsSync(dir)) {
103
113
  try {
104
114
  fs.rmSync(dir, { recursive: true, force: true });
105
- ok(`Removed legacy plugin: ${DIM}${dir}${RESET}`);
115
+ ok(`Removed legacy dir: ${DIM}${dir}${RESET}`);
106
116
  cleaned++;
107
117
  } catch (e) {
108
118
  warn(`Could not remove ${dir}: ${e.message}`);
@@ -125,11 +135,11 @@ function cleanupLegacy() {
125
135
  const oldEntry = entries[oldKey];
126
136
  if (!entries["memos-local-openclaw-plugin"]) {
127
137
  entries["memos-local-openclaw-plugin"] = oldEntry;
128
- log(`Migrated config: ${DIM}${oldKey}${RESET} -> ${GREEN}memos-local-openclaw-plugin${RESET}`);
138
+ log(`Migrated config: ${DIM}${oldKey}${RESET} ${GREEN}memos-local-openclaw-plugin${RESET}`);
129
139
  }
130
140
  delete entries[oldKey];
131
141
  cfgChanged = true;
132
- ok(`Removed legacy config entry: ${DIM}${oldKey}${RESET}`);
142
+ ok(`Removed legacy config key: ${DIM}${oldKey}${RESET}`);
133
143
  }
134
144
  }
135
145
 
@@ -141,7 +151,7 @@ function cleanupLegacy() {
141
151
  .replace(/memos-lite-openclaw-plugin/g, "memos-local-openclaw-plugin")
142
152
  .replace(/memos-lite/g, "memos-local");
143
153
  if (newEntry.source !== oldSource) {
144
- log(`Updated source path: ${DIM}${oldSource}${RESET} -> ${GREEN}${newEntry.source}${RESET}`);
154
+ log(`Updated source path: ${DIM}${oldSource}${RESET} ${GREEN}${newEntry.source}${RESET}`);
145
155
  cfgChanged = true;
146
156
  }
147
157
  }
@@ -152,6 +162,8 @@ function cleanupLegacy() {
152
162
  fs.copyFileSync(cfgPath, backup);
153
163
  fs.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
154
164
  ok(`Config updated. Backup: ${DIM}${backup}${RESET}`);
165
+ } else {
166
+ log("No legacy config entries found.");
155
167
  }
156
168
  }
157
169
  } catch (e) {
@@ -160,78 +172,98 @@ function cleanupLegacy() {
160
172
  }
161
173
 
162
174
  if (cleaned > 0) {
163
- ok(`Legacy cleanup complete (${cleaned} old plugin dir(s) removed).`);
175
+ ok(`Legacy cleanup done: ${cleaned} old dir(s) removed.`);
164
176
  } else {
165
- log("No legacy versions found.");
177
+ ok("No legacy plugin directories found. Clean.");
166
178
  }
167
179
  }
168
180
 
169
181
  try {
170
182
  cleanupLegacy();
171
183
  } catch (e) {
172
- warn(`Legacy cleanup skipped: ${e.message}`);
184
+ warn(`Legacy cleanup error: ${e.message}`);
173
185
  }
174
186
 
175
187
  /* ═══════════════════════════════════════════════════════════
176
188
  * Phase 2: Verify better-sqlite3 native module
177
189
  * ═══════════════════════════════════════════════════════════ */
178
190
 
179
- log("Checking better-sqlite3 native module...");
191
+ phase(2, "检查 better-sqlite3 原生模块 / Check native module");
180
192
 
181
193
  try {
182
194
  require("better-sqlite3");
183
195
  ok("better-sqlite3 is ready.");
184
- console.log(`\n${GREEN}${BOLD}[memos-local] Setup complete!${RESET} Restart the gateway: ${CYAN}openclaw gateway stop && openclaw gateway start${RESET}\n`);
196
+ console.log(`
197
+ ${GREEN}${BOLD} ┌──────────────────────────────────────────────────┐
198
+ │ ✔ Setup complete! │
199
+ │ │
200
+ │ Restart gateway: │
201
+ │ ${CYAN}openclaw gateway stop && openclaw gateway start${GREEN} │
202
+ └──────────────────────────────────────────────────┘${RESET}
203
+ `);
185
204
  process.exit(0);
186
205
  } catch (_) {
187
- warn("better-sqlite3 native bindings not found, attempting rebuild...");
206
+ warn("better-sqlite3 native bindings not found.");
207
+ log("Running: npm rebuild better-sqlite3 (may take 30-60s)...");
188
208
  }
189
209
 
190
- log("Running: npm rebuild better-sqlite3 (this may take 30-60 seconds)...");
191
-
192
210
  const startMs = Date.now();
193
211
 
194
212
  const result = spawnSync("npm", ["rebuild", "better-sqlite3"], {
195
213
  cwd: pluginDir,
196
- stdio: "inherit",
214
+ stdio: "pipe",
197
215
  shell: true,
198
216
  timeout: 180_000,
199
217
  });
200
218
 
201
219
  const elapsed = ((Date.now() - startMs) / 1000).toFixed(1);
220
+ const stdout = (result.stdout || "").toString().trim();
221
+ const stderr = (result.stderr || "").toString().trim();
222
+
223
+ if (stdout) log(`rebuild output: ${DIM}${stdout.slice(0, 500)}${RESET}`);
224
+ if (stderr) warn(`rebuild stderr: ${DIM}${stderr.slice(0, 500)}${RESET}`);
202
225
 
203
226
  if (result.status === 0) {
204
227
  try {
205
228
  delete require.cache[require.resolve("better-sqlite3")];
206
229
  require("better-sqlite3");
207
230
  ok(`better-sqlite3 rebuilt successfully (${elapsed}s).`);
208
- console.log(`\n${GREEN}${BOLD}[memos-local] Setup complete!${RESET} Restart the gateway: ${CYAN}openclaw gateway stop && openclaw gateway start${RESET}\n`);
231
+ console.log(`
232
+ ${GREEN}${BOLD} ┌──────────────────────────────────────────────────┐
233
+ │ ✔ Setup complete! │
234
+ │ │
235
+ │ Restart gateway: │
236
+ │ ${CYAN}openclaw gateway stop && openclaw gateway start${GREEN} │
237
+ └──────────────────────────────────────────────────┘${RESET}
238
+ `);
209
239
  process.exit(0);
210
- } catch (_) {
211
- fail(`Rebuild completed but module still cannot load (${elapsed}s).`);
240
+ } catch (retryErr) {
241
+ fail(`Rebuild completed but module still fails (${elapsed}s): ${retryErr.message}`);
212
242
  }
213
243
  } else {
214
244
  fail(`Rebuild failed with exit code ${result.status} (${elapsed}s).`);
215
245
  }
216
246
 
217
247
  console.log(`
218
- ${YELLOW}${BOLD}╔══════════════════════════════════════════════════════════════╗
219
- ║ better-sqlite3 native module build failed
220
- ╠══════════════════════════════════════════════════════════════╣${RESET}
221
- ${YELLOW}║${RESET} This plugin requires C/C++ build tools to compile ${YELLOW}║${RESET}
222
- ${YELLOW}║${RESET} the SQLite native module on first install. ${YELLOW}║${RESET}
223
- ${YELLOW}║${RESET} ${YELLOW}║${RESET}
224
- ${YELLOW}║${RESET} ${BOLD}Fix:${RESET} ${YELLOW}║${RESET}
225
- ${YELLOW}║${RESET} ${YELLOW}║${RESET}
226
- ${YELLOW}║${RESET} ${CYAN}macOS:${RESET} xcode-select --install ${YELLOW}║${RESET}
227
- ${YELLOW}║${RESET} ${CYAN}Ubuntu:${RESET} sudo apt install build-essential python3 ${YELLOW}║${RESET}
228
- ${YELLOW}║${RESET} ${CYAN}Windows:${RESET} npm install -g windows-build-tools ${YELLOW}║${RESET}
229
- ${YELLOW}║${RESET} ${YELLOW}║${RESET}
230
- ${YELLOW}║${RESET} Then retry: ${YELLOW}║${RESET}
231
- ${YELLOW}║${RESET} ${GREEN}cd ${pluginDir}${RESET}
232
- ${YELLOW}║${RESET} ${GREEN}npm rebuild better-sqlite3${RESET} ${YELLOW}║${RESET}
233
- ${YELLOW}║${RESET} ${GREEN}openclaw gateway stop && openclaw gateway start${RESET} ${YELLOW}║${RESET}
234
- ${YELLOW}${BOLD}╚══════════════════════════════════════════════════════════════╝${RESET}
248
+ ${YELLOW}${BOLD} ╔══════════════════════════════════════════════════════════════╗
249
+ better-sqlite3 native module build failed
250
+ ╠══════════════════════════════════════════════════════════════╣${RESET}
251
+ ${YELLOW} ║${RESET} ${YELLOW}║${RESET}
252
+ ${YELLOW} ║${RESET} This plugin requires C/C++ build tools to compile ${YELLOW}║${RESET}
253
+ ${YELLOW} ║${RESET} the SQLite native module on first install. ${YELLOW}║${RESET}
254
+ ${YELLOW} ║${RESET} ${YELLOW}║${RESET}
255
+ ${YELLOW} ║${RESET} ${BOLD}Install build tools:${RESET} ${YELLOW}║${RESET}
256
+ ${YELLOW} ║${RESET} ${YELLOW}║${RESET}
257
+ ${YELLOW} ║${RESET} ${CYAN}macOS:${RESET} xcode-select --install ${YELLOW}║${RESET}
258
+ ${YELLOW} ║${RESET} ${CYAN}Ubuntu:${RESET} sudo apt install build-essential python3 ${YELLOW}║${RESET}
259
+ ${YELLOW} ║${RESET} ${CYAN}Windows:${RESET} npm install -g windows-build-tools ${YELLOW}║${RESET}
260
+ ${YELLOW} ║${RESET} ${YELLOW}║${RESET}
261
+ ${YELLOW} ║${RESET} ${BOLD}Then retry:${RESET} ${YELLOW}║${RESET}
262
+ ${YELLOW} ║${RESET} ${GREEN}cd ${pluginDir}${RESET}
263
+ ${YELLOW} ║${RESET} ${GREEN}npm rebuild better-sqlite3${RESET} ${YELLOW}║${RESET}
264
+ ${YELLOW} ║${RESET} ${GREEN}openclaw gateway stop && openclaw gateway start${RESET} ${YELLOW}║${RESET}
265
+ ${YELLOW} ║${RESET} ${YELLOW}║${RESET}
266
+ ${YELLOW}${BOLD} ╚══════════════════════════════════════════════════════════════╝${RESET}
235
267
  `);
236
268
 
237
269
  process.exit(0);
@@ -83,9 +83,15 @@ export function captureMessages(
83
83
  * Also strips the envelope timestamp prefix like "[Tue 2026-03-03 21:58 GMT+8] "
84
84
  */
85
85
  export function stripInboundMetadata(text: string): string {
86
- if (!SENTINEL_FAST_RE.test(text)) return text;
86
+ // Strip envelope timestamp prefix: "[Tue 2026-03-03 21:58 GMT+8] actual message"
87
+ let cleaned = text.replace(
88
+ /^\[(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?\s+[A-Z]{3}[+-]\d{1,2}\]\s*/,
89
+ "",
90
+ );
91
+
92
+ if (!SENTINEL_FAST_RE.test(cleaned)) return cleaned.trim();
87
93
 
88
- const lines = text.split("\n");
94
+ const lines = cleaned.split("\n");
89
95
  const result: string[] = [];
90
96
  let inMetaBlock = false;
91
97
  let inFencedJson = false;
@@ -100,7 +106,6 @@ export function stripInboundMetadata(text: string): string {
100
106
  inFencedJson = false;
101
107
  continue;
102
108
  }
103
- // Sentinel without fenced JSON — skip this line only
104
109
  continue;
105
110
  }
106
111
 
@@ -120,13 +125,5 @@ export function stripInboundMetadata(text: string): string {
120
125
  result.push(line);
121
126
  }
122
127
 
123
- let cleaned = result.join("\n").trim();
124
-
125
- // Strip envelope timestamp prefix: "[Tue 2026-03-03 21:58 GMT+8] actual message"
126
- cleaned = cleaned.replace(
127
- /^\[(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?\s+[A-Z]{3}[+-]\d{1,2}\]\s*/,
128
- "",
129
- );
130
-
131
- return cleaned;
128
+ return result.join("\n").trim();
132
129
  }