@memtensor/memos-cloud-openclaw-plugin 0.1.8-beta.8 → 0.1.8-beta.9

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.
@@ -26,7 +26,7 @@ let isUpdating = false;
26
26
 
27
27
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
28
 
29
- const CHECK_INTERVAL = 5 * 60 * 1000; // 12 hours check interval
29
+ const CHECK_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours check interval
30
30
  const UPDATE_TIMEOUT = 3 * 60 * 1000; // 3 minutes timeout for the CLI update command to finish
31
31
  const PLUGIN_NAME = "@memtensor/memos-cloud-openclaw-plugin";
32
32
  const CHECK_FILE = path.join(os.tmpdir(), "memos_openclaw_update_check.json");
@@ -39,6 +39,36 @@ const ANSI = {
39
39
  RED: "\x1b[31m"
40
40
  };
41
41
 
42
+ function canExecuteCli(cliName, timeoutMs = 8000) {
43
+ return new Promise((resolve) => {
44
+ let done = false;
45
+ const child = spawn(cliName, ["--version"], { shell: true });
46
+ const timer = setTimeout(() => {
47
+ if (done) return;
48
+ done = true;
49
+ killProcessTree(child);
50
+ resolve({ ok: false, reason: `timeout after ${timeoutMs}ms` });
51
+ }, timeoutMs);
52
+
53
+ child.on("error", (err) => {
54
+ if (done) return;
55
+ done = true;
56
+ clearTimeout(timer);
57
+ resolve({ ok: false, reason: err?.message || String(err) });
58
+ });
59
+
60
+ child.on("close", (code) => {
61
+ if (done) return;
62
+ done = true;
63
+ clearTimeout(timer);
64
+ resolve({
65
+ ok: code === 0,
66
+ reason: code === 0 ? "" : `exit code ${code}`,
67
+ });
68
+ });
69
+ });
70
+ }
71
+
42
72
 
43
73
  function getPackageVersion() {
44
74
  try {
@@ -158,6 +188,15 @@ export function startUpdateChecker(log) {
158
188
  return;
159
189
  }
160
190
 
191
+ // Check if we have write permission to the plugin directory before attempting update
192
+ const pluginDir = path.join(__dirname, "..");
193
+ try {
194
+ fs.accessSync(pluginDir, fs.constants.W_OK);
195
+ } catch (err) {
196
+ log.warn?.(`${ANSI.YELLOW}[memos-cloud] Update available (${latestVersion}), but skipping auto-update due to missing write permissions in ${pluginDir}. Please run manually with sudo.${ANSI.RESET}`);
197
+ return;
198
+ }
199
+
161
200
  log.info?.(`${ANSI.YELLOW}[memos-cloud] Update available: ${currentVersion} -> ${latestVersion}. Updating in background...${ANSI.RESET}`);
162
201
 
163
202
  let dotCount = 0;
@@ -177,6 +216,14 @@ export function startUpdateChecker(log) {
177
216
  return "openclaw";
178
217
  })();
179
218
 
219
+ const preflight = await canExecuteCli(cliName);
220
+ if (!preflight.ok) {
221
+ log.warn?.(
222
+ `${ANSI.YELLOW}[memos-cloud] Update available (${latestVersion}), but cannot execute CLI '${cliName}' (${preflight.reason}). Please update manually: ${cliName} plugins update memos-cloud-openclaw-plugin${ANSI.RESET}`,
223
+ );
224
+ return;
225
+ }
226
+
180
227
  isUpdating = true;
181
228
  const spawnOpts = { shell: true };
182
229
  // On Unix, detach the process so we can kill the entire process group on timeout
@@ -184,6 +231,14 @@ export function startUpdateChecker(log) {
184
231
  spawnOpts.detached = true;
185
232
  }
186
233
  const child = spawn(cliName, ["plugins", "update", "memos-cloud-openclaw-plugin"], spawnOpts);
234
+ let finished = false;
235
+ const finishUpdateSequence = () => {
236
+ if (finished) return;
237
+ finished = true;
238
+ clearTimeout(updateTimeout);
239
+ clearInterval(progressInterval);
240
+ isUpdating = false;
241
+ };
187
242
 
188
243
  // Timeout mechanism: forcefully kill the update process if it hangs for more than the configured timeout
189
244
  const updateTimeout = setTimeout(() => {
@@ -193,8 +248,7 @@ export function startUpdateChecker(log) {
193
248
  // Fallback: if kill failed and the close event never fires, forcefully release the lock after 5 seconds
194
249
  setTimeout(() => {
195
250
  if (isUpdating) {
196
- clearInterval(progressInterval);
197
- isUpdating = false;
251
+ finishUpdateSequence();
198
252
  }
199
253
  }, 5000);
200
254
  }, UPDATE_TIMEOUT);
@@ -220,9 +274,7 @@ export function startUpdateChecker(log) {
220
274
  });
221
275
 
222
276
  child.on("close", (code) => {
223
- clearTimeout(updateTimeout);
224
- clearInterval(progressInterval);
225
- isUpdating = false;
277
+ finishUpdateSequence();
226
278
 
227
279
  // Wait for a brief moment to let file system sync if needed
228
280
  setTimeout(() => {
@@ -237,6 +289,13 @@ export function startUpdateChecker(log) {
237
289
  }, 1000); // Small 1-second buffer for file systems
238
290
  });
239
291
 
292
+ child.on("error", (err) => {
293
+ finishUpdateSequence();
294
+ log.warn?.(
295
+ `${ANSI.RED}[memos-cloud] Failed to start auto-update process: ${err?.message || String(err)}. Please run manually: ${cliName} plugins update memos-cloud-openclaw-plugin${ANSI.RESET}`,
296
+ );
297
+ });
298
+
240
299
  } catch (error) {
241
300
  log.warn?.(`${ANSI.RED}[memos-cloud] Update check failed entirely: ${error.message}${ANSI.RESET}`);
242
301
  }