@memtensor/memos-cloud-openclaw-plugin 0.1.8-beta.1 → 0.1.8-beta.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.
@@ -2,7 +2,7 @@
2
2
  "id": "memos-cloud-openclaw-plugin",
3
3
  "name": "MemOS Cloud OpenClaw Plugin",
4
4
  "description": "MemOS Cloud recall + add memory via lifecycle hooks",
5
- "version": "0.1.8-beta.1",
5
+ "version": "0.1.8-beta.2",
6
6
  "kind": "lifecycle",
7
7
  "main": "./index.js",
8
8
  "configSchema": {
package/index.js CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  USER_QUERY_MARKER,
8
8
  searchMemory,
9
9
  } from "./lib/memos-cloud-api.js";
10
+ import { checkUpdate } from "./lib/check-update.js";
10
11
  let lastCaptureTime = 0;
11
12
  const conversationCounters = new Map();
12
13
  const API_KEY_HELP_URL = "https://memos-dashboard.openmem.net/cn/apikeys/";
@@ -205,6 +206,9 @@ export default {
205
206
  const cfg = buildConfig(api.pluginConfig);
206
207
  const log = api.logger ?? console;
207
208
 
209
+ // Call update check asynchronously. The interval control is inside checkUpdate
210
+ checkUpdate(log);
211
+
208
212
  if (!cfg.envFileStatus?.found) {
209
213
  const searchPaths = cfg.envFileStatus?.searchPaths?.join(", ") ?? ENV_FILE_SEARCH_HINTS.join(", ");
210
214
  log.warn?.(`[memos-cloud] No .env found in ${searchPaths}; falling back to process env or plugin config.`);
@@ -229,6 +233,7 @@ export default {
229
233
  }
230
234
 
231
235
  api.on("before_agent_start", async (event, ctx) => {
236
+ checkUpdate(log);
232
237
  if (!cfg.recallEnabled) return;
233
238
  if (!event?.prompt || event.prompt.length < 3) return;
234
239
  if (!cfg.apiKey) {
@@ -0,0 +1,178 @@
1
+ import https from "https";
2
+ import fs from "fs";
3
+ import { exec } from "child_process";
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+
9
+ let lastCheckTime = 0;
10
+ const CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours
11
+ const PLUGIN_NAME = "@memtensor/memos-cloud-openclaw-plugin";
12
+
13
+ const ANSI = {
14
+ RESET: "\x1b[0m",
15
+ GREEN: "\x1b[32m",
16
+ YELLOW: "\x1b[33m",
17
+ CYAN: "\x1b[36m",
18
+ RED: "\x1b[31m"
19
+ };
20
+
21
+
22
+ function getPackageVersion() {
23
+ try {
24
+ const pkgPath = path.join(__dirname, "..", "package.json");
25
+ const pkgData = fs.readFileSync(pkgPath, "utf-8");
26
+ const pkg = JSON.parse(pkgData);
27
+ return pkg.version;
28
+ } catch (err) {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ function getLatestVersion(log) {
34
+ return new Promise((resolve, reject) => {
35
+ const req = https.get(
36
+ `https://registry.npmjs.org/${PLUGIN_NAME}/latest`,
37
+ { timeout: 5000 },
38
+ (res) => {
39
+ if (res.statusCode !== 200) {
40
+ req.destroy();
41
+ return reject(new Error(`Failed to fetch version, status: ${res.statusCode}`));
42
+ }
43
+
44
+ let body = "";
45
+ res.on("data", (chunk) => {
46
+ body += chunk;
47
+ });
48
+
49
+ res.on("end", () => {
50
+ try {
51
+ const data = JSON.parse(body);
52
+ resolve(data.version);
53
+ } catch (err) {
54
+ reject(err);
55
+ }
56
+ });
57
+ }
58
+ );
59
+
60
+ req.on("error", (err) => {
61
+ reject(err);
62
+ });
63
+
64
+ req.on("timeout", () => {
65
+ req.destroy();
66
+ reject(new Error("Timeout getting latest version"));
67
+ });
68
+ });
69
+ }
70
+
71
+ function compareVersions(v1, v2) {
72
+ // Split pre-release tags (e.g. 0.1.8-beta.1 -> "0.1.8" and "beta.1")
73
+ const split1 = v1.split("-");
74
+ const split2 = v2.split("-");
75
+ const parts1 = split1[0].split(".").map(Number);
76
+ const parts2 = split2[0].split(".").map(Number);
77
+
78
+ // Compare major.minor.patch
79
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
80
+ const p1 = parts1[i] || 0;
81
+ const p2 = parts2[i] || 0;
82
+ if (p1 > p2) return 1;
83
+ if (p1 < p2) return -1;
84
+ }
85
+
86
+ // If base versions are equal, compare pre-release tags.
87
+ // A version WITH a pre-release tag is LOWER than a version WITHOUT one.
88
+ // e.g. 0.1.8-beta is less than 0.1.8. 0.1.8 is the final release.
89
+ const hasPre1 = split1.length > 1;
90
+ const hasPre2 = split2.length > 1;
91
+
92
+ if (hasPre1 && !hasPre2) return -1; // v1 is a beta, v2 is a full release
93
+ if (!hasPre1 && hasPre2) return 1; // v1 is a full release, v2 is a beta
94
+ if (!hasPre1 && !hasPre2) return 0; // both are full releases and equal
95
+
96
+ // If both are pre-releases, do a basic string compare on the tag
97
+ // "alpha" < "beta" < "rc"
98
+ if (split1[1] > split2[1]) return 1;
99
+ if (split1[1] < split2[1]) return -1;
100
+
101
+ return 0;
102
+ }
103
+
104
+ export async function checkUpdate(log) {
105
+ // Prevent infinite loop: do not check for updates if the current process
106
+ // is already running an openclaw CLI command like `openclaw plugins update ...`
107
+ const isUpdateCommand = process.argv.includes("plugins") && process.argv.includes("update");
108
+ if (isUpdateCommand) {
109
+ return;
110
+ }
111
+
112
+ const now = Date.now();
113
+ if (now - lastCheckTime < CHECK_INTERVAL) {
114
+ return;
115
+ }
116
+
117
+ lastCheckTime = now;
118
+
119
+ const currentVersion = getPackageVersion();
120
+ if (!currentVersion) {
121
+ return;
122
+ }
123
+
124
+ try {
125
+ const latestVersion = await getLatestVersion(log);
126
+
127
+ // Normal version check
128
+ if (compareVersions(latestVersion, currentVersion) <= 0) {
129
+ return;
130
+ }
131
+
132
+ log.info?.(`${ANSI.YELLOW}[memos-cloud] Update available: ${currentVersion} -> ${latestVersion}. Updating in background...${ANSI.RESET}`);
133
+
134
+
135
+ let dotCount = 0;
136
+ const progressInterval = setInterval(() => {
137
+ dotCount++;
138
+ const dots = ".".repeat(dotCount % 4);
139
+ log.info?.(`${ANSI.YELLOW}[memos-cloud] Update in progress for memos-cloud-openclaw-plugin${dots}${ANSI.RESET}`);
140
+ }, 5000); // Log every 5 seconds to show it's still alive
141
+
142
+ const cliName = (() => {
143
+ // Check the full path of the entry script (e.g., .../moltbot/bin/index.js) or the executable
144
+ const scriptPath = process.argv[1] ? process.argv[1].toLowerCase() : "";
145
+ const execPath = process.execPath ? process.execPath.toLowerCase() : "";
146
+
147
+ if (scriptPath.includes("moltbot") || execPath.includes("moltbot")) return "moltbot";
148
+ if (scriptPath.includes("clawdbot") || execPath.includes("clawdbot")) return "clawdbot";
149
+ return "openclaw";
150
+ })();
151
+
152
+ exec(`${cliName} plugins update memos-cloud-openclaw-plugin`, (error, stdout, stderr) => {
153
+ clearInterval(progressInterval);
154
+
155
+ const outText = (stdout || "").trim();
156
+ const errText = (stderr || "").trim();
157
+
158
+ if (outText) log.info?.(`${ANSI.CYAN}[${cliName}-cli]${ANSI.RESET}\n${outText}`);
159
+ if (errText) log.warn?.(`${ANSI.RED}[${cliName}-cli]${ANSI.RESET}\n${errText}`);
160
+
161
+ // Wait for a brief moment to let file system sync if needed
162
+ setTimeout(() => {
163
+ const postUpdateVersion = getPackageVersion();
164
+ const actuallyUpdated = (postUpdateVersion === latestVersion) && (postUpdateVersion !== currentVersion);
165
+
166
+ if (error || !actuallyUpdated) {
167
+ const reason = error ? "Command exited with error" : "Version did not change after update command";
168
+ log.warn?.(`${ANSI.RED}[memos-cloud] Auto-update failed (${reason}). Please refer to the CLI logs above, or run manually: ${cliName} plugins update memos-cloud-openclaw-plugin${ANSI.RESET}`);
169
+ } else {
170
+ log.info?.(`${ANSI.GREEN}[memos-cloud] Successfully updated to version ${latestVersion}. Please restart the gateway to apply changes.${ANSI.RESET}`);
171
+ }
172
+ }, 1000); // Small 1-second buffer for file systems
173
+ });
174
+
175
+ } catch (error) {
176
+ // Silently handle errors
177
+ }
178
+ }
@@ -2,7 +2,7 @@
2
2
  "id": "memos-cloud-openclaw-plugin",
3
3
  "name": "MemOS Cloud OpenClaw Plugin",
4
4
  "description": "MemOS Cloud recall + add memory via lifecycle hooks",
5
- "version": "0.1.8-beta.1",
5
+ "version": "0.1.8-beta.2",
6
6
  "kind": "lifecycle",
7
7
  "main": "./index.js",
8
8
  "configSchema": {
@@ -2,7 +2,7 @@
2
2
  "id": "memos-cloud-openclaw-plugin",
3
3
  "name": "MemOS Cloud OpenClaw Plugin",
4
4
  "description": "MemOS Cloud recall + add memory via lifecycle hooks",
5
- "version": "0.1.8-beta.1",
5
+ "version": "0.1.8-beta.2",
6
6
  "kind": "lifecycle",
7
7
  "main": "./index.js",
8
8
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memtensor/memos-cloud-openclaw-plugin",
3
- "version": "0.1.8-beta.1",
3
+ "version": "0.1.8-beta.2",
4
4
  "description": "OpenClaw lifecycle plugin for MemOS Cloud (add + recall memory)",
5
5
  "scripts": {
6
6
  "sync-version": "node scripts/sync-version.js",